diff options
author | cedeel@gmail.com <cedeel@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6> | 2012-06-14 15:06:06 +0200 |
---|---|---|
committer | cedeel@gmail.com <cedeel@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6> | 2012-06-14 15:06:06 +0200 |
commit | 92c59963f82f81aa3202657e7fdbb2592924ede3 (patch) | |
tree | b7eb2474528a4998fa102e3ec9119b908cee08b4 | |
parent | Added HOOK_WEATHER_CHANGE. (diff) | |
download | cuberite-92c59963f82f81aa3202657e7fdbb2592924ede3.tar cuberite-92c59963f82f81aa3202657e7fdbb2592924ede3.tar.gz cuberite-92c59963f82f81aa3202657e7fdbb2592924ede3.tar.bz2 cuberite-92c59963f82f81aa3202657e7fdbb2592924ede3.tar.lz cuberite-92c59963f82f81aa3202657e7fdbb2592924ede3.tar.xz cuberite-92c59963f82f81aa3202657e7fdbb2592924ede3.tar.zst cuberite-92c59963f82f81aa3202657e7fdbb2592924ede3.zip |
390 files changed, 86875 insertions, 86875 deletions
diff --git a/WebServer/Globals.cpp b/WebServer/Globals.cpp index 2c60fd698..13c6ae709 100644 --- a/WebServer/Globals.cpp +++ b/WebServer/Globals.cpp @@ -1,10 +1,10 @@ -
-// Globals.cpp
-
-// This file is used for precompiled header generation in MSVC environments
-
-#include "Globals.h"
-
-
-
-
+ +// Globals.cpp + +// This file is used for precompiled header generation in MSVC environments + +#include "Globals.h" + + + + diff --git a/WebServer/Socket.cpp b/WebServer/Socket.cpp index 430461fe8..2dde93b22 100644 --- a/WebServer/Socket.cpp +++ b/WebServer/Socket.cpp @@ -1,372 +1,372 @@ -/*
- Socket.cpp
-
- Copyright (C) 2002-2004 René Nyffenegger
-
- This source code is provided 'as-is', without any express or implied
- warranty. In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this source code must not be misrepresented; you must not
- claim that you wrote the original source code. If you use this source code
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
-
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original source code.
-
- 3. This notice may not be removed or altered from any source distribution.
-
- René Nyffenegger rene.nyffenegger@adp-gmbh.ch
-*/
-
-/*
- Note on point 2:
- THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1
-*/
-
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "Socket.h"
-#include <iostream>
-
-#ifndef _WIN32
- #include <cstring>
- #include <sys/time.h>
- #include <unistd.h>
- #define SD_SEND 0x01
-#else
- #define MSG_NOSIGNAL (0)
-#endif
-
-#ifdef __MAC_NA
- #define MSG_NOSIGNAL (0)
-#endif
-
-#ifndef MSG_NOSIGNAL
- #define MSG_NOSIGNAL 0
-#endif // MSG_NOSIGNAL
-
-using namespace std;
-
-int Socket::nofSockets_= 0;
-
-
-
-
-
-void Socket::Start()
-{
- #ifdef _WIN32
- if (!nofSockets_)
- {
- WSADATA info;
- if (WSAStartup(MAKEWORD(2,0), &info))
- {
- throw "Could not start WSA";
- }
- }
- #endif
- ++nofSockets_;
-}
-
-
-
-
-
-void Socket::End()
-{
-#ifdef _WIN32
- WSACleanup();
-#endif
-}
-
-
-
-
-
-Socket::Socket() :
- s_(INVALID_SOCKET)
-{
- Start();
- // UDP: use SOCK_DGRAM instead of SOCK_STREAM
- s_ = socket(AF_INET,SOCK_STREAM,0);
-
- if (!IsValid())
- {
- throw "INVALID_SOCKET";
- }
-
- refCounter_ = new int(1);
-}
-
-
-
-
-
-Socket::Socket(SOCKET s) : s_(s)
-{
- Start();
- refCounter_ = new int(1);
-};
-
-
-
-
-
-Socket::~Socket()
-{
- if (! --(*refCounter_))
- {
- Close();
- delete refCounter_;
- }
-
- --nofSockets_;
- if (!nofSockets_)
- {
- End();
- }
-}
-
-
-
-
-
-Socket::Socket(const Socket& o)
-{
- refCounter_=o.refCounter_;
- (*refCounter_)++;
- s_ =o.s_;
-
- nofSockets_++;
-}
-
-
-
-
-
-Socket& Socket::operator=(Socket& o)
-{
- (*o.refCounter_)++;
-
- refCounter_ = o.refCounter_;
- s_ = o.s_;
-
- nofSockets_++;
-
- return *this;
-}
-
-
-
-
-
-bool Socket::IsValid(void) const
-{
- #ifdef _WIN32
- return (s_ != INVALID_SOCKET);
- #else
- return (s_ >= 0);
- #endif
-}
-
-
-
-
-
-void Socket::Close( bool a_WaitSend /* = false */ )
-{
- if (IsValid())
- {
- if (a_WaitSend)
- {
- assert( shutdown(s_, SD_SEND ) == 0 );
- char c;
- while( recv(s_, &c, 1, 0 ) > 0 )
- {}
- }
-
- #ifndef _WIN32
- // Linux needs to shut the socket down first, otherwise the socket keeps blocking accept() and select() calls!
- // Ref.: http://forum.mc-server.org/showthread.php?tid=344
- if (shutdown(s_, SHUT_RDWR) != 0)
- {
- LOGWARN("Error on shutting down socket %d", s_);
- }
- #endif // _WIN32
-
- closesocket(s_);
-
- s_ = INVALID_SOCKET;
- }
-}
-
-
-
-
-
-std::string Socket::ReceiveLine()
-{
- std::string ret;
- while (1)
- {
- char r;
-
- if (recv(s_, &r, 1, 0) <= 0 )
- {
- return "";
- }
- ret += r;
- if (r == '\n') return ret;
- }
-}
-
-
-
-
-
-std::string Socket::ReceiveBytes( unsigned int a_Length )
-{
- std::string ret;
- while( ret.size() < a_Length )
- {
- char r;
-
- if (recv(s_, &r, 1, 0) <= 0 )
- {
- return "";
- }
- ret += r;
- }
- return ret;
-}
-
-
-
-
-
-void Socket::SendLine(std::string s)
-{
- s += '\n';
- if( send(s_,s.c_str(),s.length(),MSG_NOSIGNAL) <= 0 )
- {
- //printf("SendLine Socket error!! \n" );
- Close();
- }
-}
-
-
-
-
-
-void Socket::SendBytes(const std::string& s)
-{
- if( send(s_,s.c_str(),s.length(), MSG_NOSIGNAL) <= 0 )
- {
- //printf("SendBytes Socket error!! \n" );
- Close();
- }
-}
-
-
-
-
-
-SocketServer::SocketServer(int port, int connections, TypeSocket type)
-{
- sockaddr_in sa;
-
- memset(&sa, 0, sizeof(sa));
-
- sa.sin_family = PF_INET;
- sa.sin_port = htons(port);
- s_ = socket(AF_INET, SOCK_STREAM, 0);
-
- if (!IsValid())
- {
- LOG("WebServer: INVALID_SOCKET");
- }
-
- if(type==NonBlockingSocket)
- {
- return;
- }
-
- #ifdef _WIN32
- char yes = 1;
- #else
- int yes = 1;
- #endif
-
- if (setsockopt(s_,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1)
- {
- LOG("WebServer: setsockopt == -1");
- return;
- }
-
- /* bind the socket to the internet address */
- if (bind(s_, (sockaddr *)&sa, sizeof(sockaddr_in)) == SOCKET_ERROR)
- {
- closesocket(s_);
- LOG("WebServer: INVALID_SOCKET");
- }
-
- listen(s_, connections);
-}
-
-
-
-
-
-Socket* SocketServer::Accept()
-{
- Socket * r = new Socket(accept(s_, 0, 0));
- if (!r->IsValid())
- {
- delete r;
- r = NULL;
- }
-
- return r;
-}
-
-
-
-
-
-SocketSelect::SocketSelect(Socket const * const s1, Socket const * const s2, TypeSocket type)
-{
- FD_ZERO(&fds_);
- SOCKET Highest = s1->s_;
- FD_SET(const_cast<Socket*>(s1)->s_,&fds_);
- if(s2)
- {
- FD_SET(const_cast<Socket*>(s2)->s_,&fds_);
- if (s2->s_ > Highest)
- {
- Highest = s2->s_;
- }
- }
- if (select(Highest + 1, &fds_, NULL, NULL, NULL) == SOCKET_ERROR)
- {
- throw "Error in select";
- }
-}
-
-
-
-
-
-bool SocketSelect::Readable(Socket const* const s)
-{
- return (FD_ISSET(s->s_,&fds_) != 0);
-}
-
-
-
-
+/* + Socket.cpp + + Copyright (C) 2002-2004 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ + +/* + Note on point 2: + THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 +*/ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "Socket.h" +#include <iostream> + +#ifndef _WIN32 + #include <cstring> + #include <sys/time.h> + #include <unistd.h> + #define SD_SEND 0x01 +#else + #define MSG_NOSIGNAL (0) +#endif + +#ifdef __MAC_NA + #define MSG_NOSIGNAL (0) +#endif + +#ifndef MSG_NOSIGNAL + #define MSG_NOSIGNAL 0 +#endif // MSG_NOSIGNAL + +using namespace std; + +int Socket::nofSockets_= 0; + + + + + +void Socket::Start() +{ + #ifdef _WIN32 + if (!nofSockets_) + { + WSADATA info; + if (WSAStartup(MAKEWORD(2,0), &info)) + { + throw "Could not start WSA"; + } + } + #endif + ++nofSockets_; +} + + + + + +void Socket::End() +{ +#ifdef _WIN32 + WSACleanup(); +#endif +} + + + + + +Socket::Socket() : + s_(INVALID_SOCKET) +{ + Start(); + // UDP: use SOCK_DGRAM instead of SOCK_STREAM + s_ = socket(AF_INET,SOCK_STREAM,0); + + if (!IsValid()) + { + throw "INVALID_SOCKET"; + } + + refCounter_ = new int(1); +} + + + + + +Socket::Socket(SOCKET s) : s_(s) +{ + Start(); + refCounter_ = new int(1); +}; + + + + + +Socket::~Socket() +{ + if (! --(*refCounter_)) + { + Close(); + delete refCounter_; + } + + --nofSockets_; + if (!nofSockets_) + { + End(); + } +} + + + + + +Socket::Socket(const Socket& o) +{ + refCounter_=o.refCounter_; + (*refCounter_)++; + s_ =o.s_; + + nofSockets_++; +} + + + + + +Socket& Socket::operator=(Socket& o) +{ + (*o.refCounter_)++; + + refCounter_ = o.refCounter_; + s_ = o.s_; + + nofSockets_++; + + return *this; +} + + + + + +bool Socket::IsValid(void) const +{ + #ifdef _WIN32 + return (s_ != INVALID_SOCKET); + #else + return (s_ >= 0); + #endif +} + + + + + +void Socket::Close( bool a_WaitSend /* = false */ ) +{ + if (IsValid()) + { + if (a_WaitSend) + { + assert( shutdown(s_, SD_SEND ) == 0 ); + char c; + while( recv(s_, &c, 1, 0 ) > 0 ) + {} + } + + #ifndef _WIN32 + // Linux needs to shut the socket down first, otherwise the socket keeps blocking accept() and select() calls! + // Ref.: http://forum.mc-server.org/showthread.php?tid=344 + if (shutdown(s_, SHUT_RDWR) != 0) + { + LOGWARN("Error on shutting down socket %d", s_); + } + #endif // _WIN32 + + closesocket(s_); + + s_ = INVALID_SOCKET; + } +} + + + + + +std::string Socket::ReceiveLine() +{ + std::string ret; + while (1) + { + char r; + + if (recv(s_, &r, 1, 0) <= 0 ) + { + return ""; + } + ret += r; + if (r == '\n') return ret; + } +} + + + + + +std::string Socket::ReceiveBytes( unsigned int a_Length ) +{ + std::string ret; + while( ret.size() < a_Length ) + { + char r; + + if (recv(s_, &r, 1, 0) <= 0 ) + { + return ""; + } + ret += r; + } + return ret; +} + + + + + +void Socket::SendLine(std::string s) +{ + s += '\n'; + if( send(s_,s.c_str(),s.length(),MSG_NOSIGNAL) <= 0 ) + { + //printf("SendLine Socket error!! \n" ); + Close(); + } +} + + + + + +void Socket::SendBytes(const std::string& s) +{ + if( send(s_,s.c_str(),s.length(), MSG_NOSIGNAL) <= 0 ) + { + //printf("SendBytes Socket error!! \n" ); + Close(); + } +} + + + + + +SocketServer::SocketServer(int port, int connections, TypeSocket type) +{ + sockaddr_in sa; + + memset(&sa, 0, sizeof(sa)); + + sa.sin_family = PF_INET; + sa.sin_port = htons(port); + s_ = socket(AF_INET, SOCK_STREAM, 0); + + if (!IsValid()) + { + LOG("WebServer: INVALID_SOCKET"); + } + + if(type==NonBlockingSocket) + { + return; + } + + #ifdef _WIN32 + char yes = 1; + #else + int yes = 1; + #endif + + if (setsockopt(s_,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) + { + LOG("WebServer: setsockopt == -1"); + return; + } + + /* bind the socket to the internet address */ + if (bind(s_, (sockaddr *)&sa, sizeof(sockaddr_in)) == SOCKET_ERROR) + { + closesocket(s_); + LOG("WebServer: INVALID_SOCKET"); + } + + listen(s_, connections); +} + + + + + +Socket* SocketServer::Accept() +{ + Socket * r = new Socket(accept(s_, 0, 0)); + if (!r->IsValid()) + { + delete r; + r = NULL; + } + + return r; +} + + + + + +SocketSelect::SocketSelect(Socket const * const s1, Socket const * const s2, TypeSocket type) +{ + FD_ZERO(&fds_); + SOCKET Highest = s1->s_; + FD_SET(const_cast<Socket*>(s1)->s_,&fds_); + if(s2) + { + FD_SET(const_cast<Socket*>(s2)->s_,&fds_); + if (s2->s_ > Highest) + { + Highest = s2->s_; + } + } + if (select(Highest + 1, &fds_, NULL, NULL, NULL) == SOCKET_ERROR) + { + throw "Error in select"; + } +} + + + + + +bool SocketSelect::Readable(Socket const* const s) +{ + return (FD_ISSET(s->s_,&fds_) != 0); +} + + + + diff --git a/WebServer/StdHelpers.cpp b/WebServer/StdHelpers.cpp index f858c0bc4..63e48a7d2 100644 --- a/WebServer/StdHelpers.cpp +++ b/WebServer/StdHelpers.cpp @@ -1,62 +1,62 @@ -/*
- stdHelpers.cpp
-
- Copyright (C) 2002-2004 René Nyffenegger
-
- This source code is provided 'as-is', without any express or implied
- warranty. In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this source code must not be misrepresented; you must not
- claim that you wrote the original source code. If you use this source code
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
-
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original source code.
-
- 3. This notice may not be removed or altered from any source distribution.
-
- René Nyffenegger rene.nyffenegger@adp-gmbh.ch
-*/
-
-/*
- Note on point 2:
- THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1
-*/
-
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "StdHelpers.h"
-#include <cctype>
-
-std::string ReplaceInStr(const std::string& in, const std::string& search_for, const std::string& replace_with) {
- std::string ret = in;
-
- std::string::size_type pos = ret.find(search_for);
-
- while (pos != std::string::npos) {
- ret = ret.replace(pos, search_for.size(), replace_with);
- pos = pos - search_for.size() + replace_with.size() + 1;
- pos = ret.find(search_for, pos);
- }
-
- return ret;
-}
-
-// std:toupper and std::tolower are overloaded. Well...
-// http://gcc.gnu.org/ml/libstdc++/2002-11/msg00180.html
-char toLower_ (char c) { return std::tolower(c); }
-char toUpper_ (char c) { return std::toupper(c); }
-
-void ToUpper(std::string& s) {
- std::transform(s.begin(), s.end(), s.begin(),toUpper_);
-}
-
-void ToLower(std::string& s) {
- std::transform(s.begin(), s.end(), s.begin(),toLower_);
-}
+/* + stdHelpers.cpp + + Copyright (C) 2002-2004 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ + +/* + Note on point 2: + THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 +*/ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "StdHelpers.h" +#include <cctype> + +std::string ReplaceInStr(const std::string& in, const std::string& search_for, const std::string& replace_with) { + std::string ret = in; + + std::string::size_type pos = ret.find(search_for); + + while (pos != std::string::npos) { + ret = ret.replace(pos, search_for.size(), replace_with); + pos = pos - search_for.size() + replace_with.size() + 1; + pos = ret.find(search_for, pos); + } + + return ret; +} + +// std:toupper and std::tolower are overloaded. Well... +// http://gcc.gnu.org/ml/libstdc++/2002-11/msg00180.html +char toLower_ (char c) { return std::tolower(c); } +char toUpper_ (char c) { return std::toupper(c); } + +void ToUpper(std::string& s) { + std::transform(s.begin(), s.end(), s.begin(),toUpper_); +} + +void ToLower(std::string& s) { + std::transform(s.begin(), s.end(), s.begin(),toLower_); +} diff --git a/WebServer/UrlHelper.cpp b/WebServer/UrlHelper.cpp index 44f1166fd..e0a67687b 100644 --- a/WebServer/UrlHelper.cpp +++ b/WebServer/UrlHelper.cpp @@ -1,165 +1,165 @@ -/*
- UrlHelper.cpp
-
- Copyright (C) 2002-2004 René Nyffenegger
-
- This source code is provided 'as-is', without any express or implied
- warranty. In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this source code must not be misrepresented; you must not
- claim that you wrote the original source code. If you use this source code
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
-
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original source code.
-
- 3. This notice may not be removed or altered from any source distribution.
-
- René Nyffenegger rene.nyffenegger@adp-gmbh.ch
-*/
-
-/*
- Note on point 2:
- THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1
-*/
-
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "UrlHelper.h"
-#include "Tracer.h"
-#include "StdHelpers.h"
-
-#include <sstream>
-#include <iostream>
-
-bool RemoveProtocolFromUrl(std::string const& url, std::string& protocol, std::string& rest) {
- TraceFunc("RemoveProtocolFromUrl");
- Trace(std::string("url='")+url+"'");
- std::string::size_type pos_colon = url.find(":");
-
- if (pos_colon == std::string::npos) {
- rest = url;
- return false;
- }
-
- if (url.size() < pos_colon + 2) {
- rest = url;
- return false;
- }
-
- if (url[pos_colon+1] != '/' ||
- url[pos_colon+2] != '/') {
- rest = url;
- return false;
- }
-
- protocol = url.substr(0,pos_colon);
- rest = url.substr(3+pos_colon); // Skipping three characters ( '://' )
-
- return true;
-}
-
-void SplitGetReq(std::string get_req, std::string& path, std::map<std::string, std::string>& params) {
- TraceFunc("SplitGetReq");
-
- // Remove trailing newlines
- if (get_req[get_req.size()-1] == '\x0d' ||
- get_req[get_req.size()-1] == '\x0a')
- get_req=get_req.substr(0, get_req.size()-1);
-
- if (get_req[get_req.size()-1] == '\x0d' ||
- get_req[get_req.size()-1] == '\x0a')
- get_req=get_req.substr(0, get_req.size()-1);
-
- // Remove potential Trailing HTTP/1.x
- if (get_req.size() > 7) {
- if (get_req.substr(get_req.size()-8, 7) == "HTTP/1.") {
- get_req=get_req.substr(0, get_req.size()-9);
- }
- }
-
- std::string::size_type qm = get_req.find("?");
- if (qm != std::string::npos) {
- std::string url_params = get_req.substr(qm+1);
-
- path = get_req.substr(0, qm);
-
- // Appending a '&' so that there are as many '&' as name-value pairs.
- // It makes it easier to split the url for name value pairs, he he he
- url_params += "&";
-
- std::string::size_type next_amp = url_params.find("&");
-
- while (next_amp != std::string::npos) {
- std::string name_value = url_params.substr(0,next_amp);
- url_params = url_params.substr(next_amp+1);
- next_amp = url_params.find("&");
-
- std::string::size_type pos_equal = name_value.find("=");
-
- std::string nam = name_value.substr(0,pos_equal);
- std::string val = name_value.substr(pos_equal+1);
-
- std::string::size_type pos_plus;
- while ( (pos_plus = val.find("+")) != std::string::npos ) {
- val.replace(pos_plus, 1, " ");
- }
-
- // Replacing %xy notation
- std::string::size_type pos_hex = 0;
- while ( (pos_hex = val.find("%", pos_hex)) != std::string::npos ) {
- std::stringstream h;
- h << val.substr(pos_hex+1, 2);
- h << std::hex;
-
- int i;
- h>>i;
-
- std::stringstream f;
- f << static_cast<char>(i);
- std::string s;
- f >> s;
-
- val.replace(pos_hex, 3, s);
- pos_hex ++;
- }
-
- params.insert(std::map<std::string,std::string>::value_type(nam, val));
- }
- }
- else {
- path = get_req;
- }
-}
-
-void SplitUrl(std::string const& url, std::string& protocol, std::string& server, std::string& path) {
- TraceFunc("SplitUrl");
- RemoveProtocolFromUrl(url, protocol, server);
-
- if (protocol == "http") {
- std::string::size_type pos_slash = server.find("/");
-
- if (pos_slash != std::string::npos) {
- Trace("slash found");
- path = server.substr(pos_slash);
- server = server.substr(0, pos_slash);
- }
- else {
- Trace("slash not found");
- path = "/";
- }
- }
- else if (protocol == "file") {
- path = ReplaceInStr(server, "\\", "/");
- server = "";
- }
- else {
- std::cerr << "unknown protocol in SplitUrl: '" << protocol << "'" << std::endl;
- }
-}
+/* + UrlHelper.cpp + + Copyright (C) 2002-2004 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ + +/* + Note on point 2: + THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 +*/ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "UrlHelper.h" +#include "Tracer.h" +#include "StdHelpers.h" + +#include <sstream> +#include <iostream> + +bool RemoveProtocolFromUrl(std::string const& url, std::string& protocol, std::string& rest) { + TraceFunc("RemoveProtocolFromUrl"); + Trace(std::string("url='")+url+"'"); + std::string::size_type pos_colon = url.find(":"); + + if (pos_colon == std::string::npos) { + rest = url; + return false; + } + + if (url.size() < pos_colon + 2) { + rest = url; + return false; + } + + if (url[pos_colon+1] != '/' || + url[pos_colon+2] != '/') { + rest = url; + return false; + } + + protocol = url.substr(0,pos_colon); + rest = url.substr(3+pos_colon); // Skipping three characters ( '://' ) + + return true; +} + +void SplitGetReq(std::string get_req, std::string& path, std::map<std::string, std::string>& params) { + TraceFunc("SplitGetReq"); + + // Remove trailing newlines + if (get_req[get_req.size()-1] == '\x0d' || + get_req[get_req.size()-1] == '\x0a') + get_req=get_req.substr(0, get_req.size()-1); + + if (get_req[get_req.size()-1] == '\x0d' || + get_req[get_req.size()-1] == '\x0a') + get_req=get_req.substr(0, get_req.size()-1); + + // Remove potential Trailing HTTP/1.x + if (get_req.size() > 7) { + if (get_req.substr(get_req.size()-8, 7) == "HTTP/1.") { + get_req=get_req.substr(0, get_req.size()-9); + } + } + + std::string::size_type qm = get_req.find("?"); + if (qm != std::string::npos) { + std::string url_params = get_req.substr(qm+1); + + path = get_req.substr(0, qm); + + // Appending a '&' so that there are as many '&' as name-value pairs. + // It makes it easier to split the url for name value pairs, he he he + url_params += "&"; + + std::string::size_type next_amp = url_params.find("&"); + + while (next_amp != std::string::npos) { + std::string name_value = url_params.substr(0,next_amp); + url_params = url_params.substr(next_amp+1); + next_amp = url_params.find("&"); + + std::string::size_type pos_equal = name_value.find("="); + + std::string nam = name_value.substr(0,pos_equal); + std::string val = name_value.substr(pos_equal+1); + + std::string::size_type pos_plus; + while ( (pos_plus = val.find("+")) != std::string::npos ) { + val.replace(pos_plus, 1, " "); + } + + // Replacing %xy notation + std::string::size_type pos_hex = 0; + while ( (pos_hex = val.find("%", pos_hex)) != std::string::npos ) { + std::stringstream h; + h << val.substr(pos_hex+1, 2); + h << std::hex; + + int i; + h>>i; + + std::stringstream f; + f << static_cast<char>(i); + std::string s; + f >> s; + + val.replace(pos_hex, 3, s); + pos_hex ++; + } + + params.insert(std::map<std::string,std::string>::value_type(nam, val)); + } + } + else { + path = get_req; + } +} + +void SplitUrl(std::string const& url, std::string& protocol, std::string& server, std::string& path) { + TraceFunc("SplitUrl"); + RemoveProtocolFromUrl(url, protocol, server); + + if (protocol == "http") { + std::string::size_type pos_slash = server.find("/"); + + if (pos_slash != std::string::npos) { + Trace("slash found"); + path = server.substr(pos_slash); + server = server.substr(0, pos_slash); + } + else { + Trace("slash not found"); + path = "/"; + } + } + else if (protocol == "file") { + path = ReplaceInStr(server, "\\", "/"); + server = ""; + } + else { + std::cerr << "unknown protocol in SplitUrl: '" << protocol << "'" << std::endl; + } +} diff --git a/WebServer/WebServer.cpp b/WebServer/WebServer.cpp index 8be690bd1..089be4352 100644 --- a/WebServer/WebServer.cpp +++ b/WebServer/WebServer.cpp @@ -1,497 +1,497 @@ -/*
- WebServer.cpp
-
- Copyright (C) 2003-2007 René Nyffenegger
-
- This source code is provided 'as-is', without any express or implied
- warranty. In no event will the author be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this source code must not be misrepresented; you must not
- claim that you wrote the original source code. If you use this source code
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
-
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original source code.
-
- 3. This notice may not be removed or altered from any source distribution.
-
- René Nyffenegger rene.nyffenegger@adp-gmbh.ch
-
- Thanks to Tom Lynn who pointed out an error in this source code.
-*/
-
-/*
- Note on point 2:
- THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1
-*/
-
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include <ctime>
-#ifdef _WIN32
- #include <process.h>
-#endif
-#include <iostream>
-#include <sstream>
-
-
-#include "WebServer.h"
-#include "cEvents.h"
-#include "Socket.h"
-#include "UrlHelper.h"
-#include "base64.h"
-
-
-
-
-
-webserver::request_func webserver::request_func_ = NULL;
-
-
-
-
-
-static std::string EatLine( std::string& a_String )
-{
- std::string RetVal = "";
- unsigned int StringSize = a_String.size();
- const char* c = a_String.c_str();
-
- for( unsigned int i = 0; i < StringSize; ++i, ++c)
- {
- if( *c == '\n' )
- {
- RetVal += *c;
-// ++i; ++c;
-// if( i < StringSize )
-// {
-// if( *c == '\r' )
-// {
-// RetVal += *c;
-// }
-// }
- break;
- }
- RetVal += *c;
- }
- a_String = a_String.substr( RetVal.size() );
- return RetVal;
-}
-
-
-
-
-
-// Turns
-// "blabla my string with \"quotes\"!"
-// into
-// blabla my string with "quotes"!
-static std::string GetQuotedString( const std::string& a_String )
-{
- std::string RetVal;
-
- bool bGotFirstQuote = false;
- bool bIgnoreNext = false;
- unsigned int StrLen = a_String.size();
- for( unsigned int i = 0; i < StrLen; ++i )
- {
- if( bIgnoreNext == false )
- {
- if( a_String[i] == '\"' )
- {
- if( bGotFirstQuote == false )
- {
- bGotFirstQuote = true;
- }
- else
- {
- break;
- }
- continue;
- }
- else if( a_String[i] == '\\' ) // Escape character
- {
- bIgnoreNext = true;
- continue;
- }
- }
- RetVal.push_back( a_String[i] );
- bIgnoreNext = false;
- }
-
- return RetVal;
-}
-
-
-
-
-
-void ParseMultipartFormData( webserver::http_request& req, Socket* s)
-{
- static const std::string multipart_form_data = "multipart/form-data";
- if(req.content_type_.substr(0, multipart_form_data.size()) == multipart_form_data) // Difficult data... :(
- {
- AStringVector ContentTypeData = StringSplit( req.content_type_, "; " );
-
- std::string boundary;
- // Find boundary
- for( unsigned int i = 0; i < ContentTypeData.size(); ++i )
- {
- static const std::string boundary_ = "boundary=";
- if( ContentTypeData[i].substr(0, boundary_.size()) == boundary_ ) // Found boundary
- {
- boundary = ContentTypeData[i].substr( boundary_.size() );
- }
- }
-
- //LOGINFO("Boundary: %s", boundary.c_str() );
- std::string boundary_start = "--" + boundary;
- std::string boundary_end = boundary_start + "--";
-
- std::string Content = s->ReceiveBytes( req.content_length_ );
-
- //printf("Total content: \n%s\n", Content.c_str() );
-
- // Should start with boundary!
- std::string line = EatLine( Content );
- if( line.substr(0, boundary_start.size() ) != boundary_start )
- {
- // Something was wrong! :(
- Content.clear();
- }
-
- while( !Content.empty() )
- {
- webserver::formdata FormData;
-
- static const std::string content_disposition = "Content-Disposition: ";
- static const std::string content_type = "Content-Type: ";
-
- std::string f_disposition;
-
- while( 1 )
- {
- std::string line = EatLine( Content );
- if( line.empty() )
- break;
-
- unsigned int pos_cr_lf = line.find_first_of("\x0a\x0d");
- if (pos_cr_lf == 0) break; // Empty line, indicates end of mime thingy
-
- if( line.substr(0, content_disposition.size() ) == content_disposition )
- {
- f_disposition = line.substr(content_disposition.size());
- LOGINFO("Disposition: %s", f_disposition.c_str() );
- }
- else if( line.substr(0, content_type.size() ) == content_type )
- {
- FormData.content_type_ = line.substr(content_type.size());
- }
-
- //LOGINFO("Got line: '%s'", line.c_str() );
- }
-
- // Check if we got the proper headers
- if( !f_disposition.empty() )
- {
- static const std::string disp_name = "name=";
- static const std::string disp_filename = "filename=";
-
- // Parse the disposition
- AStringVector DispositionData = StringSplit( f_disposition, "; " );
- for( unsigned int i = 0; i < DispositionData.size(); ++i )
- {
- if( DispositionData[i].substr(0, disp_name.size()) == disp_name )
- {
- FormData.name_ = GetQuotedString( DispositionData[i].substr(disp_name.size()) );
- }
- else if( DispositionData[i].substr(0, disp_filename.size()) == disp_filename )
- {
- FormData.filename_ = GetQuotedString( DispositionData[i].substr(disp_filename.size()) );
- }
- }
-
- std::string ContentValue;
- // Parse until boundary_end is found
- while( 1 )
- {
- std::string line = EatLine( Content );
- if( line.empty() )
- break;
-
- if( line.substr(0, boundary_end.size() ) == boundary_end )
- {
- break;
- }
- else if( line.substr(0, boundary_start.size() ) == boundary_start )
- {
- break;
- }
- ContentValue.append( line.c_str(), line.size() );
- }
-
-
- FormData.value_ = ContentValue;
- }
-
- req.multipart_formdata_.push_back( FormData );
- }
- }
-}
-
-
-
-
-
-#ifdef _WIN32
-unsigned webserver::Request(void* ptr_s)
-#else
-void* webserver::Request(void* ptr_s)
-#endif
-{
- Socket* s = (reinterpret_cast<Socket*>(ptr_s));
-
- std::string line = s->ReceiveLine();
- if (line.empty())
- {
- s->Close();
- delete s;
- return 0;
- }
-
- http_request req;
- std::string path;
- std::map<std::string, std::string> params;
- size_t posStartPath = 0;
-
- if (line.find("GET") == 0)
- {
- req.method_="GET";
- posStartPath = line.find_first_not_of(" ",3);
- }
- else if (line.find("POST") == 0)
- {
- req.method_="POST";
- posStartPath = line.find_first_not_of(" ",4);
- }
-
- SplitGetReq(line.substr(posStartPath), path, params);
-
- req.status_ = "202 OK";
- req.s_ = s;
- req.path_ = path;
- req.params_ = params;
-
- static const std::string authorization = "Authorization: Basic ";
- static const std::string accept = "Accept: " ;
- static const std::string accept_language = "Accept-Language: " ;
- static const std::string accept_encoding = "Accept-Encoding: " ;
- static const std::string user_agent = "User-Agent: " ;
- static const std::string content_length = "Content-Length: " ;
- static const std::string content_type = "Content-Type: " ;
-
- while(1)
- {
- line=s->ReceiveLine();
- if (line.empty())
- {
- break;
- }
-
- unsigned int pos_cr_lf = line.find_first_of("\x0a\x0d");
- if (pos_cr_lf == 0) break;
-
- line = line.substr(0,pos_cr_lf);
-
- if (line.substr(0, authorization.size()) == authorization)
- {
- req.authentication_given_ = true;
- std::string encoded = line.substr(authorization.size());
- std::string decoded = base64_decode(encoded);
-
- unsigned int pos_colon = decoded.find(":");
-
- req.username_ = decoded.substr(0, pos_colon);
- req.password_ = decoded.substr(pos_colon+1 );
- }
- else if (line.substr(0, accept.size()) == accept)
- {
- req.accept_ = line.substr(accept.size());
- }
- else if (line.substr(0, accept_language.size()) == accept_language)
- {
- req.accept_language_ = line.substr(accept_language.size());
- }
- else if (line.substr(0, accept_encoding.size()) == accept_encoding)
- {
- req.accept_encoding_ = line.substr(accept_encoding.size());
- }
- else if (line.substr(0, user_agent.size()) == user_agent)
- {
- req.user_agent_ = line.substr(user_agent.size());
- }
- else if (line.substr(0, content_length.size()) == content_length)
- {
- req.content_length_ = atoi( line.substr(content_length.size()).c_str() );
- }
- else if (line.substr(0, content_type.size()) == content_type)
- {
- req.content_type_ = line.substr(content_type.size());
- }
- }
-
- if( (req.method_.compare("POST") == 0) && (req.content_length_ > 0) )
- {
- // The only content type we can parse at the moment, the default HTML post data
- if( req.content_type_.compare( "application/x-www-form-urlencoded" ) == 0 )
- {
- std::string Content = s->ReceiveBytes( req.content_length_ );
- Content.insert( 0, "/ ?" ); // Little hack, inserts dummy URL so that SplitGetReq() can work with this content
-
- std::string dummy;
- std::map<std::string, std::string> post_params;
- SplitGetReq(Content, dummy, post_params);
-
- req.params_post_ = post_params;
- }
- else
- {
- ParseMultipartFormData( req, s );
- }
- }
-
- request_func_(&req);
-
- std::stringstream str_str;
- str_str << req.answer_.size();
-
- time_t ltime;
- time(<ime);
- tm* gmt= gmtime(<ime);
-
-#ifdef _WIN32
- static std::string const serverName = "MCServerWebAdmin (Windows)";
-#elif __APPLE__
- static std::string const serverName = "MCServerWebAdmin (MacOSX)";
-#else
- static std::string const serverName = "MCServerWebAdmin (Linux)";
-#endif
-
-
- char* asctime_remove_nl = std::asctime(gmt);
- asctime_remove_nl[24] = 0;
-
- s->SendBytes("HTTP/1.1 ");
-
- if (! req.auth_realm_.empty() )
- {
- s->SendLine("401 Unauthorized");
- s->SendBytes("WWW-Authenticate: Basic Realm=\"");
- s->SendBytes(req.auth_realm_);
- s->SendLine("\"");
- }
- else
- {
- s->SendLine(req.status_);
- }
- s->SendLine(std::string("Date: ") + asctime_remove_nl + " GMT");
- s->SendLine(std::string("Server: ") +serverName);
- s->SendLine("Connection: close");
- s->SendLine("Content-Type: text/html; charset=ISO-8859-1");
- s->SendLine("Content-Length: " + str_str.str());
- s->SendLine("");
- s->SendLine(req.answer_);
-
- s->Close( true ); // true = wait for all data to be sent before closing
- delete s;
-
-
- return 0;
-}
-
-
-
-
-
-void webserver::Stop()
-{
- m_bStop = true;
- m_Socket->Close();
- m_Events->Wait();
-}
-
-
-
-
-
-bool webserver::Begin()
-{
- if (!m_Socket->IsValid())
- {
- LOGINFO("WebAdmin: The server socket is invalid. Terminating WebAdmin.");
- return false;
- }
- m_bStop = false;
- while ( !m_bStop )
- {
- Socket * ptr_s = m_Socket->Accept();
- if (m_bStop)
- {
- if (ptr_s != 0)
- {
- ptr_s->Close();
- delete ptr_s;
- }
- break;
- }
- if (ptr_s == NULL)
- {
- LOGINFO("WebAdmin: Accepted socket is NULL. Terminating WebAdmin to avoid busywait.");
- return false;
- }
-
- #ifdef _WIN32
- unsigned ret;
- HANDLE hHandle = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, Request, (void *)ptr_s, 0, &ret));
- CloseHandle(hHandle);
- #else
- // Mattes: TODO: this handle probably leaks!
- pthread_t * hHandle = new pthread_t;
- pthread_create( hHandle, NULL, Request, ptr_s);
- #endif
- }
- m_Events->Set();
- return true;
-}
-
-
-
-
-
-webserver::webserver(unsigned int port_to_listen, request_func r)
-{
- m_Socket = new SocketServer(port_to_listen, 1);
-
- request_func_ = r;
- m_Events = new cEvents();
-}
-
-
-
-
-
-webserver::~webserver()
-{
- delete m_Socket;
- delete m_Events;
-}
-
-
-
-
+/* + WebServer.cpp + + Copyright (C) 2003-2007 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch + + Thanks to Tom Lynn who pointed out an error in this source code. +*/ + +/* + Note on point 2: + THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1 +*/ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include <ctime> +#ifdef _WIN32 + #include <process.h> +#endif +#include <iostream> +#include <sstream> + + +#include "WebServer.h" +#include "cEvents.h" +#include "Socket.h" +#include "UrlHelper.h" +#include "base64.h" + + + + + +webserver::request_func webserver::request_func_ = NULL; + + + + + +static std::string EatLine( std::string& a_String ) +{ + std::string RetVal = ""; + unsigned int StringSize = a_String.size(); + const char* c = a_String.c_str(); + + for( unsigned int i = 0; i < StringSize; ++i, ++c) + { + if( *c == '\n' ) + { + RetVal += *c; +// ++i; ++c; +// if( i < StringSize ) +// { +// if( *c == '\r' ) +// { +// RetVal += *c; +// } +// } + break; + } + RetVal += *c; + } + a_String = a_String.substr( RetVal.size() ); + return RetVal; +} + + + + + +// Turns +// "blabla my string with \"quotes\"!" +// into +// blabla my string with "quotes"! +static std::string GetQuotedString( const std::string& a_String ) +{ + std::string RetVal; + + bool bGotFirstQuote = false; + bool bIgnoreNext = false; + unsigned int StrLen = a_String.size(); + for( unsigned int i = 0; i < StrLen; ++i ) + { + if( bIgnoreNext == false ) + { + if( a_String[i] == '\"' ) + { + if( bGotFirstQuote == false ) + { + bGotFirstQuote = true; + } + else + { + break; + } + continue; + } + else if( a_String[i] == '\\' ) // Escape character + { + bIgnoreNext = true; + continue; + } + } + RetVal.push_back( a_String[i] ); + bIgnoreNext = false; + } + + return RetVal; +} + + + + + +void ParseMultipartFormData( webserver::http_request& req, Socket* s) +{ + static const std::string multipart_form_data = "multipart/form-data"; + if(req.content_type_.substr(0, multipart_form_data.size()) == multipart_form_data) // Difficult data... :( + { + AStringVector ContentTypeData = StringSplit( req.content_type_, "; " ); + + std::string boundary; + // Find boundary + for( unsigned int i = 0; i < ContentTypeData.size(); ++i ) + { + static const std::string boundary_ = "boundary="; + if( ContentTypeData[i].substr(0, boundary_.size()) == boundary_ ) // Found boundary + { + boundary = ContentTypeData[i].substr( boundary_.size() ); + } + } + + //LOGINFO("Boundary: %s", boundary.c_str() ); + std::string boundary_start = "--" + boundary; + std::string boundary_end = boundary_start + "--"; + + std::string Content = s->ReceiveBytes( req.content_length_ ); + + //printf("Total content: \n%s\n", Content.c_str() ); + + // Should start with boundary! + std::string line = EatLine( Content ); + if( line.substr(0, boundary_start.size() ) != boundary_start ) + { + // Something was wrong! :( + Content.clear(); + } + + while( !Content.empty() ) + { + webserver::formdata FormData; + + static const std::string content_disposition = "Content-Disposition: "; + static const std::string content_type = "Content-Type: "; + + std::string f_disposition; + + while( 1 ) + { + std::string line = EatLine( Content ); + if( line.empty() ) + break; + + unsigned int pos_cr_lf = line.find_first_of("\x0a\x0d"); + if (pos_cr_lf == 0) break; // Empty line, indicates end of mime thingy + + if( line.substr(0, content_disposition.size() ) == content_disposition ) + { + f_disposition = line.substr(content_disposition.size()); + LOGINFO("Disposition: %s", f_disposition.c_str() ); + } + else if( line.substr(0, content_type.size() ) == content_type ) + { + FormData.content_type_ = line.substr(content_type.size()); + } + + //LOGINFO("Got line: '%s'", line.c_str() ); + } + + // Check if we got the proper headers + if( !f_disposition.empty() ) + { + static const std::string disp_name = "name="; + static const std::string disp_filename = "filename="; + + // Parse the disposition + AStringVector DispositionData = StringSplit( f_disposition, "; " ); + for( unsigned int i = 0; i < DispositionData.size(); ++i ) + { + if( DispositionData[i].substr(0, disp_name.size()) == disp_name ) + { + FormData.name_ = GetQuotedString( DispositionData[i].substr(disp_name.size()) ); + } + else if( DispositionData[i].substr(0, disp_filename.size()) == disp_filename ) + { + FormData.filename_ = GetQuotedString( DispositionData[i].substr(disp_filename.size()) ); + } + } + + std::string ContentValue; + // Parse until boundary_end is found + while( 1 ) + { + std::string line = EatLine( Content ); + if( line.empty() ) + break; + + if( line.substr(0, boundary_end.size() ) == boundary_end ) + { + break; + } + else if( line.substr(0, boundary_start.size() ) == boundary_start ) + { + break; + } + ContentValue.append( line.c_str(), line.size() ); + } + + + FormData.value_ = ContentValue; + } + + req.multipart_formdata_.push_back( FormData ); + } + } +} + + + + + +#ifdef _WIN32 +unsigned webserver::Request(void* ptr_s) +#else +void* webserver::Request(void* ptr_s) +#endif +{ + Socket* s = (reinterpret_cast<Socket*>(ptr_s)); + + std::string line = s->ReceiveLine(); + if (line.empty()) + { + s->Close(); + delete s; + return 0; + } + + http_request req; + std::string path; + std::map<std::string, std::string> params; + size_t posStartPath = 0; + + if (line.find("GET") == 0) + { + req.method_="GET"; + posStartPath = line.find_first_not_of(" ",3); + } + else if (line.find("POST") == 0) + { + req.method_="POST"; + posStartPath = line.find_first_not_of(" ",4); + } + + SplitGetReq(line.substr(posStartPath), path, params); + + req.status_ = "202 OK"; + req.s_ = s; + req.path_ = path; + req.params_ = params; + + static const std::string authorization = "Authorization: Basic "; + static const std::string accept = "Accept: " ; + static const std::string accept_language = "Accept-Language: " ; + static const std::string accept_encoding = "Accept-Encoding: " ; + static const std::string user_agent = "User-Agent: " ; + static const std::string content_length = "Content-Length: " ; + static const std::string content_type = "Content-Type: " ; + + while(1) + { + line=s->ReceiveLine(); + if (line.empty()) + { + break; + } + + unsigned int pos_cr_lf = line.find_first_of("\x0a\x0d"); + if (pos_cr_lf == 0) break; + + line = line.substr(0,pos_cr_lf); + + if (line.substr(0, authorization.size()) == authorization) + { + req.authentication_given_ = true; + std::string encoded = line.substr(authorization.size()); + std::string decoded = base64_decode(encoded); + + unsigned int pos_colon = decoded.find(":"); + + req.username_ = decoded.substr(0, pos_colon); + req.password_ = decoded.substr(pos_colon+1 ); + } + else if (line.substr(0, accept.size()) == accept) + { + req.accept_ = line.substr(accept.size()); + } + else if (line.substr(0, accept_language.size()) == accept_language) + { + req.accept_language_ = line.substr(accept_language.size()); + } + else if (line.substr(0, accept_encoding.size()) == accept_encoding) + { + req.accept_encoding_ = line.substr(accept_encoding.size()); + } + else if (line.substr(0, user_agent.size()) == user_agent) + { + req.user_agent_ = line.substr(user_agent.size()); + } + else if (line.substr(0, content_length.size()) == content_length) + { + req.content_length_ = atoi( line.substr(content_length.size()).c_str() ); + } + else if (line.substr(0, content_type.size()) == content_type) + { + req.content_type_ = line.substr(content_type.size()); + } + } + + if( (req.method_.compare("POST") == 0) && (req.content_length_ > 0) ) + { + // The only content type we can parse at the moment, the default HTML post data + if( req.content_type_.compare( "application/x-www-form-urlencoded" ) == 0 ) + { + std::string Content = s->ReceiveBytes( req.content_length_ ); + Content.insert( 0, "/ ?" ); // Little hack, inserts dummy URL so that SplitGetReq() can work with this content + + std::string dummy; + std::map<std::string, std::string> post_params; + SplitGetReq(Content, dummy, post_params); + + req.params_post_ = post_params; + } + else + { + ParseMultipartFormData( req, s ); + } + } + + request_func_(&req); + + std::stringstream str_str; + str_str << req.answer_.size(); + + time_t ltime; + time(<ime); + tm* gmt= gmtime(<ime); + +#ifdef _WIN32 + static std::string const serverName = "MCServerWebAdmin (Windows)"; +#elif __APPLE__ + static std::string const serverName = "MCServerWebAdmin (MacOSX)"; +#else + static std::string const serverName = "MCServerWebAdmin (Linux)"; +#endif + + + char* asctime_remove_nl = std::asctime(gmt); + asctime_remove_nl[24] = 0; + + s->SendBytes("HTTP/1.1 "); + + if (! req.auth_realm_.empty() ) + { + s->SendLine("401 Unauthorized"); + s->SendBytes("WWW-Authenticate: Basic Realm=\""); + s->SendBytes(req.auth_realm_); + s->SendLine("\""); + } + else + { + s->SendLine(req.status_); + } + s->SendLine(std::string("Date: ") + asctime_remove_nl + " GMT"); + s->SendLine(std::string("Server: ") +serverName); + s->SendLine("Connection: close"); + s->SendLine("Content-Type: text/html; charset=ISO-8859-1"); + s->SendLine("Content-Length: " + str_str.str()); + s->SendLine(""); + s->SendLine(req.answer_); + + s->Close( true ); // true = wait for all data to be sent before closing + delete s; + + + return 0; +} + + + + + +void webserver::Stop() +{ + m_bStop = true; + m_Socket->Close(); + m_Events->Wait(); +} + + + + + +bool webserver::Begin() +{ + if (!m_Socket->IsValid()) + { + LOGINFO("WebAdmin: The server socket is invalid. Terminating WebAdmin."); + return false; + } + m_bStop = false; + while ( !m_bStop ) + { + Socket * ptr_s = m_Socket->Accept(); + if (m_bStop) + { + if (ptr_s != 0) + { + ptr_s->Close(); + delete ptr_s; + } + break; + } + if (ptr_s == NULL) + { + LOGINFO("WebAdmin: Accepted socket is NULL. Terminating WebAdmin to avoid busywait."); + return false; + } + + #ifdef _WIN32 + unsigned ret; + HANDLE hHandle = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, Request, (void *)ptr_s, 0, &ret)); + CloseHandle(hHandle); + #else + // Mattes: TODO: this handle probably leaks! + pthread_t * hHandle = new pthread_t; + pthread_create( hHandle, NULL, Request, ptr_s); + #endif + } + m_Events->Set(); + return true; +} + + + + + +webserver::webserver(unsigned int port_to_listen, request_func r) +{ + m_Socket = new SocketServer(port_to_listen, 1); + + request_func_ = r; + m_Events = new cEvents(); +} + + + + + +webserver::~webserver() +{ + delete m_Socket; + delete m_Events; +} + + + + diff --git a/WebServer/base64.cpp b/WebServer/base64.cpp index 72cd7cd59..4c19b600b 100644 --- a/WebServer/base64.cpp +++ b/WebServer/base64.cpp @@ -1,99 +1,99 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "base64.h"
-#include <iostream>
-
-static const std::string base64_chars =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789+/";
-
-
-static inline bool is_base64(unsigned char c) {
- return (isalnum(c) || (c == '+') || (c == '/'));
-}
-
-std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
- std::string ret;
- int i = 0;
- int j = 0;
- unsigned char char_array_3[3];
- unsigned char char_array_4[4];
-
- while (in_len--) {
- char_array_3[i++] = *(bytes_to_encode++);
- if (i == 3) {
- char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
- char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
- char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
- char_array_4[3] = char_array_3[2] & 0x3f;
-
- for(i = 0; (i <4) ; i++)
- ret += base64_chars[char_array_4[i]];
- i = 0;
- }
- }
-
- if (i)
- {
- for(j = i; j < 3; j++)
- char_array_3[j] = '\0';
-
- char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
- char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
- char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
- char_array_4[3] = char_array_3[2] & 0x3f;
-
- for (j = 0; (j < i + 1); j++)
- ret += base64_chars[char_array_4[j]];
-
- while((i++ < 3))
- ret += '=';
-
- }
-
- return ret;
-
-}
-
-std::string base64_decode(std::string const& encoded_string) {
- int in_len = encoded_string.size();
- int i = 0;
- int j = 0;
- int in_ = 0;
- unsigned char char_array_4[4], char_array_3[3];
- std::string ret;
-
- while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
- char_array_4[i++] = encoded_string[in_]; in_++;
- if (i ==4) {
- for (i = 0; i <4; i++)
- char_array_4[i] = base64_chars.find(char_array_4[i]);
-
- char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
- char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
- char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
-
- for (i = 0; (i < 3); i++)
- ret += char_array_3[i];
- i = 0;
- }
- }
-
- if (i) {
- for (j = i; j <4; j++)
- char_array_4[j] = 0;
-
- for (j = 0; j <4; j++)
- char_array_4[j] = base64_chars.find(char_array_4[j]);
-
- char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
- char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
- char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
-
- for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
- }
-
- return ret;
-}
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "base64.h" +#include <iostream> + +static const std::string base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + + +static inline bool is_base64(unsigned char c) { + return (isalnum(c) || (c == '+') || (c == '/')); +} + +std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { + std::string ret; + int i = 0; + int j = 0; + unsigned char char_array_3[3]; + unsigned char char_array_4[4]; + + while (in_len--) { + char_array_3[i++] = *(bytes_to_encode++); + if (i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for(i = 0; (i <4) ; i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if (i) + { + for(j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (j = 0; (j < i + 1); j++) + ret += base64_chars[char_array_4[j]]; + + while((i++ < 3)) + ret += '='; + + } + + return ret; + +} + +std::string base64_decode(std::string const& encoded_string) { + int in_len = encoded_string.size(); + int i = 0; + int j = 0; + int in_ = 0; + unsigned char char_array_4[4], char_array_3[3]; + std::string ret; + + while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { + char_array_4[i++] = encoded_string[in_]; in_++; + if (i ==4) { + for (i = 0; i <4; i++) + char_array_4[i] = base64_chars.find(char_array_4[i]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) + ret += char_array_3[i]; + i = 0; + } + } + + if (i) { + for (j = i; j <4; j++) + char_array_4[j] = 0; + + for (j = 0; j <4; j++) + char_array_4[j] = base64_chars.find(char_array_4[j]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; + } + + return ret; +} diff --git a/WebServer/cEvents.cpp b/WebServer/cEvents.cpp index 4c9fa8775..a00a0e817 100644 --- a/WebServer/cEvents.cpp +++ b/WebServer/cEvents.cpp @@ -1,125 +1,125 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cEvents.h"
-
-
-
-
-
-cEvents::cEvents( unsigned int a_NumEvents /* = 1 */ )
- : m_NumEvents( a_NumEvents )
-#ifndef _WIN32
- , m_bNamed( false )
-#endif
-{
- if( m_NumEvents < 1 ) m_NumEvents = 1;
-
-#ifdef _WIN32
- m_Handle = new HANDLE[ m_NumEvents ];
- for( unsigned int i = 0; i < m_NumEvents; i++)
- {
- ((HANDLE*)m_Handle)[i] = CreateEvent( 0, FALSE, FALSE, 0 );
- }
-#else
- m_Handle = new sem_t*[ m_NumEvents ];
- for( unsigned int i = 0; i < m_NumEvents; i++)
- {
-
- sem_t* & HandlePtr = ((sem_t**)m_Handle)[i];
- HandlePtr = new sem_t;
-
- if( sem_init( HandlePtr, 0, 0 ) )
- {
- LOG("WARNING cEvents: Could not create unnamed semaphore, fallback to named.");
- m_bNamed = true;
- delete HandlePtr; // named semaphores return their own address
-
- char c_Str[32];
- sprintf( c_Str, "cEvents%p", &HandlePtr );
- HandlePtr = sem_open( c_Str, O_CREAT, 777, 0 );
- if( HandlePtr == SEM_FAILED )
- LOG("ERROR: Could not create Event. (%i)", errno);
- else
- if( sem_unlink( c_Str ) != 0 )
- LOG("ERROR: Could not unlink cEvents. (%i)", errno);
- }
- }
-#endif
-}
-
-
-
-
-
-cEvents::~cEvents()
-{
-#ifdef _WIN32
- for( unsigned int i = 0; i < m_NumEvents; i++ )
- {
- CloseHandle( ((HANDLE*)m_Handle)[i] );
- }
- delete [] (HANDLE*)m_Handle;
-#else
- for( unsigned int i = 0; i < m_NumEvents; i++ )
- {
- if( m_bNamed )
- {
- sem_t* & HandlePtr = ((sem_t**)m_Handle)[i];
- char c_Str[32];
- sprintf( c_Str, "cEvents%p", &HandlePtr );
- // LOG("Closing event: %s", c_Str );
- // LOG("Sem ptr: %p", HandlePtr );
- if( sem_close( HandlePtr ) != 0 )
- {
- LOG("ERROR: Could not close cEvents. (%i)", errno);
- }
- }
- else
- {
- sem_destroy( ((sem_t**)m_Handle)[i] );
- delete ((sem_t**)m_Handle)[i];
- }
- }
- delete [] (sem_t**)m_Handle; m_Handle = 0;
-#endif
-}
-
-
-
-
-
-void cEvents::Wait()
-{
-#ifdef _WIN32
- WaitForMultipleObjects( m_NumEvents, (HANDLE*)m_Handle, true, INFINITE );
-#else
- for(unsigned int i = 0; i < m_NumEvents; i++)
- {
- if( sem_wait( ((sem_t**)m_Handle)[i] ) != 0 )
- {
- LOG("ERROR: Could not wait for cEvents. (%i)", errno);
- }
- }
-#endif
-}
-
-
-
-
-
-void cEvents::Set(unsigned int a_EventNum /* = 0 */)
-{
-#ifdef _WIN32
- SetEvent( ((HANDLE*)m_Handle)[a_EventNum] );
-#else
- if( sem_post( ((sem_t**)m_Handle)[a_EventNum] ) != 0 )
- {
- LOG("ERROR: Could not set cEvents. (%i)", errno);
- }
-#endif
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cEvents.h" + + + + + +cEvents::cEvents( unsigned int a_NumEvents /* = 1 */ ) + : m_NumEvents( a_NumEvents ) +#ifndef _WIN32 + , m_bNamed( false ) +#endif +{ + if( m_NumEvents < 1 ) m_NumEvents = 1; + +#ifdef _WIN32 + m_Handle = new HANDLE[ m_NumEvents ]; + for( unsigned int i = 0; i < m_NumEvents; i++) + { + ((HANDLE*)m_Handle)[i] = CreateEvent( 0, FALSE, FALSE, 0 ); + } +#else + m_Handle = new sem_t*[ m_NumEvents ]; + for( unsigned int i = 0; i < m_NumEvents; i++) + { + + sem_t* & HandlePtr = ((sem_t**)m_Handle)[i]; + HandlePtr = new sem_t; + + if( sem_init( HandlePtr, 0, 0 ) ) + { + LOG("WARNING cEvents: Could not create unnamed semaphore, fallback to named."); + m_bNamed = true; + delete HandlePtr; // named semaphores return their own address + + char c_Str[32]; + sprintf( c_Str, "cEvents%p", &HandlePtr ); + HandlePtr = sem_open( c_Str, O_CREAT, 777, 0 ); + if( HandlePtr == SEM_FAILED ) + LOG("ERROR: Could not create Event. (%i)", errno); + else + if( sem_unlink( c_Str ) != 0 ) + LOG("ERROR: Could not unlink cEvents. (%i)", errno); + } + } +#endif +} + + + + + +cEvents::~cEvents() +{ +#ifdef _WIN32 + for( unsigned int i = 0; i < m_NumEvents; i++ ) + { + CloseHandle( ((HANDLE*)m_Handle)[i] ); + } + delete [] (HANDLE*)m_Handle; +#else + for( unsigned int i = 0; i < m_NumEvents; i++ ) + { + if( m_bNamed ) + { + sem_t* & HandlePtr = ((sem_t**)m_Handle)[i]; + char c_Str[32]; + sprintf( c_Str, "cEvents%p", &HandlePtr ); + // LOG("Closing event: %s", c_Str ); + // LOG("Sem ptr: %p", HandlePtr ); + if( sem_close( HandlePtr ) != 0 ) + { + LOG("ERROR: Could not close cEvents. (%i)", errno); + } + } + else + { + sem_destroy( ((sem_t**)m_Handle)[i] ); + delete ((sem_t**)m_Handle)[i]; + } + } + delete [] (sem_t**)m_Handle; m_Handle = 0; +#endif +} + + + + + +void cEvents::Wait() +{ +#ifdef _WIN32 + WaitForMultipleObjects( m_NumEvents, (HANDLE*)m_Handle, true, INFINITE ); +#else + for(unsigned int i = 0; i < m_NumEvents; i++) + { + if( sem_wait( ((sem_t**)m_Handle)[i] ) != 0 ) + { + LOG("ERROR: Could not wait for cEvents. (%i)", errno); + } + } +#endif +} + + + + + +void cEvents::Set(unsigned int a_EventNum /* = 0 */) +{ +#ifdef _WIN32 + SetEvent( ((HANDLE*)m_Handle)[a_EventNum] ); +#else + if( sem_post( ((sem_t**)m_Handle)[a_EventNum] ) != 0 ) + { + LOG("ERROR: Could not set cEvents. (%i)", errno); + } +#endif +} + + + + diff --git a/converter/source/MemoryLeak.h b/converter/source/MemoryLeak.h index 6ac06a302..2d62f2a4b 100644 --- a/converter/source/MemoryLeak.h +++ b/converter/source/MemoryLeak.h @@ -1,18 +1,18 @@ -#pragma once
-
-#ifdef _WIN32
-
-#ifdef _DEBUG
-
-#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>
-#include <crtdbg.h>
-
-#ifndef DEBUG_NEW
-#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
-#define new DEBUG_NEW
-#endif
-
-#endif
-
-#endif
+#pragma once + +#ifdef _WIN32 + +#ifdef _DEBUG + +#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> + +#ifndef DEBUG_NEW +#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) +#define new DEBUG_NEW +#endif + +#endif + +#endif diff --git a/converter/source/cDeNotch.cpp b/converter/source/cDeNotch.cpp index 89075a92e..75d4ffa9d 100644 --- a/converter/source/cDeNotch.cpp +++ b/converter/source/cDeNotch.cpp @@ -25,10 +25,10 @@ inline bool fOpenFile( FILE*& a_hFile, const char* a_FileName, const char* a_Mode ) { -#ifdef _WIN32
- return fopen_s(&a_hFile, a_FileName, a_Mode ) == 0;
-#else
- return (a_hFile = fopen(a_FileName, a_Mode )) != 0;
+#ifdef _WIN32 + return fopen_s(&a_hFile, a_FileName, a_Mode ) == 0; +#else + return (a_hFile = fopen(a_FileName, a_Mode )) != 0; #endif } diff --git a/converter/source/cMakeDir.cpp b/converter/source/cMakeDir.cpp index 60817d5aa..579d39359 100644 --- a/converter/source/cMakeDir.cpp +++ b/converter/source/cMakeDir.cpp @@ -1,24 +1,24 @@ -#include "cMakeDir.h"
-
-#ifndef _WIN32
-//#include <cstring> // If something is missing, uncomment some of these!
-//#include <cstdlib>
-//#include <stdio.h>
-#include <sys/stat.h> // for mkdir
-//#include <sys/types.h>
-#else
-#include <Windows.h>
-#endif
-
-void cMakeDir::MakeDir( const char* a_Directory )
-{
-#ifdef _WIN32
- SECURITY_ATTRIBUTES Attrib;
- Attrib.nLength = sizeof(SECURITY_ATTRIBUTES);
- Attrib.lpSecurityDescriptor = NULL;
- Attrib.bInheritHandle = false;
- ::CreateDirectory(a_Directory, &Attrib);
-#else
- mkdir(a_Directory, S_IRWXU | S_IRWXG | S_IRWXO);
-#endif
+#include "cMakeDir.h" + +#ifndef _WIN32 +//#include <cstring> // If something is missing, uncomment some of these! +//#include <cstdlib> +//#include <stdio.h> +#include <sys/stat.h> // for mkdir +//#include <sys/types.h> +#else +#include <Windows.h> +#endif + +void cMakeDir::MakeDir( const char* a_Directory ) +{ +#ifdef _WIN32 + SECURITY_ATTRIBUTES Attrib; + Attrib.nLength = sizeof(SECURITY_ATTRIBUTES); + Attrib.lpSecurityDescriptor = NULL; + Attrib.bInheritHandle = false; + ::CreateDirectory(a_Directory, &Attrib); +#else + mkdir(a_Directory, S_IRWXU | S_IRWXG | S_IRWXO); +#endif }
\ No newline at end of file diff --git a/converter/source/cMakeDir.h b/converter/source/cMakeDir.h index 378df2a36..240b76507 100644 --- a/converter/source/cMakeDir.h +++ b/converter/source/cMakeDir.h @@ -1,7 +1,7 @@ -#pragma once
-
-class cMakeDir
-{
-public:
- static void MakeDir( const char* a_Directory );
+#pragma once + +class cMakeDir +{ +public: + static void MakeDir( const char* a_Directory ); };
\ No newline at end of file diff --git a/converter/source/main.cpp b/converter/source/main.cpp index 6239cbd43..5df378cd6 100644 --- a/converter/source/main.cpp +++ b/converter/source/main.cpp @@ -14,8 +14,8 @@ int main () { -#ifdef _DEBUG
- _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
+#ifdef _DEBUG + _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif cTimer Timer; @@ -63,8 +63,8 @@ int main () clock_t progEnd = clock(); //end main program timer std::cout << "Time to complete converter: " << double(Timer.diffclock(progEnd,progBegin)) << " Seconds"<< std::endl; -#ifdef _DEBUG
- _CrtDumpMemoryLeaks();
+#ifdef _DEBUG + _CrtDumpMemoryLeaks(); #endif #ifdef _WIN32 diff --git a/iniFile/iniFile.cpp b/iniFile/iniFile.cpp index 5d162ee49..8134ade8c 100644 --- a/iniFile/iniFile.cpp +++ b/iniFile/iniFile.cpp @@ -1,606 +1,606 @@ -// IniFile.cpp: Implementation of the CIniFile class.
-// Written by: Adam Clauss
-// Email: cabadam@houston.rr.com
-// You may use this class/code as you wish in your programs. Feel free to distribute it, and
-// email suggested changes to me.
-//
-// Rewritten by: Shane Hill
-// Date: 21/08/2001
-// Email: Shane.Hill@dsto.defence.gov.au
-// Reason: Remove dependancy on MFC. Code should compile on any
-// platform.
-//////////////////////////////////////////////////////////////////////
-
-/*
- !! MODIFIED BY FAKETRUTH !!
-*/
-
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-// C++ Includes
-#include <iostream>
-#include <fstream>
-#include <sstream>
-
-using namespace std;
-
-// C Includes
-#include <ctype.h>
-
-// Local Includes
-#include "iniFile.h"
-
-#if defined(WIN32)
-#define iniEOL endl
-#else
-#define iniEOL '\r' << endl
-#endif
-
-#ifndef _WIN32
-#define sscanf_s(buffer, stringbuffer, ...) (sscanf(buffer, stringbuffer, __VA_ARGS__))
-#endif
-
-
-
-
-
-cIniFile::cIniFile( const string iniPath)
-{
- Path( iniPath);
- caseInsensitive = true;
-}
-
-bool cIniFile::ReadFile()
-{
- // Normally you would use ifstream, but the SGI CC compiler has
- // a few bugs with ifstream. So ... fstream used.
- fstream f;
- string line;
- string keyname, valuename, value;
- string::size_type pLeft, pRight;
-
- f.open( path.c_str(), ios::in);
- if ( f.fail())
- return false;
-
- while( getline( f, line)) {
- // To be compatible with Win32, check for existence of '\r'.
- // Win32 files have the '\r' and Unix files don't at the end of a line.
- // Note that the '\r' will be written to INI files from
- // Unix so that the created INI file can be read under Win32
- // without change.
- unsigned int lineLength = line.length();
- if(lineLength == 0) continue;
- if ( line[lineLength - 1] == '\r')
- line = line.substr( 0, lineLength - 1);
-
- if ( line.length()) {
- // Check that the user hasn't opened a binary file by checking the first
- // character of each line!
- if ( !isprint( line[0])) {
- printf( "Failing on char %d\n", line[0]);
- f.close();
- return false;
- }
- if (( pLeft = line.find_first_of(";#[=")) != string::npos) {
- switch ( line[pLeft]) {
- case '[':
- if ((pRight = line.find_last_of("]")) != string::npos &&
- pRight > pLeft) {
- keyname = line.substr( pLeft + 1, pRight - pLeft - 1);
- AddKeyName( keyname);
- }
- break;
-
- case '=':
- valuename = line.substr( 0, pLeft);
- value = line.substr( pLeft + 1);
- SetValue( keyname, valuename, value);
- break;
-
- case ';':
- case '#':
- if ( !names.size())
- HeaderComment( line.substr( pLeft + 1));
- else
- KeyComment( keyname, line.substr( pLeft + 1));
- break;
- }
- }
- }
- }
-
- f.close();
- if ( names.size())
- return true;
- return false;
-}
-
-
-
-
-
-bool cIniFile::WriteFile()
-{
- unsigned commentID, keyID, valueID;
- // Normally you would use ofstream, but the SGI CC compiler has
- // a few bugs with ofstream. So ... fstream used.
- fstream f;
-
- f.open( path.c_str(), ios::out);
- if ( f.fail())
- return false;
-
- // Write header comments.
- for ( commentID = 0; commentID < comments.size(); ++commentID)
- f << ';' << comments[commentID] << iniEOL;
- if ( comments.size())
- f << iniEOL;
-
- // Write keys and values.
- for ( keyID = 0; keyID < keys.size(); ++keyID) {
- f << '[' << names[keyID] << ']' << iniEOL;
- // Comments.
- for ( commentID = 0; commentID < keys[keyID].comments.size(); ++commentID)
- f << ';' << keys[keyID].comments[commentID] << iniEOL;
- // Values.
- for ( valueID = 0; valueID < keys[keyID].names.size(); ++valueID)
- f << keys[keyID].names[valueID] << '=' << keys[keyID].values[valueID] << iniEOL;
- f << iniEOL;
- }
- f.close();
-
- return true;
-}
-
-
-
-
-
-long cIniFile::FindKey( const string & keyname) const
-{
- for ( unsigned keyID = 0; keyID < names.size(); ++keyID)
- if ( CheckCase( names[keyID]) == CheckCase( keyname))
- return long(keyID);
- return noID;
-}
-
-
-
-
-
-long cIniFile::FindValue( unsigned const keyID, const string & valuename) const
-{
- if ( !keys.size() || keyID >= keys.size())
- return noID;
-
- for ( unsigned valueID = 0; valueID < keys[keyID].names.size(); ++valueID)
- if ( CheckCase( keys[keyID].names[valueID]) == CheckCase( valuename))
- return long(valueID);
- return noID;
-}
-
-
-
-
-
-unsigned cIniFile::AddKeyName( const string & keyname)
-{
- names.resize( names.size() + 1, keyname);
- keys.resize( keys.size() + 1);
- return names.size() - 1;
-}
-
-
-
-
-
-string cIniFile::KeyName( unsigned const keyID) const
-{
- if ( keyID < names.size())
- return names[keyID];
- else
- return "";
-}
-
-
-
-
-
-unsigned cIniFile::NumValues( unsigned const keyID)
-{
- if ( keyID < keys.size())
- return keys[keyID].names.size();
- return 0;
-}
-
-
-
-
-
-unsigned cIniFile::NumValues( const string & keyname)
-{
- long keyID = FindKey( keyname);
- if ( keyID == noID)
- return 0;
- return keys[keyID].names.size();
-}
-
-
-
-
-
-string cIniFile::ValueName( unsigned const keyID, unsigned const valueID) const
-{
- if ( keyID < keys.size() && valueID < keys[keyID].names.size())
- return keys[keyID].names[valueID];
- return "";
-}
-
-
-
-
-
-string cIniFile::ValueName( const string & keyname, unsigned const valueID) const
-{
- long keyID = FindKey( keyname);
- if ( keyID == noID)
- return "";
- return ValueName( keyID, valueID);
-}
-
-
-
-
-
-bool cIniFile::SetValue( unsigned const keyID, unsigned const valueID, const string & value)
-{
- if ( keyID < keys.size() && valueID < keys[keyID].names.size())
- keys[keyID].values[valueID] = value;
-
- return false;
-}
-
-
-
-
-
-bool cIniFile::SetValue( const string & keyname, const string & valuename, const string & value, bool const create)
-{
- long keyID = FindKey( keyname);
- if ( keyID == noID) {
- if ( create)
- keyID = long( AddKeyName( keyname));
- else
- return false;
- }
-
- long valueID = FindValue( unsigned(keyID), valuename);
- if ( valueID == noID) {
- if ( !create)
- return false;
- keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename);
- keys[keyID].values.resize( keys[keyID].values.size() + 1, value);
- } else
- {
- if(!create)
- keys[keyID].values[valueID] = value;
- else
- {
- keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename);
- keys[keyID].values.resize( keys[keyID].values.size() + 1, value);
- }
- }
-
- return true;
-}
-
-
-
-
-
-bool cIniFile::SetValueI( const string & keyname, const string & valuename, int const value, bool const create)
-{
- AString Data;
- Printf(Data, "%d", value);
- return SetValue( keyname, valuename, Data, create);
-}
-
-
-
-
-
-bool cIniFile::SetValueF( const string & keyname, const string & valuename, double const value, bool const create)
-{
- AString Data;
- Printf(Data, "%f", value);
- return SetValue( keyname, valuename, Data, create);
-}
-
-
-
-
-
-bool cIniFile::SetValueV( const string & keyname, const string & valuename, char *format, ...)
-{
- va_list args;
-
- va_start( args, format);
-
- AString Data;
- AppendVPrintf(Data, format, args);
- va_end( args);
- return SetValue( keyname, valuename, Data);
-}
-
-
-
-
-
-string cIniFile::GetValue( unsigned const keyID, unsigned const valueID, const string & defValue) const
-{
- if ( keyID < keys.size() && valueID < keys[keyID].names.size())
- return keys[keyID].values[valueID];
- return defValue;
-}
-
-
-
-
-
-string cIniFile::GetValue( const string & keyname, const string & valuename, const string & defValue) const
-{
- long keyID = FindKey( keyname);
- if ( keyID == noID)
- return defValue;
-
- long valueID = FindValue( unsigned(keyID), valuename);
- if ( valueID == noID)
- return defValue;
-
- return keys[keyID].values[valueID];
-}
-
-
-
-
-
-int cIniFile::GetValueI(const string & keyname, const string & valuename, int const defValue) const
-{
- AString Data;
- Printf(Data, "%d", defValue);
- return atoi( GetValue( keyname, valuename, Data).c_str());
-}
-
-
-
-
-
-double cIniFile::GetValueF(const string & keyname, const string & valuename, double const defValue) const
-{
- AString Data;
- Printf(Data, "%f", defValue);
- return atof( GetValue( keyname, valuename, Data).c_str());
-}
-
-
-
-
-
-AString cIniFile::GetValueSet(const AString & keyname, const AString & valuename, const AString & defValue)
-{
- long keyID = FindKey( keyname);
- if ( keyID == noID)
- {
- SetValue(keyname, valuename, defValue);
- return defValue;
- }
-
- long valueID = FindValue( unsigned(keyID), valuename);
- if ( valueID == noID)
- {
- SetValue(keyname, valuename, defValue);
- return defValue;
- }
-
- return keys[keyID].values[valueID];
-}
-
-
-
-
-
-double cIniFile::GetValueSetF(const AString & keyname, const AString & valuename, const double defValue)
-{
- AString Data;
- Printf(Data, "%f", defValue);
- return atof(GetValueSet(keyname, valuename, Data).c_str());
-}
-
-
-
-
-
-int cIniFile::GetValueSetI(const AString & keyname, const AString & valuename, const int defValue)
-{
- AString Data;
- Printf(Data, "%d", defValue);
- return atoi(GetValueSet(keyname, valuename, Data).c_str());
-}
-
-
-
-
-
-bool cIniFile::DeleteValueByID( const unsigned keyID, const unsigned valueID )
-{
- if ( keyID < keys.size() && valueID < keys[keyID].names.size())
- {
- // This looks strange, but is neccessary.
- vector<string>::iterator npos = keys[keyID].names.begin() + valueID;
- vector<string>::iterator vpos = keys[keyID].values.begin() + valueID;
- keys[keyID].names.erase( npos, npos + 1);
- keys[keyID].values.erase( vpos, vpos + 1);
- return true;
- }
- return false;
-}
-
-bool cIniFile::DeleteValue( const string & keyname, const string & valuename)
-{
- long keyID = FindKey( keyname);
- if ( keyID == noID)
- return false;
-
- long valueID = FindValue( unsigned(keyID), valuename);
- if ( valueID == noID)
- return false;
-
- return DeleteValueByID( keyID, valueID );
-}
-
-bool cIniFile::DeleteKey( const string & keyname)
-{
- long keyID = FindKey( keyname);
- if ( keyID == noID)
- return false;
-
- // Now hopefully this destroys the vector lists within keys.
- // Looking at <vector> source, this should be the case using the destructor.
- // If not, I may have to do it explicitly. Memory leak check should tell.
- // memleak_test.cpp shows that the following not required.
- //keys[keyID].names.clear();
- //keys[keyID].values.clear();
-
- vector<string>::iterator npos = names.begin() + keyID;
- vector<key>::iterator kpos = keys.begin() + keyID;
- names.erase( npos, npos + 1);
- keys.erase( kpos, kpos + 1);
-
- return true;
-}
-
-void cIniFile::Erase()
-{
- // This loop not needed. The vector<> destructor seems to do
- // all the work itself. memleak_test.cpp shows this.
- //for ( unsigned i = 0; i < keys.size(); ++i) {
- // keys[i].names.clear();
- // keys[i].values.clear();
- //}
- names.clear();
- keys.clear();
- comments.clear();
-}
-
-void cIniFile::HeaderComment( const string & comment)
-{
- comments.resize( comments.size() + 1, comment);
-}
-
-string cIniFile::HeaderComment( unsigned const commentID) const
-{
- if ( commentID < comments.size())
- return comments[commentID];
- return "";
-}
-
-bool cIniFile::DeleteHeaderComment( unsigned commentID)
-{
- if ( commentID < comments.size()) {
- vector<string>::iterator cpos = comments.begin() + commentID;
- comments.erase( cpos, cpos + 1);
- return true;
- }
- return false;
-}
-
-unsigned cIniFile::NumKeyComments( unsigned const keyID) const
-{
- if ( keyID < keys.size())
- return keys[keyID].comments.size();
- return 0;
-}
-
-unsigned cIniFile::NumKeyComments( const string & keyname) const
-{
- long keyID = FindKey( keyname);
- if ( keyID == noID)
- return 0;
- return keys[keyID].comments.size();
-}
-
-bool cIniFile::KeyComment( unsigned const keyID, const string & comment)
-{
- if ( keyID < keys.size()) {
- keys[keyID].comments.resize( keys[keyID].comments.size() + 1, comment);
- return true;
- }
- return false;
-}
-
-bool cIniFile::KeyComment( const string & keyname, const string & comment)
-{
- long keyID = FindKey( keyname);
- if ( keyID == noID)
- return false;
- return KeyComment( unsigned(keyID), comment);
-}
-
-string cIniFile::KeyComment( unsigned const keyID, unsigned const commentID) const
-{
- if ( keyID < keys.size() && commentID < keys[keyID].comments.size())
- return keys[keyID].comments[commentID];
- return "";
-}
-
-string cIniFile::KeyComment( const string & keyname, unsigned const commentID) const
-{
- long keyID = FindKey( keyname);
- if ( keyID == noID)
- return "";
- return KeyComment( unsigned(keyID), commentID);
-}
-
-bool cIniFile::DeleteKeyComment( unsigned const keyID, unsigned const commentID)
-{
- if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) {
- vector<string>::iterator cpos = keys[keyID].comments.begin() + commentID;
- keys[keyID].comments.erase( cpos, cpos + 1);
- return true;
- }
- return false;
-}
-
-bool cIniFile::DeleteKeyComment( const string & keyname, unsigned const commentID)
-{
- long keyID = FindKey( keyname);
- if ( keyID == noID)
- return false;
- return DeleteKeyComment( unsigned(keyID), commentID);
-}
-
-bool cIniFile::DeleteKeyComments( unsigned const keyID)
-{
- if ( keyID < keys.size()) {
- keys[keyID].comments.clear();
- return true;
- }
- return false;
-}
-
-bool cIniFile::DeleteKeyComments( const string & keyname)
-{
- long keyID = FindKey( keyname);
- if ( keyID == noID)
- return false;
- return DeleteKeyComments( unsigned(keyID));
-}
-
-string cIniFile::CheckCase( string s) const
-{
- if ( caseInsensitive)
- for ( string::size_type i = 0; i < s.length(); ++i)
- s[i] = (char)tolower(s[i]);
- return s;
-}
+// IniFile.cpp: Implementation of the CIniFile class. +// Written by: Adam Clauss +// Email: cabadam@houston.rr.com +// You may use this class/code as you wish in your programs. Feel free to distribute it, and +// email suggested changes to me. +// +// Rewritten by: Shane Hill +// Date: 21/08/2001 +// Email: Shane.Hill@dsto.defence.gov.au +// Reason: Remove dependancy on MFC. Code should compile on any +// platform. +////////////////////////////////////////////////////////////////////// + +/* + !! MODIFIED BY FAKETRUTH !! +*/ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +// C++ Includes +#include <iostream> +#include <fstream> +#include <sstream> + +using namespace std; + +// C Includes +#include <ctype.h> + +// Local Includes +#include "iniFile.h" + +#if defined(WIN32) +#define iniEOL endl +#else +#define iniEOL '\r' << endl +#endif + +#ifndef _WIN32 +#define sscanf_s(buffer, stringbuffer, ...) (sscanf(buffer, stringbuffer, __VA_ARGS__)) +#endif + + + + + +cIniFile::cIniFile( const string iniPath) +{ + Path( iniPath); + caseInsensitive = true; +} + +bool cIniFile::ReadFile() +{ + // Normally you would use ifstream, but the SGI CC compiler has + // a few bugs with ifstream. So ... fstream used. + fstream f; + string line; + string keyname, valuename, value; + string::size_type pLeft, pRight; + + f.open( path.c_str(), ios::in); + if ( f.fail()) + return false; + + while( getline( f, line)) { + // To be compatible with Win32, check for existence of '\r'. + // Win32 files have the '\r' and Unix files don't at the end of a line. + // Note that the '\r' will be written to INI files from + // Unix so that the created INI file can be read under Win32 + // without change. + unsigned int lineLength = line.length(); + if(lineLength == 0) continue; + if ( line[lineLength - 1] == '\r') + line = line.substr( 0, lineLength - 1); + + if ( line.length()) { + // Check that the user hasn't opened a binary file by checking the first + // character of each line! + if ( !isprint( line[0])) { + printf( "Failing on char %d\n", line[0]); + f.close(); + return false; + } + if (( pLeft = line.find_first_of(";#[=")) != string::npos) { + switch ( line[pLeft]) { + case '[': + if ((pRight = line.find_last_of("]")) != string::npos && + pRight > pLeft) { + keyname = line.substr( pLeft + 1, pRight - pLeft - 1); + AddKeyName( keyname); + } + break; + + case '=': + valuename = line.substr( 0, pLeft); + value = line.substr( pLeft + 1); + SetValue( keyname, valuename, value); + break; + + case ';': + case '#': + if ( !names.size()) + HeaderComment( line.substr( pLeft + 1)); + else + KeyComment( keyname, line.substr( pLeft + 1)); + break; + } + } + } + } + + f.close(); + if ( names.size()) + return true; + return false; +} + + + + + +bool cIniFile::WriteFile() +{ + unsigned commentID, keyID, valueID; + // Normally you would use ofstream, but the SGI CC compiler has + // a few bugs with ofstream. So ... fstream used. + fstream f; + + f.open( path.c_str(), ios::out); + if ( f.fail()) + return false; + + // Write header comments. + for ( commentID = 0; commentID < comments.size(); ++commentID) + f << ';' << comments[commentID] << iniEOL; + if ( comments.size()) + f << iniEOL; + + // Write keys and values. + for ( keyID = 0; keyID < keys.size(); ++keyID) { + f << '[' << names[keyID] << ']' << iniEOL; + // Comments. + for ( commentID = 0; commentID < keys[keyID].comments.size(); ++commentID) + f << ';' << keys[keyID].comments[commentID] << iniEOL; + // Values. + for ( valueID = 0; valueID < keys[keyID].names.size(); ++valueID) + f << keys[keyID].names[valueID] << '=' << keys[keyID].values[valueID] << iniEOL; + f << iniEOL; + } + f.close(); + + return true; +} + + + + + +long cIniFile::FindKey( const string & keyname) const +{ + for ( unsigned keyID = 0; keyID < names.size(); ++keyID) + if ( CheckCase( names[keyID]) == CheckCase( keyname)) + return long(keyID); + return noID; +} + + + + + +long cIniFile::FindValue( unsigned const keyID, const string & valuename) const +{ + if ( !keys.size() || keyID >= keys.size()) + return noID; + + for ( unsigned valueID = 0; valueID < keys[keyID].names.size(); ++valueID) + if ( CheckCase( keys[keyID].names[valueID]) == CheckCase( valuename)) + return long(valueID); + return noID; +} + + + + + +unsigned cIniFile::AddKeyName( const string & keyname) +{ + names.resize( names.size() + 1, keyname); + keys.resize( keys.size() + 1); + return names.size() - 1; +} + + + + + +string cIniFile::KeyName( unsigned const keyID) const +{ + if ( keyID < names.size()) + return names[keyID]; + else + return ""; +} + + + + + +unsigned cIniFile::NumValues( unsigned const keyID) +{ + if ( keyID < keys.size()) + return keys[keyID].names.size(); + return 0; +} + + + + + +unsigned cIniFile::NumValues( const string & keyname) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return 0; + return keys[keyID].names.size(); +} + + + + + +string cIniFile::ValueName( unsigned const keyID, unsigned const valueID) const +{ + if ( keyID < keys.size() && valueID < keys[keyID].names.size()) + return keys[keyID].names[valueID]; + return ""; +} + + + + + +string cIniFile::ValueName( const string & keyname, unsigned const valueID) const +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return ""; + return ValueName( keyID, valueID); +} + + + + + +bool cIniFile::SetValue( unsigned const keyID, unsigned const valueID, const string & value) +{ + if ( keyID < keys.size() && valueID < keys[keyID].names.size()) + keys[keyID].values[valueID] = value; + + return false; +} + + + + + +bool cIniFile::SetValue( const string & keyname, const string & valuename, const string & value, bool const create) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) { + if ( create) + keyID = long( AddKeyName( keyname)); + else + return false; + } + + long valueID = FindValue( unsigned(keyID), valuename); + if ( valueID == noID) { + if ( !create) + return false; + keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename); + keys[keyID].values.resize( keys[keyID].values.size() + 1, value); + } else + { + if(!create) + keys[keyID].values[valueID] = value; + else + { + keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename); + keys[keyID].values.resize( keys[keyID].values.size() + 1, value); + } + } + + return true; +} + + + + + +bool cIniFile::SetValueI( const string & keyname, const string & valuename, int const value, bool const create) +{ + AString Data; + Printf(Data, "%d", value); + return SetValue( keyname, valuename, Data, create); +} + + + + + +bool cIniFile::SetValueF( const string & keyname, const string & valuename, double const value, bool const create) +{ + AString Data; + Printf(Data, "%f", value); + return SetValue( keyname, valuename, Data, create); +} + + + + + +bool cIniFile::SetValueV( const string & keyname, const string & valuename, char *format, ...) +{ + va_list args; + + va_start( args, format); + + AString Data; + AppendVPrintf(Data, format, args); + va_end( args); + return SetValue( keyname, valuename, Data); +} + + + + + +string cIniFile::GetValue( unsigned const keyID, unsigned const valueID, const string & defValue) const +{ + if ( keyID < keys.size() && valueID < keys[keyID].names.size()) + return keys[keyID].values[valueID]; + return defValue; +} + + + + + +string cIniFile::GetValue( const string & keyname, const string & valuename, const string & defValue) const +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return defValue; + + long valueID = FindValue( unsigned(keyID), valuename); + if ( valueID == noID) + return defValue; + + return keys[keyID].values[valueID]; +} + + + + + +int cIniFile::GetValueI(const string & keyname, const string & valuename, int const defValue) const +{ + AString Data; + Printf(Data, "%d", defValue); + return atoi( GetValue( keyname, valuename, Data).c_str()); +} + + + + + +double cIniFile::GetValueF(const string & keyname, const string & valuename, double const defValue) const +{ + AString Data; + Printf(Data, "%f", defValue); + return atof( GetValue( keyname, valuename, Data).c_str()); +} + + + + + +AString cIniFile::GetValueSet(const AString & keyname, const AString & valuename, const AString & defValue) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + { + SetValue(keyname, valuename, defValue); + return defValue; + } + + long valueID = FindValue( unsigned(keyID), valuename); + if ( valueID == noID) + { + SetValue(keyname, valuename, defValue); + return defValue; + } + + return keys[keyID].values[valueID]; +} + + + + + +double cIniFile::GetValueSetF(const AString & keyname, const AString & valuename, const double defValue) +{ + AString Data; + Printf(Data, "%f", defValue); + return atof(GetValueSet(keyname, valuename, Data).c_str()); +} + + + + + +int cIniFile::GetValueSetI(const AString & keyname, const AString & valuename, const int defValue) +{ + AString Data; + Printf(Data, "%d", defValue); + return atoi(GetValueSet(keyname, valuename, Data).c_str()); +} + + + + + +bool cIniFile::DeleteValueByID( const unsigned keyID, const unsigned valueID ) +{ + if ( keyID < keys.size() && valueID < keys[keyID].names.size()) + { + // This looks strange, but is neccessary. + vector<string>::iterator npos = keys[keyID].names.begin() + valueID; + vector<string>::iterator vpos = keys[keyID].values.begin() + valueID; + keys[keyID].names.erase( npos, npos + 1); + keys[keyID].values.erase( vpos, vpos + 1); + return true; + } + return false; +} + +bool cIniFile::DeleteValue( const string & keyname, const string & valuename) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + + long valueID = FindValue( unsigned(keyID), valuename); + if ( valueID == noID) + return false; + + return DeleteValueByID( keyID, valueID ); +} + +bool cIniFile::DeleteKey( const string & keyname) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + + // Now hopefully this destroys the vector lists within keys. + // Looking at <vector> source, this should be the case using the destructor. + // If not, I may have to do it explicitly. Memory leak check should tell. + // memleak_test.cpp shows that the following not required. + //keys[keyID].names.clear(); + //keys[keyID].values.clear(); + + vector<string>::iterator npos = names.begin() + keyID; + vector<key>::iterator kpos = keys.begin() + keyID; + names.erase( npos, npos + 1); + keys.erase( kpos, kpos + 1); + + return true; +} + +void cIniFile::Erase() +{ + // This loop not needed. The vector<> destructor seems to do + // all the work itself. memleak_test.cpp shows this. + //for ( unsigned i = 0; i < keys.size(); ++i) { + // keys[i].names.clear(); + // keys[i].values.clear(); + //} + names.clear(); + keys.clear(); + comments.clear(); +} + +void cIniFile::HeaderComment( const string & comment) +{ + comments.resize( comments.size() + 1, comment); +} + +string cIniFile::HeaderComment( unsigned const commentID) const +{ + if ( commentID < comments.size()) + return comments[commentID]; + return ""; +} + +bool cIniFile::DeleteHeaderComment( unsigned commentID) +{ + if ( commentID < comments.size()) { + vector<string>::iterator cpos = comments.begin() + commentID; + comments.erase( cpos, cpos + 1); + return true; + } + return false; +} + +unsigned cIniFile::NumKeyComments( unsigned const keyID) const +{ + if ( keyID < keys.size()) + return keys[keyID].comments.size(); + return 0; +} + +unsigned cIniFile::NumKeyComments( const string & keyname) const +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return 0; + return keys[keyID].comments.size(); +} + +bool cIniFile::KeyComment( unsigned const keyID, const string & comment) +{ + if ( keyID < keys.size()) { + keys[keyID].comments.resize( keys[keyID].comments.size() + 1, comment); + return true; + } + return false; +} + +bool cIniFile::KeyComment( const string & keyname, const string & comment) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + return KeyComment( unsigned(keyID), comment); +} + +string cIniFile::KeyComment( unsigned const keyID, unsigned const commentID) const +{ + if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) + return keys[keyID].comments[commentID]; + return ""; +} + +string cIniFile::KeyComment( const string & keyname, unsigned const commentID) const +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return ""; + return KeyComment( unsigned(keyID), commentID); +} + +bool cIniFile::DeleteKeyComment( unsigned const keyID, unsigned const commentID) +{ + if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) { + vector<string>::iterator cpos = keys[keyID].comments.begin() + commentID; + keys[keyID].comments.erase( cpos, cpos + 1); + return true; + } + return false; +} + +bool cIniFile::DeleteKeyComment( const string & keyname, unsigned const commentID) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + return DeleteKeyComment( unsigned(keyID), commentID); +} + +bool cIniFile::DeleteKeyComments( unsigned const keyID) +{ + if ( keyID < keys.size()) { + keys[keyID].comments.clear(); + return true; + } + return false; +} + +bool cIniFile::DeleteKeyComments( const string & keyname) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + return DeleteKeyComments( unsigned(keyID)); +} + +string cIniFile::CheckCase( string s) const +{ + if ( caseInsensitive) + for ( string::size_type i = 0; i < s.length(); ++i) + s[i] = (char)tolower(s[i]); + return s; +} diff --git a/iniFile/iniFile.h b/iniFile/iniFile.h index 13fa15e59..58a5a52b6 100644 --- a/iniFile/iniFile.h +++ b/iniFile/iniFile.h @@ -1,186 +1,186 @@ -// IniFile.cpp: Implementation of the CIniFile class.
-// Written by: Adam Clauss
-// Email: cabadam@tamu.edu
-// You may use this class/code as you wish in your programs. Feel free to distribute it, and
-// email suggested changes to me.
-//
-// Rewritten by: Shane Hill
-// Date: 21/08/2001
-// Email: Shane.Hill@dsto.defence.gov.au
-// Reason: Remove dependancy on MFC. Code should compile on any
-// platform. Tested on Windows/Linux/Irix
-//////////////////////////////////////////////////////////////////////
-
-/*
-!! MODIFIED BY FAKETRUTH and madmaxoft!!
-*/
-
-#ifndef CIniFile_H
-#define CIniFile_H
-
-
-
-
-
-#define MAX_KEYNAME 128
-#define MAX_VALUENAME 128
-#define MAX_VALUEDATA 2048
-
-
-
-
-
-class cIniFile //tolua_export
-{ //tolua_export
-private:
- bool caseInsensitive;
- std::string path;
- struct key {
- std::vector<std::string> names;
- std::vector<std::string> values;
- std::vector<std::string> comments;
- };
- std::vector<key> keys;
- std::vector<std::string> names;
- std::vector<std::string> comments;
- std::string CheckCase( std::string s) const;
-
-public:
- enum errors{ noID = -1}; //tolua_export
- cIniFile( const std::string iniPath = ""); //tolua_export
- virtual ~cIniFile() {}
-
- // Sets whether or not keynames and valuenames should be case sensitive.
- // The default is case insensitive.
- void CaseSensitive() {caseInsensitive = false;} //tolua_export
- void CaseInsensitive() {caseInsensitive = true;} //tolua_export
-
- // Sets path of ini file to read and write from.
- void Path(const std::string & newPath) {path = newPath;} //tolua_export
- std::string Path() const {return path;} //tolua_export
- void SetPath(const std::string & newPath) {Path( newPath);} //tolua_export
-
- // Reads ini file specified using path.
- // Returns true if successful, false otherwise.
- bool ReadFile(); //tolua_export
-
- // Writes data stored in class to ini file.
- bool WriteFile(); //tolua_export
-
- // Deletes all stored ini data.
- void Erase(); //tolua_export
- void Clear() {Erase();} //tolua_export
- void Reset() {Erase();} //tolua_export
-
- // Returns index of specified key, or noID if not found.
- long FindKey( const std::string & keyname) const; //tolua_export
-
- // Returns index of specified value, in the specified key, or noID if not found.
- long FindValue( const unsigned keyID, const std::string & valuename) const; //tolua_export
-
- // Returns number of keys currently in the ini.
- unsigned NumKeys() const {return names.size();} //tolua_export
- unsigned GetNumKeys() const {return NumKeys();} //tolua_export
-
- // Add a key name.
- unsigned AddKeyName( const std::string & keyname); //tolua_export
-
- // Returns key names by index.
- std::string KeyName( const unsigned keyID) const; //tolua_export
- std::string GetKeyName( const unsigned keyID) const {return KeyName(keyID);} //tolua_export
-
- // Returns number of values stored for specified key.
- unsigned NumValues( const std::string & keyname); //tolua_export
- unsigned GetNumValues( const std::string & keyname) {return NumValues( keyname);} //tolua_export
- unsigned NumValues( const unsigned keyID); //tolua_export
- unsigned GetNumValues( const unsigned keyID) {return NumValues( keyID);} //tolua_export
-
- // Returns value name by index for a given keyname or keyID.
- std::string ValueName( const std::string & keyname, const unsigned valueID) const; //tolua_export
- std::string GetValueName( const std::string & keyname, const unsigned valueID) const { //tolua_export
- return ValueName( keyname, valueID);
- } //tolua_export
- std::string ValueName( const unsigned keyID, const unsigned valueID) const; //tolua_export
- std::string GetValueName( const unsigned keyID, const unsigned valueID) const { //tolua_export
- return ValueName( keyID, valueID);
- } //tolua_export
-
- // Gets value of [keyname] valuename =.
- // Overloaded to return string, int, and double.
- // Returns defValue if key/value not found.
- AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const; // tolua_export
- AString GetValue (const unsigned keyID, const unsigned valueID, const AString & defValue = "") const; // tolua_export
- double GetValueF(const AString & keyname, const AString & valuename, const double defValue = 0) const; // tolua_export
- int GetValueI(const AString & keyname, const AString & valuename, const int defValue = 0) const; // tolua_export
- bool GetValueB(const AString & keyname, const AString & valuename, const bool defValue = false) const { // tolua_export
- return ( GetValueI( keyname, valuename, int( defValue)) > 0);
- } // tolua_export
-
- // Gets the value; if not found, write the default to the INI file
- AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = ""); // tolua_export
- double GetValueSetF(const AString & keyname, const AString & valuename, const double defValue = 0.0); // tolua_export
- int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0); // tolua_export
- bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) { // tolua_export
- return (GetValueSetI(keyname, valuename, defValue ? 1 : 0) > 0);
- } // tolua_export
-
- // Sets value of [keyname] valuename =.
- // Specify the optional paramter as false (0) if you do not want it to create
- // the key if it doesn't exist. Returns true if data entered, false otherwise.
- // Overloaded to accept string, int, and double.
- bool SetValue( const unsigned keyID, const unsigned valueID, const std::string & value); //tolua_export
- bool SetValue( const std::string & keyname, const std::string & valuename, const std::string & value, const bool create = true); //tolua_export
- bool SetValueI( const std::string & keyname, const std::string & valuename, const int value, const bool create = true); //tolua_export
- bool SetValueB( const std::string & keyname, const std::string & valuename, const bool value, const bool create = true) { //tolua_export
- return SetValueI( keyname, valuename, int(value), create);
- } //tolua_export
- bool SetValueF( const std::string & keyname, const std::string & valuename, const double value, const bool create = true); //tolua_export
- bool SetValueV( const std::string & keyname, const std::string & valuename, char *format, ...);
-
- // Deletes specified value.
- // Returns true if value existed and deleted, false otherwise.
- bool DeleteValueByID( const unsigned keyID, const unsigned valueID ); //tolua_export
- bool DeleteValue( const std::string & keyname, const std::string & valuename); //tolua_export
-
- // Deletes specified key and all values contained within.
- // Returns true if key existed and deleted, false otherwise.
- bool DeleteKey(const std::string & keyname); //tolua_export
-
- // Header comment functions.
- // Header comments are those comments before the first key.
- //
- // Number of header comments.
- unsigned NumHeaderComments() {return comments.size();} //tolua_export
- // Add a header comment.
- void HeaderComment( const std::string & comment); //tolua_export
- // Return a header comment.
- std::string HeaderComment( const unsigned commentID) const; //tolua_export
- // Delete a header comment.
- bool DeleteHeaderComment( unsigned commentID); //tolua_export
- // Delete all header comments.
- void DeleteHeaderComments() {comments.clear();} //tolua_export
-
- // Key comment functions.
- // Key comments are those comments within a key. Any comments
- // defined within value names will be added to this list. Therefore,
- // these comments will be moved to the top of the key definition when
- // the CIniFile::WriteFile() is called.
- //
- // Number of key comments.
- unsigned NumKeyComments( const unsigned keyID) const; //tolua_export
- unsigned NumKeyComments( const std::string & keyname) const; //tolua_export
- // Add a key comment.
- bool KeyComment( const unsigned keyID, const std::string & comment); //tolua_export
- bool KeyComment( const std::string & keyname, const std::string & comment); //tolua_export
- // Return a key comment.
- std::string KeyComment( const unsigned keyID, const unsigned commentID) const; //tolua_export
- std::string KeyComment( const std::string & keyname, const unsigned commentID) const; //tolua_export
- // Delete a key comment.
- bool DeleteKeyComment( const unsigned keyID, const unsigned commentID); //tolua_export
- bool DeleteKeyComment( const std::string & keyname, const unsigned commentID); //tolua_export
- // Delete all comments for a key.
- bool DeleteKeyComments( const unsigned keyID); //tolua_export
- bool DeleteKeyComments( const std::string & keyname); //tolua_export
-}; //tolua_export
-
-#endif
+// IniFile.cpp: Implementation of the CIniFile class. +// Written by: Adam Clauss +// Email: cabadam@tamu.edu +// You may use this class/code as you wish in your programs. Feel free to distribute it, and +// email suggested changes to me. +// +// Rewritten by: Shane Hill +// Date: 21/08/2001 +// Email: Shane.Hill@dsto.defence.gov.au +// Reason: Remove dependancy on MFC. Code should compile on any +// platform. Tested on Windows/Linux/Irix +////////////////////////////////////////////////////////////////////// + +/* +!! MODIFIED BY FAKETRUTH and madmaxoft!! +*/ + +#ifndef CIniFile_H +#define CIniFile_H + + + + + +#define MAX_KEYNAME 128 +#define MAX_VALUENAME 128 +#define MAX_VALUEDATA 2048 + + + + + +class cIniFile //tolua_export +{ //tolua_export +private: + bool caseInsensitive; + std::string path; + struct key { + std::vector<std::string> names; + std::vector<std::string> values; + std::vector<std::string> comments; + }; + std::vector<key> keys; + std::vector<std::string> names; + std::vector<std::string> comments; + std::string CheckCase( std::string s) const; + +public: + enum errors{ noID = -1}; //tolua_export + cIniFile( const std::string iniPath = ""); //tolua_export + virtual ~cIniFile() {} + + // Sets whether or not keynames and valuenames should be case sensitive. + // The default is case insensitive. + void CaseSensitive() {caseInsensitive = false;} //tolua_export + void CaseInsensitive() {caseInsensitive = true;} //tolua_export + + // Sets path of ini file to read and write from. + void Path(const std::string & newPath) {path = newPath;} //tolua_export + std::string Path() const {return path;} //tolua_export + void SetPath(const std::string & newPath) {Path( newPath);} //tolua_export + + // Reads ini file specified using path. + // Returns true if successful, false otherwise. + bool ReadFile(); //tolua_export + + // Writes data stored in class to ini file. + bool WriteFile(); //tolua_export + + // Deletes all stored ini data. + void Erase(); //tolua_export + void Clear() {Erase();} //tolua_export + void Reset() {Erase();} //tolua_export + + // Returns index of specified key, or noID if not found. + long FindKey( const std::string & keyname) const; //tolua_export + + // Returns index of specified value, in the specified key, or noID if not found. + long FindValue( const unsigned keyID, const std::string & valuename) const; //tolua_export + + // Returns number of keys currently in the ini. + unsigned NumKeys() const {return names.size();} //tolua_export + unsigned GetNumKeys() const {return NumKeys();} //tolua_export + + // Add a key name. + unsigned AddKeyName( const std::string & keyname); //tolua_export + + // Returns key names by index. + std::string KeyName( const unsigned keyID) const; //tolua_export + std::string GetKeyName( const unsigned keyID) const {return KeyName(keyID);} //tolua_export + + // Returns number of values stored for specified key. + unsigned NumValues( const std::string & keyname); //tolua_export + unsigned GetNumValues( const std::string & keyname) {return NumValues( keyname);} //tolua_export + unsigned NumValues( const unsigned keyID); //tolua_export + unsigned GetNumValues( const unsigned keyID) {return NumValues( keyID);} //tolua_export + + // Returns value name by index for a given keyname or keyID. + std::string ValueName( const std::string & keyname, const unsigned valueID) const; //tolua_export + std::string GetValueName( const std::string & keyname, const unsigned valueID) const { //tolua_export + return ValueName( keyname, valueID); + } //tolua_export + std::string ValueName( const unsigned keyID, const unsigned valueID) const; //tolua_export + std::string GetValueName( const unsigned keyID, const unsigned valueID) const { //tolua_export + return ValueName( keyID, valueID); + } //tolua_export + + // Gets value of [keyname] valuename =. + // Overloaded to return string, int, and double. + // Returns defValue if key/value not found. + AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const; // tolua_export + AString GetValue (const unsigned keyID, const unsigned valueID, const AString & defValue = "") const; // tolua_export + double GetValueF(const AString & keyname, const AString & valuename, const double defValue = 0) const; // tolua_export + int GetValueI(const AString & keyname, const AString & valuename, const int defValue = 0) const; // tolua_export + bool GetValueB(const AString & keyname, const AString & valuename, const bool defValue = false) const { // tolua_export + return ( GetValueI( keyname, valuename, int( defValue)) > 0); + } // tolua_export + + // Gets the value; if not found, write the default to the INI file + AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = ""); // tolua_export + double GetValueSetF(const AString & keyname, const AString & valuename, const double defValue = 0.0); // tolua_export + int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0); // tolua_export + bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) { // tolua_export + return (GetValueSetI(keyname, valuename, defValue ? 1 : 0) > 0); + } // tolua_export + + // Sets value of [keyname] valuename =. + // Specify the optional paramter as false (0) if you do not want it to create + // the key if it doesn't exist. Returns true if data entered, false otherwise. + // Overloaded to accept string, int, and double. + bool SetValue( const unsigned keyID, const unsigned valueID, const std::string & value); //tolua_export + bool SetValue( const std::string & keyname, const std::string & valuename, const std::string & value, const bool create = true); //tolua_export + bool SetValueI( const std::string & keyname, const std::string & valuename, const int value, const bool create = true); //tolua_export + bool SetValueB( const std::string & keyname, const std::string & valuename, const bool value, const bool create = true) { //tolua_export + return SetValueI( keyname, valuename, int(value), create); + } //tolua_export + bool SetValueF( const std::string & keyname, const std::string & valuename, const double value, const bool create = true); //tolua_export + bool SetValueV( const std::string & keyname, const std::string & valuename, char *format, ...); + + // Deletes specified value. + // Returns true if value existed and deleted, false otherwise. + bool DeleteValueByID( const unsigned keyID, const unsigned valueID ); //tolua_export + bool DeleteValue( const std::string & keyname, const std::string & valuename); //tolua_export + + // Deletes specified key and all values contained within. + // Returns true if key existed and deleted, false otherwise. + bool DeleteKey(const std::string & keyname); //tolua_export + + // Header comment functions. + // Header comments are those comments before the first key. + // + // Number of header comments. + unsigned NumHeaderComments() {return comments.size();} //tolua_export + // Add a header comment. + void HeaderComment( const std::string & comment); //tolua_export + // Return a header comment. + std::string HeaderComment( const unsigned commentID) const; //tolua_export + // Delete a header comment. + bool DeleteHeaderComment( unsigned commentID); //tolua_export + // Delete all header comments. + void DeleteHeaderComments() {comments.clear();} //tolua_export + + // Key comment functions. + // Key comments are those comments within a key. Any comments + // defined within value names will be added to this list. Therefore, + // these comments will be moved to the top of the key definition when + // the CIniFile::WriteFile() is called. + // + // Number of key comments. + unsigned NumKeyComments( const unsigned keyID) const; //tolua_export + unsigned NumKeyComments( const std::string & keyname) const; //tolua_export + // Add a key comment. + bool KeyComment( const unsigned keyID, const std::string & comment); //tolua_export + bool KeyComment( const std::string & keyname, const std::string & comment); //tolua_export + // Return a key comment. + std::string KeyComment( const unsigned keyID, const unsigned commentID) const; //tolua_export + std::string KeyComment( const std::string & keyname, const unsigned commentID) const; //tolua_export + // Delete a key comment. + bool DeleteKeyComment( const unsigned keyID, const unsigned commentID); //tolua_export + bool DeleteKeyComment( const std::string & keyname, const unsigned commentID); //tolua_export + // Delete all comments for a key. + bool DeleteKeyComments( const unsigned keyID); //tolua_export + bool DeleteKeyComments( const std::string & keyname); //tolua_export +}; //tolua_export + +#endif diff --git a/source/Bindings.cpp b/source/Bindings.cpp index a2e7950b4..040ca67a3 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,21337 +1,21337 @@ -/*
-** Lua binding: AllToLua
-** Generated automatically by tolua++-1.0.92 on Thu Jun 14 14:20:17 2012.
-*/
-
-#ifndef __cplusplus
-#include "stdlib.h"
-#endif
-#include "string.h"
-
-#include "tolua++.h"
-
-/* Exported function */
-TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S);
-
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-#include "tolua_base.h"
-#include "cTorch.h"
-#include "cStairs.h"
-#include "cStep.h"
-#include "cLadder.h"
-#include "../iniFile/iniFile.h"
-#include "BlockID.h"
-#include "PacketID.h"
-#include "Defines.h"
-#include "LuaFunctions.h"
-#include "cStringMap.h"
-#include "cChatColor.h"
-#include "cClientHandle.h"
-#include "cEntity.h"
-#include "cPawn.h"
-#include "cPlayer.h"
-#include "cPluginManager.h"
-#include "cPlugin.h"
-#include "cPlugin_NewLua.h"
-#include "cPlugin_Lua.h"
-#include "cServer.h"
-#include "cWorld.h"
-#include "cInventory.h"
-#include "cItem.h"
-#include "cWebAdmin.h"
-#include "cWebPlugin.h"
-#include "cWebPlugin_Lua.h"
-#include "cPickup.h"
-#include "cRoot.h"
-#include "cTCPLink.h"
-#include "Vector3f.h"
-#include "Vector3d.h"
-#include "Vector3i.h"
-#include "Matrix4f.h"
-#include "cCuboid.h"
-#include "cMCLogger.h"
-#include "cTracer.h"
-#include "cGroup.h"
-#include "packets/cPacket_Login.h"
-#include "packets/cPacket_BlockDig.h"
-#include "packets/cPacket_BlockPlace.h"
-#include "cLuaChunk.h"
-#include "CraftingRecipes.h"
-#include "LuaItems.h"
-
-/* function to release collected object via destructor */
-#ifdef __cplusplus
-
-static int tolua_collect_cMCLogger (lua_State* tolua_S)
-{
- cMCLogger* self = (cMCLogger*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-
-static int tolua_collect_cItem (lua_State* tolua_S)
-{
- cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-
-static int tolua_collect_Vector3f (lua_State* tolua_S)
-{
- Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-
-static int tolua_collect_cIniFile (lua_State* tolua_S)
-{
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-
-static int tolua_collect_cPickup (lua_State* tolua_S)
-{
- cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-
-static int tolua_collect_cPacket_BlockDig (lua_State* tolua_S)
-{
- cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-
-static int tolua_collect_cTracer (lua_State* tolua_S)
-{
- cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-
-static int tolua_collect_cPlugin (lua_State* tolua_S)
-{
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-
-static int tolua_collect_cCraftingGrid (lua_State* tolua_S)
-{
- cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-
-static int tolua_collect_cCuboid (lua_State* tolua_S)
-{
- cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-
-static int tolua_collect_cWebPlugin (lua_State* tolua_S)
-{
- cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-
-static int tolua_collect_Vector3i (lua_State* tolua_S)
-{
- Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-
-static int tolua_collect_cEntity (lua_State* tolua_S)
-{
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-
-static int tolua_collect_cTCPLink (lua_State* tolua_S)
-{
- cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-
-static int tolua_collect_Vector3d (lua_State* tolua_S)
-{
- Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0);
- Mtolua_delete(self);
- return 0;
-}
-#endif
-
-
-/* function to register type */
-static void tolua_reg_types (lua_State* tolua_S)
-{
- tolua_usertype(tolua_S,"BLOCKTYPE");
- tolua_usertype(tolua_S,"TakeDamageInfo");
- tolua_usertype(tolua_S,"cLuaItems");
- tolua_usertype(tolua_S,"cLuaChunk");
- tolua_usertype(tolua_S,"cCraftingGrid");
- tolua_usertype(tolua_S,"cCraftingRecipe");
- tolua_usertype(tolua_S,"cPlugin");
- tolua_usertype(tolua_S,"cEntity");
- tolua_usertype(tolua_S,"NIBBLETYPE");
- tolua_usertype(tolua_S,"Lua__cPacket_BlockDig");
- tolua_usertype(tolua_S,"cTCPLink");
- tolua_usertype(tolua_S,"Lua__cTCPLink");
- tolua_usertype(tolua_S,"Json::Value");
- tolua_usertype(tolua_S,"cServer");
- tolua_usertype(tolua_S,"cRoot");
- tolua_usertype(tolua_S,"cMCLogger");
- tolua_usertype(tolua_S,"cGroup");
- tolua_usertype(tolua_S,"cTracer");
- tolua_usertype(tolua_S,"cPlugin::CommandStruct");
- tolua_usertype(tolua_S,"cPickup");
- tolua_usertype(tolua_S,"cItems");
- tolua_usertype(tolua_S,"cPacket_Login");
- tolua_usertype(tolua_S,"cClientHandle");
- tolua_usertype(tolua_S,"cStep");
- tolua_usertype(tolua_S,"cFurnaceRecipe");
- tolua_usertype(tolua_S,"cCuboid");
- tolua_usertype(tolua_S,"cChatColor");
- tolua_usertype(tolua_S,"Vector3i");
- tolua_usertype(tolua_S,"cPacket_PickupSpawn");
- tolua_usertype(tolua_S,"Lua__cWebPlugin");
- tolua_usertype(tolua_S,"Lua__cPawn");
- tolua_usertype(tolua_S,"cStairs");
- tolua_usertype(tolua_S,"cItem");
- tolua_usertype(tolua_S,"Vector3f");
- tolua_usertype(tolua_S,"cPlugin_Lua");
- tolua_usertype(tolua_S,"cWebPlugin_Lua");
- tolua_usertype(tolua_S,"Lua__cPlugin_NewLua");
- tolua_usertype(tolua_S,"cPacket");
- tolua_usertype(tolua_S,"cPacket_BlockDig");
- tolua_usertype(tolua_S,"cWebAdmin");
- tolua_usertype(tolua_S,"cCraftingRecipes");
- tolua_usertype(tolua_S,"cBlockEntity");
- tolua_usertype(tolua_S,"cGroupManager");
- tolua_usertype(tolua_S,"Lua__cPickup");
- tolua_usertype(tolua_S,"Lua__cPlugin");
- tolua_usertype(tolua_S,"cWebPlugin");
- tolua_usertype(tolua_S,"cPacket_BlockPlace");
- tolua_usertype(tolua_S,"cLadder");
- tolua_usertype(tolua_S,"cPluginManager");
- tolua_usertype(tolua_S,"HTTPFormData");
- tolua_usertype(tolua_S,"cIniFile");
- tolua_usertype(tolua_S,"Lua__cPlayer");
- tolua_usertype(tolua_S,"HTTPRequest");
- tolua_usertype(tolua_S,"cPawn");
- tolua_usertype(tolua_S,"cPlayer");
- tolua_usertype(tolua_S,"cTorch");
- tolua_usertype(tolua_S,"cStringMap");
- tolua_usertype(tolua_S,"cInventory");
- tolua_usertype(tolua_S,"cWorld");
- tolua_usertype(tolua_S,"cPlugin_NewLua");
- tolua_usertype(tolua_S,"Lua__cEntity");
- tolua_usertype(tolua_S,"Vector3d");
-}
-
-/* method: DirectionToMetaData of class cTorch */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cTorch_DirectionToMetaData00
-static int tolua_AllToLua_cTorch_DirectionToMetaData00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cTorch",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- char a_Direction = ((char) tolua_tonumber(tolua_S,2,0));
- {
- char tolua_ret = (char) cTorch::DirectionToMetaData(a_Direction);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'DirectionToMetaData'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: MetaDataToDirection of class cTorch */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cTorch_MetaDataToDirection00
-static int tolua_AllToLua_cTorch_MetaDataToDirection00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cTorch",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- char a_MetaData = ((char) tolua_tonumber(tolua_S,2,0));
- {
- char tolua_ret = (char) cTorch::MetaDataToDirection(a_MetaData);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'MetaDataToDirection'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: RotationToMetaData of class cStairs */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cStairs_RotationToMetaData00
-static int tolua_AllToLua_cStairs_RotationToMetaData00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cStairs",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- float a_Rotation = ((float) tolua_tonumber(tolua_S,2,0));
- int a_Direction = ((int) tolua_tonumber(tolua_S,3,0));
- {
- char tolua_ret = (char) cStairs::RotationToMetaData(a_Rotation,a_Direction);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'RotationToMetaData'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: DirectionToMetaData of class cStep */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cStep_DirectionToMetaData00
-static int tolua_AllToLua_cStep_DirectionToMetaData00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cStep",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- int a_Direction = ((int) tolua_tonumber(tolua_S,2,0));
- {
- char tolua_ret = (char) cStep::DirectionToMetaData(a_Direction);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'DirectionToMetaData'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: DirectionToMetaData of class cLadder */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLadder_DirectionToMetaData00
-static int tolua_AllToLua_cLadder_DirectionToMetaData00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cLadder",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- char a_Direction = ((char) tolua_tonumber(tolua_S,2,0));
- {
- char tolua_ret = (char) cLadder::DirectionToMetaData(a_Direction);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'DirectionToMetaData'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: MetaDataToDirection of class cLadder */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLadder_MetaDataToDirection00
-static int tolua_AllToLua_cLadder_MetaDataToDirection00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cLadder",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- char a_MetaData = ((char) tolua_tonumber(tolua_S,2,0));
- {
- char tolua_ret = (char) cLadder::MetaDataToDirection(a_MetaData);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'MetaDataToDirection'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_new00
-static int tolua_AllToLua_cIniFile_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const std::string iniPath = ((const std::string) tolua_tocppstring(tolua_S,2,""));
- {
- cIniFile* tolua_ret = (cIniFile*) Mtolua_new((cIniFile)(iniPath));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cIniFile");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_new00_local
-static int tolua_AllToLua_cIniFile_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const std::string iniPath = ((const std::string) tolua_tocppstring(tolua_S,2,""));
- {
- cIniFile* tolua_ret = (cIniFile*) Mtolua_new((cIniFile)(iniPath));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cIniFile");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: CaseSensitive of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_CaseSensitive00
-static int tolua_AllToLua_cIniFile_CaseSensitive00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CaseSensitive'", NULL);
-#endif
- {
- self->CaseSensitive();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'CaseSensitive'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: CaseInsensitive of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_CaseInsensitive00
-static int tolua_AllToLua_cIniFile_CaseInsensitive00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CaseInsensitive'", NULL);
-#endif
- {
- self->CaseInsensitive();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'CaseInsensitive'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Path of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Path00
-static int tolua_AllToLua_cIniFile_Path00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string newPath = ((const std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Path'", NULL);
-#endif
- {
- self->Path(newPath);
- tolua_pushcppstring(tolua_S,(const char*)newPath);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Path'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Path of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Path01
-static int tolua_AllToLua_cIniFile_Path01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Path'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->Path();
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_Path00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetPath of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetPath00
-static int tolua_AllToLua_cIniFile_SetPath00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string newPath = ((const std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPath'", NULL);
-#endif
- {
- self->SetPath(newPath);
- tolua_pushcppstring(tolua_S,(const char*)newPath);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetPath'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: ReadFile of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_ReadFile00
-static int tolua_AllToLua_cIniFile_ReadFile00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ReadFile'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->ReadFile();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'ReadFile'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: WriteFile of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_WriteFile00
-static int tolua_AllToLua_cIniFile_WriteFile00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'WriteFile'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->WriteFile();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'WriteFile'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Erase of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Erase00
-static int tolua_AllToLua_cIniFile_Erase00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Erase'", NULL);
-#endif
- {
- self->Erase();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Erase'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Clear of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Clear00
-static int tolua_AllToLua_cIniFile_Clear00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL);
-#endif
- {
- self->Clear();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Reset of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Reset00
-static int tolua_AllToLua_cIniFile_Reset00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Reset'", NULL);
-#endif
- {
- self->Reset();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Reset'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: FindKey of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_FindKey00
-static int tolua_AllToLua_cIniFile_FindKey00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FindKey'", NULL);
-#endif
- {
- long tolua_ret = (long) self->FindKey(keyname);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'FindKey'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: FindValue of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_FindValue00
-static int tolua_AllToLua_cIniFile_FindValue00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
- const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FindValue'", NULL);
-#endif
- {
- long tolua_ret = (long) self->FindValue(keyID,valuename);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'FindValue'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: NumKeys of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumKeys00
-static int tolua_AllToLua_cIniFile_NumKeys00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumKeys'", NULL);
-#endif
- {
- unsigned tolua_ret = (unsigned) self->NumKeys();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'NumKeys'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetNumKeys of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetNumKeys00
-static int tolua_AllToLua_cIniFile_GetNumKeys00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumKeys'", NULL);
-#endif
- {
- unsigned tolua_ret = (unsigned) self->GetNumKeys();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetNumKeys'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: AddKeyName of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_AddKeyName00
-static int tolua_AllToLua_cIniFile_AddKeyName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddKeyName'", NULL);
-#endif
- {
- unsigned tolua_ret = (unsigned) self->AddKeyName(keyname);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'AddKeyName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: KeyName of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyName00
-static int tolua_AllToLua_cIniFile_KeyName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyName'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->KeyName(keyID);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'KeyName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetKeyName of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetKeyName00
-static int tolua_AllToLua_cIniFile_GetKeyName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetKeyName'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->GetKeyName(keyID);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetKeyName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: NumValues of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumValues00
-static int tolua_AllToLua_cIniFile_NumValues00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumValues'", NULL);
-#endif
- {
- unsigned tolua_ret = (unsigned) self->NumValues(keyname);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'NumValues'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetNumValues of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetNumValues00
-static int tolua_AllToLua_cIniFile_GetNumValues00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumValues'", NULL);
-#endif
- {
- unsigned tolua_ret = (unsigned) self->GetNumValues(keyname);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetNumValues'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: NumValues of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumValues01
-static int tolua_AllToLua_cIniFile_NumValues01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumValues'", NULL);
-#endif
- {
- unsigned tolua_ret = (unsigned) self->NumValues(keyID);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_NumValues00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetNumValues of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetNumValues01
-static int tolua_AllToLua_cIniFile_GetNumValues01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumValues'", NULL);
-#endif
- {
- unsigned tolua_ret = (unsigned) self->GetNumValues(keyID);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_GetNumValues00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: ValueName of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_ValueName00
-static int tolua_AllToLua_cIniFile_ValueName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
- const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ValueName'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->ValueName(keyname,valueID);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'ValueName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetValueName of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueName00
-static int tolua_AllToLua_cIniFile_GetValueName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
- const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueName'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->GetValueName(keyname,valueID);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetValueName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: ValueName of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_ValueName01
-static int tolua_AllToLua_cIniFile_ValueName01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
- const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ValueName'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->ValueName(keyID,valueID);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_ValueName00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetValueName of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueName01
-static int tolua_AllToLua_cIniFile_GetValueName01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
- const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueName'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->GetValueName(keyID,valueID);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_GetValueName00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetValue of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue00
-static int tolua_AllToLua_cIniFile_GetValue00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0));
- const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL);
-#endif
- {
- AString tolua_ret = (AString) self->GetValue(keyname,valuename);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetValue'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetValue of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue01
-static int tolua_AllToLua_cIniFile_GetValue01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0));
- const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0));
- const AString defValue = ((const AString) tolua_tocppstring(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL);
-#endif
- {
- AString tolua_ret = (AString) self->GetValue(keyname,valuename,defValue);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- tolua_pushcppstring(tolua_S,(const char*)defValue);
- }
- }
- return 4;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_GetValue00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetValue of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue02
-static int tolua_AllToLua_cIniFile_GetValue02(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
- const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL);
-#endif
- {
- AString tolua_ret = (AString) self->GetValue(keyID,valueID);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_GetValue01(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetValue of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue03
-static int tolua_AllToLua_cIniFile_GetValue03(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
- const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0));
- const AString defValue = ((const AString) tolua_tocppstring(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL);
-#endif
- {
- AString tolua_ret = (AString) self->GetValue(keyID,valueID,defValue);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)defValue);
- }
- }
- return 2;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_GetValue02(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetValueF of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueF00
-static int tolua_AllToLua_cIniFile_GetValueF00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0));
- const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0));
- const double defValue = ((const double) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueF'", NULL);
-#endif
- {
- double tolua_ret = (double) self->GetValueF(keyname,valuename,defValue);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetValueF'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetValueI of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueI00
-static int tolua_AllToLua_cIniFile_GetValueI00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0));
- const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0));
- const int defValue = ((const int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueI'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetValueI(keyname,valuename,defValue);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetValueI'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetValueB of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueB00
-static int tolua_AllToLua_cIniFile_GetValueB00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isboolean(tolua_S,4,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0));
- const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0));
- const bool defValue = ((const bool) tolua_toboolean(tolua_S,4,false));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueB'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->GetValueB(keyname,valuename,defValue);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetValueB'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetValueSet of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSet00
-static int tolua_AllToLua_cIniFile_GetValueSet00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0));
- const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSet'", NULL);
-#endif
- {
- AString tolua_ret = (AString) self->GetValueSet(keyname,valuename);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetValueSet'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetValueSet of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSet01
-static int tolua_AllToLua_cIniFile_GetValueSet01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0));
- const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0));
- const AString defValue = ((const AString) tolua_tocppstring(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSet'", NULL);
-#endif
- {
- AString tolua_ret = (AString) self->GetValueSet(keyname,valuename,defValue);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- tolua_pushcppstring(tolua_S,(const char*)defValue);
- }
- }
- return 4;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_GetValueSet00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetValueSetF of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSetF00
-static int tolua_AllToLua_cIniFile_GetValueSetF00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0));
- const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0));
- const double defValue = ((const double) tolua_tonumber(tolua_S,4,0.0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSetF'", NULL);
-#endif
- {
- double tolua_ret = (double) self->GetValueSetF(keyname,valuename,defValue);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetValueSetF'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetValueSetI of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSetI00
-static int tolua_AllToLua_cIniFile_GetValueSetI00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0));
- const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0));
- const int defValue = ((const int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSetI'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetValueSetI(keyname,valuename,defValue);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetValueSetI'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetValueSetB of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSetB00
-static int tolua_AllToLua_cIniFile_GetValueSetB00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isboolean(tolua_S,4,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0));
- const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0));
- const bool defValue = ((const bool) tolua_toboolean(tolua_S,4,false));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSetB'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->GetValueSetB(keyname,valuename,defValue);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetValueSetB'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetValue of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValue00
-static int tolua_AllToLua_cIniFile_SetValue00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
- const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0));
- const std::string value = ((const std::string) tolua_tocppstring(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValue'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->SetValue(keyID,valueID,value);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)value);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetValue'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetValue of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValue01
-static int tolua_AllToLua_cIniFile_SetValue01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,4,0,&tolua_err) ||
- !tolua_isboolean(tolua_S,5,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,6,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
- const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0));
- const std::string value = ((const std::string) tolua_tocppstring(tolua_S,4,0));
- const bool create = ((const bool) tolua_toboolean(tolua_S,5,true));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValue'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->SetValue(keyname,valuename,value,create);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- tolua_pushcppstring(tolua_S,(const char*)value);
- }
- }
- return 4;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_SetValue00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetValueI of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValueI00
-static int tolua_AllToLua_cIniFile_SetValueI00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isboolean(tolua_S,5,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,6,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
- const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0));
- const int value = ((const int) tolua_tonumber(tolua_S,4,0));
- const bool create = ((const bool) tolua_toboolean(tolua_S,5,true));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValueI'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->SetValueI(keyname,valuename,value,create);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetValueI'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetValueB of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValueB00
-static int tolua_AllToLua_cIniFile_SetValueB00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isboolean(tolua_S,4,0,&tolua_err) ||
- !tolua_isboolean(tolua_S,5,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,6,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
- const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0));
- const bool value = ((const bool) tolua_toboolean(tolua_S,4,0));
- const bool create = ((const bool) tolua_toboolean(tolua_S,5,true));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValueB'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->SetValueB(keyname,valuename,value,create);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetValueB'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetValueF of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValueF00
-static int tolua_AllToLua_cIniFile_SetValueF00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isboolean(tolua_S,5,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,6,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
- const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0));
- const double value = ((const double) tolua_tonumber(tolua_S,4,0));
- const bool create = ((const bool) tolua_toboolean(tolua_S,5,true));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValueF'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->SetValueF(keyname,valuename,value,create);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetValueF'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: DeleteValueByID of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteValueByID00
-static int tolua_AllToLua_cIniFile_DeleteValueByID00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
- const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteValueByID'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->DeleteValueByID(keyID,valueID);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'DeleteValueByID'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: DeleteValue of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteValue00
-static int tolua_AllToLua_cIniFile_DeleteValue00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
- const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteValue'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->DeleteValue(keyname,valuename);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)valuename);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'DeleteValue'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: DeleteKey of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKey00
-static int tolua_AllToLua_cIniFile_DeleteKey00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKey'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->DeleteKey(keyname);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'DeleteKey'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: NumHeaderComments of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumHeaderComments00
-static int tolua_AllToLua_cIniFile_NumHeaderComments00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumHeaderComments'", NULL);
-#endif
- {
- unsigned tolua_ret = (unsigned) self->NumHeaderComments();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'NumHeaderComments'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: HeaderComment of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_HeaderComment00
-static int tolua_AllToLua_cIniFile_HeaderComment00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string comment = ((const std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HeaderComment'", NULL);
-#endif
- {
- self->HeaderComment(comment);
- tolua_pushcppstring(tolua_S,(const char*)comment);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'HeaderComment'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: HeaderComment of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_HeaderComment01
-static int tolua_AllToLua_cIniFile_HeaderComment01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HeaderComment'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->HeaderComment(commentID);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_HeaderComment00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: DeleteHeaderComment of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteHeaderComment00
-static int tolua_AllToLua_cIniFile_DeleteHeaderComment00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- unsigned commentID = ((unsigned) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteHeaderComment'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->DeleteHeaderComment(commentID);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'DeleteHeaderComment'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: DeleteHeaderComments of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteHeaderComments00
-static int tolua_AllToLua_cIniFile_DeleteHeaderComments00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteHeaderComments'", NULL);
-#endif
- {
- self->DeleteHeaderComments();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'DeleteHeaderComments'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: NumKeyComments of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumKeyComments00
-static int tolua_AllToLua_cIniFile_NumKeyComments00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumKeyComments'", NULL);
-#endif
- {
- unsigned tolua_ret = (unsigned) self->NumKeyComments(keyID);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'NumKeyComments'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: NumKeyComments of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumKeyComments01
-static int tolua_AllToLua_cIniFile_NumKeyComments01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumKeyComments'", NULL);
-#endif
- {
- unsigned tolua_ret = (unsigned) self->NumKeyComments(keyname);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- }
- }
- return 2;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_NumKeyComments00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: KeyComment of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment00
-static int tolua_AllToLua_cIniFile_KeyComment00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
- const std::string comment = ((const std::string) tolua_tocppstring(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->KeyComment(keyID,comment);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)comment);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'KeyComment'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: KeyComment of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment01
-static int tolua_AllToLua_cIniFile_KeyComment01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
- const std::string comment = ((const std::string) tolua_tocppstring(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->KeyComment(keyname,comment);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- tolua_pushcppstring(tolua_S,(const char*)comment);
- }
- }
- return 3;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_KeyComment00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: KeyComment of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment02
-static int tolua_AllToLua_cIniFile_KeyComment02(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
- const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->KeyComment(keyID,commentID);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_KeyComment01(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: KeyComment of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment03
-static int tolua_AllToLua_cIniFile_KeyComment03(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
- const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->KeyComment(keyname,commentID);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- }
- }
- return 2;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_KeyComment02(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: DeleteKeyComment of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComment00
-static int tolua_AllToLua_cIniFile_DeleteKeyComment00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
- const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComment'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->DeleteKeyComment(keyID,commentID);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'DeleteKeyComment'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: DeleteKeyComment of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComment01
-static int tolua_AllToLua_cIniFile_DeleteKeyComment01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
- const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComment'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->DeleteKeyComment(keyname,commentID);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- }
- }
- return 2;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_DeleteKeyComment00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: DeleteKeyComments of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComments00
-static int tolua_AllToLua_cIniFile_DeleteKeyComments00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComments'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->DeleteKeyComments(keyID);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'DeleteKeyComments'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: DeleteKeyComments of class cIniFile */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComments01
-static int tolua_AllToLua_cIniFile_DeleteKeyComments01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0);
- const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComments'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->DeleteKeyComments(keyname);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)keyname);
- }
- }
- return 2;
-tolua_lerror:
- return tolua_AllToLua_cIniFile_DeleteKeyComments00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* function: BlockStringToType */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_BlockStringToType00
-static int tolua_AllToLua_BlockStringToType00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_iscppstring(tolua_S,1,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const AString a_BlockTypeString = ((const AString) tolua_tocppstring(tolua_S,1,0));
- {
- int tolua_ret = (int) BlockStringToType(a_BlockTypeString);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)a_BlockTypeString);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'BlockStringToType'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* function: StringToItem */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_StringToItem00
-static int tolua_AllToLua_StringToItem00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_iscppstring(tolua_S,1,0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const AString a_ItemTypeString = ((const AString) tolua_tocppstring(tolua_S,1,0));
- cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0));
- {
- bool tolua_ret = (bool) StringToItem(a_ItemTypeString,*a_Item);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)a_ItemTypeString);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'StringToItem'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: g_BlockLightValue */
-#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockLightValue
-static int tolua_get_AllToLua_g_BlockLightValue(lua_State* tolua_S)
-{
- int tolua_index;
-#ifndef TOLUA_RELEASE
- {
- tolua_Error tolua_err;
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);
- }
-#endif
- tolua_index = (int)tolua_tonumber(tolua_S,2,0);
-#ifndef TOLUA_RELEASE
- if (tolua_index<0)
- tolua_error(tolua_S,"array indexing out of range.",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)g_BlockLightValue[tolua_index]);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: g_BlockLightValue */
-#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockLightValue
-static int tolua_set_AllToLua_g_BlockLightValue(lua_State* tolua_S)
-{
- int tolua_index;
-#ifndef TOLUA_RELEASE
- {
- tolua_Error tolua_err;
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);
- }
-#endif
- tolua_index = (int)tolua_tonumber(tolua_S,2,0);
-#ifndef TOLUA_RELEASE
- if (tolua_index<0)
- tolua_error(tolua_S,"array indexing out of range.",NULL);
-#endif
- g_BlockLightValue[tolua_index] = ((unsigned char) tolua_tonumber(tolua_S,3,0));
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: g_BlockSpreadLightFalloff */
-#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockSpreadLightFalloff
-static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S)
-{
- int tolua_index;
-#ifndef TOLUA_RELEASE
- {
- tolua_Error tolua_err;
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);
- }
-#endif
- tolua_index = (int)tolua_tonumber(tolua_S,2,0);
-#ifndef TOLUA_RELEASE
- if (tolua_index<0)
- tolua_error(tolua_S,"array indexing out of range.",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)g_BlockSpreadLightFalloff[tolua_index]);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: g_BlockSpreadLightFalloff */
-#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockSpreadLightFalloff
-static int tolua_set_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S)
-{
- int tolua_index;
-#ifndef TOLUA_RELEASE
- {
- tolua_Error tolua_err;
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);
- }
-#endif
- tolua_index = (int)tolua_tonumber(tolua_S,2,0);
-#ifndef TOLUA_RELEASE
- if (tolua_index<0)
- tolua_error(tolua_S,"array indexing out of range.",NULL);
-#endif
- g_BlockSpreadLightFalloff[tolua_index] = ((unsigned char) tolua_tonumber(tolua_S,3,0));
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: g_BlockTransparent */
-#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockTransparent
-static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S)
-{
- int tolua_index;
-#ifndef TOLUA_RELEASE
- {
- tolua_Error tolua_err;
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);
- }
-#endif
- tolua_index = (int)tolua_tonumber(tolua_S,2,0);
-#ifndef TOLUA_RELEASE
- if (tolua_index<0)
- tolua_error(tolua_S,"array indexing out of range.",NULL);
-#endif
- tolua_pushboolean(tolua_S,(bool)g_BlockTransparent[tolua_index]);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: g_BlockTransparent */
-#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockTransparent
-static int tolua_set_AllToLua_g_BlockTransparent(lua_State* tolua_S)
-{
- int tolua_index;
-#ifndef TOLUA_RELEASE
- {
- tolua_Error tolua_err;
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);
- }
-#endif
- tolua_index = (int)tolua_tonumber(tolua_S,2,0);
-#ifndef TOLUA_RELEASE
- if (tolua_index<0)
- tolua_error(tolua_S,"array indexing out of range.",NULL);
-#endif
- g_BlockTransparent[tolua_index] = ((bool) tolua_toboolean(tolua_S,3,0));
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: g_BlockOneHitDig */
-#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockOneHitDig
-static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S)
-{
- int tolua_index;
-#ifndef TOLUA_RELEASE
- {
- tolua_Error tolua_err;
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);
- }
-#endif
- tolua_index = (int)tolua_tonumber(tolua_S,2,0);
-#ifndef TOLUA_RELEASE
- if (tolua_index<0)
- tolua_error(tolua_S,"array indexing out of range.",NULL);
-#endif
- tolua_pushboolean(tolua_S,(bool)g_BlockOneHitDig[tolua_index]);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: g_BlockOneHitDig */
-#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockOneHitDig
-static int tolua_set_AllToLua_g_BlockOneHitDig(lua_State* tolua_S)
-{
- int tolua_index;
-#ifndef TOLUA_RELEASE
- {
- tolua_Error tolua_err;
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);
- }
-#endif
- tolua_index = (int)tolua_tonumber(tolua_S,2,0);
-#ifndef TOLUA_RELEASE
- if (tolua_index<0)
- tolua_error(tolua_S,"array indexing out of range.",NULL);
-#endif
- g_BlockOneHitDig[tolua_index] = ((bool) tolua_toboolean(tolua_S,3,0));
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* function: IsValidBlock */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_IsValidBlock00
-static int tolua_AllToLua_IsValidBlock00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isnumber(tolua_S,1,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- int a_BlockID = ((int) tolua_tonumber(tolua_S,1,0));
- {
- bool tolua_ret = (bool) IsValidBlock(a_BlockID);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsValidBlock'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* function: IsValidItem */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_IsValidItem00
-static int tolua_AllToLua_IsValidItem00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isnumber(tolua_S,1,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- int a_ItemID = ((int) tolua_tonumber(tolua_S,1,0));
- {
- bool tolua_ret = (bool) IsValidItem(a_ItemID);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsValidItem'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* function: AddDirection */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_AddDirection00
-static int tolua_AllToLua_AddDirection00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isnumber(tolua_S,1,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isboolean(tolua_S,5,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,6,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- int a_X = ((int) tolua_tonumber(tolua_S,1,0));
- unsigned char a_Y = ((unsigned char) tolua_tonumber(tolua_S,2,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,3,0));
- char a_Direction = ((char) tolua_tonumber(tolua_S,4,0));
- bool a_bInverse = ((bool) tolua_toboolean(tolua_S,5,false));
- {
- AddDirection(a_X,a_Y,a_Z,a_Direction,a_bInverse);
- tolua_pushnumber(tolua_S,(lua_Number)a_X);
- tolua_pushnumber(tolua_S,(lua_Number)a_Y);
- tolua_pushnumber(tolua_S,(lua_Number)a_Z);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'AddDirection'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* function: ItemCategory::IsPickaxe */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsPickaxe00
-static int tolua_AllToLua_ItemCategory_IsPickaxe00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isnumber(tolua_S,1,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0));
- {
- bool tolua_ret = (bool) ItemCategory::IsPickaxe(a_ItemID);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsPickaxe'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* function: ItemCategory::IsAxe */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsAxe00
-static int tolua_AllToLua_ItemCategory_IsAxe00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isnumber(tolua_S,1,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0));
- {
- bool tolua_ret = (bool) ItemCategory::IsAxe(a_ItemID);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsAxe'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* function: ItemCategory::IsSword */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsSword00
-static int tolua_AllToLua_ItemCategory_IsSword00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isnumber(tolua_S,1,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0));
- {
- bool tolua_ret = (bool) ItemCategory::IsSword(a_ItemID);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsSword'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* function: ItemCategory::IsHoe */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsHoe00
-static int tolua_AllToLua_ItemCategory_IsHoe00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isnumber(tolua_S,1,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0));
- {
- bool tolua_ret = (bool) ItemCategory::IsHoe(a_ItemID);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsHoe'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* function: ItemCategory::IsShovel */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsShovel00
-static int tolua_AllToLua_ItemCategory_IsShovel00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isnumber(tolua_S,1,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0));
- {
- bool tolua_ret = (bool) ItemCategory::IsShovel(a_ItemID);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsShovel'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* function: ItemCategory::IsTool */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsTool00
-static int tolua_AllToLua_ItemCategory_IsTool00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isnumber(tolua_S,1,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0));
- {
- bool tolua_ret = (bool) ItemCategory::IsTool(a_ItemID);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsTool'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* function: GetTime */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_GetTime00
-static int tolua_AllToLua_GetTime00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isnoobj(tolua_S,1,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- unsigned int tolua_ret = (unsigned int) GetTime();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetTime'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* function: GetChar */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_GetChar00
-static int tolua_AllToLua_GetChar00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_iscppstring(tolua_S,1,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- std::string a_Str = ((std::string) tolua_tocppstring(tolua_S,1,0));
- unsigned int a_Idx = ((unsigned int) tolua_tonumber(tolua_S,2,0));
- {
- std::string tolua_ret = (std::string) GetChar(a_Str,a_Idx);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)a_Str);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetChar'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: clear of class cStringMap */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cStringMap_clear00
-static int tolua_AllToLua_cStringMap_clear00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cStringMap",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cStringMap* self = (cStringMap*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'clear'", NULL);
-#endif
- {
- self->clear();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'clear'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: size of class cStringMap */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cStringMap_size00
-static int tolua_AllToLua_cStringMap_size00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cStringMap",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cStringMap* self = (const cStringMap*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'size'", NULL);
-#endif
- {
- unsigned int tolua_ret = (unsigned int) self->size();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'size'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: get of class cStringMap */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cStringMap_get00
-static int tolua_AllToLua_cStringMap_get00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cStringMap",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cStringMap* self = (cStringMap*) tolua_tousertype(tolua_S,1,0);
- const std::string index = ((const std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'get'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->get(index);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)index);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'get'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Color of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Color
-static int tolua_get_cChatColor_Color(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Color);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Delimiter of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Delimiter
-static int tolua_get_cChatColor_Delimiter(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Delimiter);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Black of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Black
-static int tolua_get_cChatColor_Black(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Black);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Navy of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Navy
-static int tolua_get_cChatColor_Navy(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Navy);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Green of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Green
-static int tolua_get_cChatColor_Green(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Green);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Blue of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Blue
-static int tolua_get_cChatColor_Blue(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Blue);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Red of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Red
-static int tolua_get_cChatColor_Red(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Red);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Purple of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Purple
-static int tolua_get_cChatColor_Purple(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Purple);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Gold of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Gold
-static int tolua_get_cChatColor_Gold(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Gold);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: LightGray of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightGray
-static int tolua_get_cChatColor_LightGray(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightGray);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Gray of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Gray
-static int tolua_get_cChatColor_Gray(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Gray);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: DarkPurple of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_DarkPurple
-static int tolua_get_cChatColor_DarkPurple(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::DarkPurple);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: LightGreen of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightGreen
-static int tolua_get_cChatColor_LightGreen(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightGreen);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: LightBlue of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightBlue
-static int tolua_get_cChatColor_LightBlue(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightBlue);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Rose of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Rose
-static int tolua_get_cChatColor_Rose(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Rose);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: LightPurple of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightPurple
-static int tolua_get_cChatColor_LightPurple(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightPurple);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Yellow of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Yellow
-static int tolua_get_cChatColor_Yellow(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Yellow);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: White of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_White
-static int tolua_get_cChatColor_White(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::White);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Random of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Random
-static int tolua_get_cChatColor_Random(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Random);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Bold of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Bold
-static int tolua_get_cChatColor_Bold(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Bold);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Strikethrough of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Strikethrough
-static int tolua_get_cChatColor_Strikethrough(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Strikethrough);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Underlined of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Underlined
-static int tolua_get_cChatColor_Underlined(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Underlined);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Italic of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Italic
-static int tolua_get_cChatColor_Italic(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Italic);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Plain of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Plain
-static int tolua_get_cChatColor_Plain(lua_State* tolua_S)
-{
- tolua_pushcppstring(tolua_S,(const char*)cChatColor::Plain);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: MakeColor of class cChatColor */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cChatColor_MakeColor00
-static int tolua_AllToLua_cChatColor_MakeColor00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cChatColor",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- char a_Color = ((char) tolua_tonumber(tolua_S,2,0));
- {
- const std::string tolua_ret = (const std::string) cChatColor::MakeColor(a_Color);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'MakeColor'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetPlayer of class cClientHandle */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetPlayer00
-static int tolua_AllToLua_cClientHandle_GetPlayer00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPlayer'", NULL);
-#endif
- {
- cPlayer* tolua_ret = (cPlayer*) self->GetPlayer();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlayer");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetPlayer'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Kick of class cClientHandle */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_Kick00
-static int tolua_AllToLua_cClientHandle_Kick00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0);
- const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Kick'", NULL);
-#endif
- {
- self->Kick(a_Reason);
- tolua_pushcppstring(tolua_S,(const char*)a_Reason);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Kick'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetUsername of class cClientHandle */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetUsername00
-static int tolua_AllToLua_cClientHandle_GetUsername00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cClientHandle",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cClientHandle* self = (const cClientHandle*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetUsername'", NULL);
-#endif
- {
- const AString tolua_ret = (const AString) self->GetUsername();
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetUsername'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetPing of class cClientHandle */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetPing00
-static int tolua_AllToLua_cClientHandle_GetPing00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cClientHandle",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cClientHandle* self = (const cClientHandle*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPing'", NULL);
-#endif
- {
- short tolua_ret = (short) self->GetPing();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetPing'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetViewDistance of class cClientHandle */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_SetViewDistance00
-static int tolua_AllToLua_cClientHandle_SetViewDistance00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0);
- int a_ViewDistance = ((int) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetViewDistance'", NULL);
-#endif
- {
- self->SetViewDistance(a_ViewDistance);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetViewDistance'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetViewDistance of class cClientHandle */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetViewDistance00
-static int tolua_AllToLua_cClientHandle_GetViewDistance00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetViewDistance'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetViewDistance();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetViewDistance'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetUniqueID of class cClientHandle */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetUniqueID00
-static int tolua_AllToLua_cClientHandle_GetUniqueID00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cClientHandle",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cClientHandle* self = (const cClientHandle*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetUniqueID'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetUniqueID();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetUniqueID'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: delete of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_delete00
-static int tolua_AllToLua_cEntity_delete00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL);
-#endif
- Mtolua_delete(self);
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Initialize of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_Initialize00
-static int tolua_AllToLua_cEntity_Initialize00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
- cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL);
-#endif
- {
- self->Initialize(a_World);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetEntityType of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetEntityType00
-static int tolua_AllToLua_cEntity_GetEntityType00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEntityType'", NULL);
-#endif
- {
- unsigned int tolua_ret = (unsigned int) self->GetEntityType();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetEntityType'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: IsA of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_IsA00
-static int tolua_AllToLua_cEntity_IsA00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
- const char* a_EntityType = ((const char*) tolua_tostring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsA'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->IsA(a_EntityType);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsA'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetClass of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetClass00
-static int tolua_AllToLua_cEntity_GetClass00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetClass'", NULL);
-#endif
- {
- const char* tolua_ret = (const char*) self->GetClass();
- tolua_pushstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetClass'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetWorld of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetWorld00
-static int tolua_AllToLua_cEntity_GetWorld00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWorld'", NULL);
-#endif
- {
- cWorld* tolua_ret = (cWorld*) self->GetWorld();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetWorld'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetPosition of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosition00
-static int tolua_AllToLua_cEntity_GetPosition00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosition'", NULL);
-#endif
- {
- const Vector3d& tolua_ret = (const Vector3d&) self->GetPosition();
- tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const Vector3d");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetPosition'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetPosX of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosX00
-static int tolua_AllToLua_cEntity_GetPosX00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosX'", NULL);
-#endif
- {
- const double tolua_ret = (const double) self->GetPosX();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetPosX'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetPosY of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosY00
-static int tolua_AllToLua_cEntity_GetPosY00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosY'", NULL);
-#endif
- {
- const double tolua_ret = (const double) self->GetPosY();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetPosY'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetPosZ of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosZ00
-static int tolua_AllToLua_cEntity_GetPosZ00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosZ'", NULL);
-#endif
- {
- const double tolua_ret = (const double) self->GetPosZ();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetPosZ'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetRot of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetRot00
-static int tolua_AllToLua_cEntity_GetRot00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetRot'", NULL);
-#endif
- {
- const Vector3f& tolua_ret = (const Vector3f&) self->GetRot();
- tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const Vector3f");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetRot'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetRotation of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetRotation00
-static int tolua_AllToLua_cEntity_GetRotation00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetRotation'", NULL);
-#endif
- {
- float tolua_ret = (float) self->GetRotation();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetRotation'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetPitch of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPitch00
-static int tolua_AllToLua_cEntity_GetPitch00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPitch'", NULL);
-#endif
- {
- float tolua_ret = (float) self->GetPitch();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetPitch'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetRoll of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetRoll00
-static int tolua_AllToLua_cEntity_GetRoll00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetRoll'", NULL);
-#endif
- {
- float tolua_ret = (float) self->GetRoll();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetRoll'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetLookVector of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetLookVector00
-static int tolua_AllToLua_cEntity_GetLookVector00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLookVector'", NULL);
-#endif
- {
- Vector3f tolua_ret = (Vector3f) self->GetLookVector();
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetLookVector'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetChunkX of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkX00
-static int tolua_AllToLua_cEntity_GetChunkX00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetChunkX'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetChunkX();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetChunkX'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetChunkY of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkY00
-static int tolua_AllToLua_cEntity_GetChunkY00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetChunkY'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetChunkY();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetChunkY'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetChunkZ of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkZ00
-static int tolua_AllToLua_cEntity_GetChunkZ00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetChunkZ'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetChunkZ();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetChunkZ'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetPosX of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosX00
-static int tolua_AllToLua_cEntity_SetPosX00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
- const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosX'", NULL);
-#endif
- {
- self->SetPosX(a_PosX);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosX);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetPosX'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetPosY of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosY00
-static int tolua_AllToLua_cEntity_SetPosY00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
- const double a_PosY = ((const double) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosY'", NULL);
-#endif
- {
- self->SetPosY(a_PosY);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosY);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetPosY'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetPosZ of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosZ00
-static int tolua_AllToLua_cEntity_SetPosZ00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
- const double a_PosZ = ((const double) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosZ'", NULL);
-#endif
- {
- self->SetPosZ(a_PosZ);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosZ);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetPosZ'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetPosition of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosition00
-static int tolua_AllToLua_cEntity_SetPosition00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
- const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0));
- const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0));
- const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosition'", NULL);
-#endif
- {
- self->SetPosition(a_PosX,a_PosY,a_PosZ);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosX);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosY);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosZ);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetPosition'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetPosition of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosition01
-static int tolua_AllToLua_cEntity_SetPosition01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
- const Vector3d* a_Pos = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosition'", NULL);
-#endif
- {
- self->SetPosition(*a_Pos);
- }
- }
- return 0;
-tolua_lerror:
- return tolua_AllToLua_cEntity_SetPosition00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetRot of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetRot00
-static int tolua_AllToLua_cEntity_SetRot00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
- const Vector3f* a_Rot = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRot'", NULL);
-#endif
- {
- self->SetRot(*a_Rot);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetRot'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetRotation of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetRotation00
-static int tolua_AllToLua_cEntity_SetRotation00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
- float a_Rotation = ((float) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRotation'", NULL);
-#endif
- {
- self->SetRotation(a_Rotation);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetRotation'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetPitch of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPitch00
-static int tolua_AllToLua_cEntity_SetPitch00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
- float a_Pitch = ((float) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPitch'", NULL);
-#endif
- {
- self->SetPitch(a_Pitch);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetPitch'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetRoll of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetRoll00
-static int tolua_AllToLua_cEntity_SetRoll00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
- float a_Roll = ((float) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRoll'", NULL);
-#endif
- {
- self->SetRoll(a_Roll);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetRoll'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetUniqueID of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetUniqueID00
-static int tolua_AllToLua_cEntity_GetUniqueID00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetUniqueID'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetUniqueID();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetUniqueID'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: IsDestroyed of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_IsDestroyed00
-static int tolua_AllToLua_cEntity_IsDestroyed00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsDestroyed'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->IsDestroyed();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsDestroyed'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Destroy of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_Destroy00
-static int tolua_AllToLua_cEntity_Destroy00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Destroy'", NULL);
-#endif
- {
- self->Destroy();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Destroy'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Tick of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_Tick00
-static int tolua_AllToLua_cEntity_Tick00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
- float a_Dt = ((float) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Tick'", NULL);
-#endif
- {
- self->Tick(a_Dt);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Tick'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SpawnOn of class cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SpawnOn00
-static int tolua_AllToLua_cEntity_SpawnOn00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cClientHandle",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
- cClientHandle* a_Client = ((cClientHandle*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SpawnOn'", NULL);
-#endif
- {
- self->SpawnOn(a_Client);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SpawnOn'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
- class Lua__cEntity : public cEntity, public ToluaBase {
-public:
- void Initialize( cWorld* a_World) {
- if (push_method("Initialize", tolua_AllToLua_cEntity_Initialize00)) {
- tolua_pushusertype(lua_state, (void*)a_World, "cWorld");
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cEntity:: Initialize(a_World);
- };
- };
- unsigned int GetEntityType( void ) {
- if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) {
- ToluaBase::dbcall(lua_state, 1, 1);
- unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return (unsigned int ) cEntity:: GetEntityType();
- };
- };
- bool IsA( const char* a_EntityType) {
- if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) {
- tolua_pushstring(lua_state, (const char*)a_EntityType);
- ToluaBase::dbcall(lua_state, 2, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cEntity:: IsA(a_EntityType);
- };
- };
- const char* GetClass( void ) {
- if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) {
- ToluaBase::dbcall(lua_state, 1, 1);
- const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( const char* ) cEntity:: GetClass();
- };
- };
- void Tick( float a_Dt) {
- if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) {
- tolua_pushnumber(lua_state, (lua_Number)a_Dt);
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- if (lua_state)
- LOG("pure-virtual method cEntity::Tick not implemented.");
- else {
- LOG("pure-virtual method cEntity::Tick called with no lua_state. Aborting");
- ::abort();
- };
- return ( void )0;
- };
- };
-
- void cEntity__Initialize( cWorld* a_World) {
- return ( void )cEntity::Initialize(a_World);
- };
- unsigned int cEntity__GetEntityType( void ) {
- return (unsigned int )cEntity::GetEntityType();
- };
- bool cEntity__IsA( const char* a_EntityType) {
- return ( bool )cEntity::IsA(a_EntityType);
- };
- const char* cEntity__GetClass( void ) {
- return ( const char* )cEntity::GetClass();
- };
- Lua__cEntity( const double& a_X, const double& a_Y, const double& a_Z): cEntity(a_X,a_Y,a_Z){};
-};
-
-/* method: tolua__set_instance of class Lua__cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_tolua__set_instance00
-static int tolua_AllToLua_Lua__cEntity_tolua__set_instance00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0);
- lua_State* L = tolua_S;
- lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL);
-#endif
- {
- self->tolua__set_instance(L,lo);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cEntity__Initialize of class Lua__cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__Initialize00
-static int tolua_AllToLua_Lua__cEntity_cEntity__Initialize00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0);
- cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__Initialize'", NULL);
-#endif
- {
- self->cEntity__Initialize(a_World);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cEntity__Initialize'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cEntity__GetEntityType of class Lua__cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__GetEntityType00
-static int tolua_AllToLua_Lua__cEntity_cEntity__GetEntityType00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__GetEntityType'", NULL);
-#endif
- {
- unsigned int tolua_ret = (unsigned int) self->cEntity__GetEntityType();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cEntity__GetEntityType'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cEntity__IsA of class Lua__cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__IsA00
-static int tolua_AllToLua_Lua__cEntity_cEntity__IsA00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0);
- const char* a_EntityType = ((const char*) tolua_tostring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__IsA'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cEntity__IsA(a_EntityType);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cEntity__IsA'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cEntity__GetClass of class Lua__cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__GetClass00
-static int tolua_AllToLua_Lua__cEntity_cEntity__GetClass00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__GetClass'", NULL);
-#endif
- {
- const char* tolua_ret = (const char*) self->cEntity__GetClass();
- tolua_pushstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cEntity__GetClass'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Lua__cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_new00
-static int tolua_AllToLua_Lua__cEntity_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Lua__cEntity",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const double a_X = ((const double) tolua_tonumber(tolua_S,2,0));
- const double a_Y = ((const double) tolua_tonumber(tolua_S,3,0));
- const double a_Z = ((const double) tolua_tonumber(tolua_S,4,0));
- {
- Lua__cEntity* tolua_ret = (Lua__cEntity*) Mtolua_new((Lua__cEntity)(a_X,a_Y,a_Z));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cEntity");
- tolua_pushnumber(tolua_S,(lua_Number)a_X);
- tolua_pushnumber(tolua_S,(lua_Number)a_Y);
- tolua_pushnumber(tolua_S,(lua_Number)a_Z);
- }
- }
- return 4;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Lua__cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_new00_local
-static int tolua_AllToLua_Lua__cEntity_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Lua__cEntity",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const double a_X = ((const double) tolua_tonumber(tolua_S,2,0));
- const double a_Y = ((const double) tolua_tonumber(tolua_S,3,0));
- const double a_Z = ((const double) tolua_tonumber(tolua_S,4,0));
- {
- Lua__cEntity* tolua_ret = (Lua__cEntity*) Mtolua_new((Lua__cEntity)(a_X,a_Y,a_Z));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cEntity");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- tolua_pushnumber(tolua_S,(lua_Number)a_X);
- tolua_pushnumber(tolua_S,(lua_Number)a_Y);
- tolua_pushnumber(tolua_S,(lua_Number)a_Z);
- }
- }
- return 4;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: delete of class Lua__cEntity */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_delete00
-static int tolua_AllToLua_Lua__cEntity_delete00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL);
-#endif
- Mtolua_delete(self);
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-
-/* function to release collected object via destructor */
-#ifdef __cplusplus
-
-static int tolua_collect_Lua__cEntity (lua_State* tolua_S)
-{
- Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0);
- delete self;
- return 0;
-}
-#endif
-
-/* get function: Damage of class TakeDamageInfo */
-#ifndef TOLUA_DISABLE_tolua_get_TakeDamageInfo_Damage
-static int tolua_get_TakeDamageInfo_Damage(lua_State* tolua_S)
-{
- TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Damage'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->Damage);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: Damage of class TakeDamageInfo */
-#ifndef TOLUA_DISABLE_tolua_set_TakeDamageInfo_Damage
-static int tolua_set_TakeDamageInfo_Damage(lua_State* tolua_S)
-{
- TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Damage'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->Damage = ((int) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Instigator of class TakeDamageInfo */
-#ifndef TOLUA_DISABLE_tolua_get_TakeDamageInfo_Instigator_ptr
-static int tolua_get_TakeDamageInfo_Instigator_ptr(lua_State* tolua_S)
-{
- TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Instigator'",NULL);
-#endif
- tolua_pushusertype(tolua_S,(void*)self->Instigator,"cEntity");
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: Instigator of class TakeDamageInfo */
-#ifndef TOLUA_DISABLE_tolua_set_TakeDamageInfo_Instigator_ptr
-static int tolua_set_TakeDamageInfo_Instigator_ptr(lua_State* tolua_S)
-{
- TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Instigator'",NULL);
- if (!tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->Instigator = ((cEntity*) tolua_tousertype(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: TeleportToEntity of class cPawn */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_TeleportToEntity00
-static int tolua_AllToLua_cPawn_TeleportToEntity00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0);
- cEntity* a_Entity = ((cEntity*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TeleportToEntity'", NULL);
-#endif
- {
- self->TeleportToEntity(a_Entity);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'TeleportToEntity'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: TeleportTo of class cPawn */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_TeleportTo00
-static int tolua_AllToLua_cPawn_TeleportTo00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0);
- const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0));
- const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0));
- const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TeleportTo'", NULL);
-#endif
- {
- self->TeleportTo(a_PosX,a_PosY,a_PosZ);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosX);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosY);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosZ);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'TeleportTo'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Heal of class cPawn */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_Heal00
-static int tolua_AllToLua_cPawn_Heal00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0);
- int a_Health = ((int) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Heal'", NULL);
-#endif
- {
- self->Heal(a_Health);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Heal'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: TakeDamage of class cPawn */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_TakeDamage00
-static int tolua_AllToLua_cPawn_TakeDamage00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0);
- int a_Damage = ((int) tolua_tonumber(tolua_S,2,0));
- cEntity* a_Instigator = ((cEntity*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TakeDamage'", NULL);
-#endif
- {
- self->TakeDamage(a_Damage,a_Instigator);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'TakeDamage'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: KilledBy of class cPawn */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_KilledBy00
-static int tolua_AllToLua_cPawn_KilledBy00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0);
- cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KilledBy'", NULL);
-#endif
- {
- self->KilledBy(a_Killer);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'KilledBy'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetHealth of class cPawn */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_GetHealth00
-static int tolua_AllToLua_cPawn_GetHealth00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHealth'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetHealth();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetHealth'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
- class Lua__cPawn : public cPawn, public ToluaBase {
-public:
- void TeleportToEntity( cEntity* a_Entity) {
- if (push_method("TeleportToEntity", tolua_AllToLua_cPawn_TeleportToEntity00)) {
- tolua_pushusertype(lua_state, (void*)a_Entity, "cEntity");
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cPawn:: TeleportToEntity(a_Entity);
- };
- };
- void TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) {
- if (push_method("TeleportTo", tolua_AllToLua_cPawn_TeleportTo00)) {
- tolua_pushnumber(lua_state, (lua_Number)a_PosX);
- tolua_pushnumber(lua_state, (lua_Number)a_PosY);
- tolua_pushnumber(lua_state, (lua_Number)a_PosZ);
- ToluaBase::dbcall(lua_state, 4, 0);
- } else {
- return ( void ) cPawn:: TeleportTo(a_PosX,a_PosY,a_PosZ);
- };
- };
- void TakeDamage( int a_Damage, cEntity* a_Instigator) {
- if (push_method("TakeDamage", tolua_AllToLua_cPawn_TakeDamage00)) {
- tolua_pushnumber(lua_state, (lua_Number)a_Damage);
- tolua_pushusertype(lua_state, (void*)a_Instigator, "cEntity");
- ToluaBase::dbcall(lua_state, 3, 0);
- } else {
- return ( void ) cPawn:: TakeDamage(a_Damage,a_Instigator);
- };
- };
- void KilledBy( cEntity* a_Killer) {
- if (push_method("KilledBy", tolua_AllToLua_cPawn_KilledBy00)) {
- tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity");
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cPawn:: KilledBy(a_Killer);
- };
- };
- void Initialize( cWorld* a_World) {
- if (push_method("Initialize", tolua_AllToLua_cEntity_Initialize00)) {
- tolua_pushusertype(lua_state, (void*)a_World, "cWorld");
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cPawn:: Initialize(a_World);
- };
- };
- unsigned int GetEntityType( void ) {
- if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) {
- ToluaBase::dbcall(lua_state, 1, 1);
- unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return (unsigned int ) cPawn:: GetEntityType();
- };
- };
- bool IsA( const char* a_EntityType) {
- if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) {
- tolua_pushstring(lua_state, (const char*)a_EntityType);
- ToluaBase::dbcall(lua_state, 2, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPawn:: IsA(a_EntityType);
- };
- };
- const char* GetClass( void ) {
- if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) {
- ToluaBase::dbcall(lua_state, 1, 1);
- const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( const char* ) cPawn:: GetClass();
- };
- };
- void Tick( float a_Dt) {
- if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) {
- tolua_pushnumber(lua_state, (lua_Number)a_Dt);
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- if (lua_state)
- LOG("pure-virtual method cPawn::Tick not implemented.");
- else {
- LOG("pure-virtual method cPawn::Tick called with no lua_state. Aborting");
- ::abort();
- };
- return ( void )0;
- };
- };
-
- void cPawn__TeleportToEntity( cEntity* a_Entity) {
- return ( void )cPawn::TeleportToEntity(a_Entity);
- };
- void cPawn__TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) {
- return ( void )cPawn::TeleportTo(a_PosX,a_PosY,a_PosZ);
- };
- void cPawn__TakeDamage( int a_Damage, cEntity* a_Instigator) {
- return ( void )cPawn::TakeDamage(a_Damage,a_Instigator);
- };
- void cPawn__KilledBy( cEntity* a_Killer) {
- return ( void )cPawn::KilledBy(a_Killer);
- };
- void cPawn__Initialize( cWorld* a_World) {
- return ( void )cPawn::Initialize(a_World);
- };
- unsigned int cPawn__GetEntityType( void ) {
- return (unsigned int )cPawn::GetEntityType();
- };
- bool cPawn__IsA( const char* a_EntityType) {
- return ( bool )cPawn::IsA(a_EntityType);
- };
- const char* cPawn__GetClass( void ) {
- return ( const char* )cPawn::GetClass();
- };
-};
-
-/* method: tolua__set_instance of class Lua__cPawn */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_tolua__set_instance00
-static int tolua_AllToLua_Lua__cPawn_tolua__set_instance00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0);
- lua_State* L = tolua_S;
- lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL);
-#endif
- {
- self->tolua__set_instance(L,lo);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPawn__TeleportToEntity of class Lua__cPawn */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__TeleportToEntity00
-static int tolua_AllToLua_Lua__cPawn_cPawn__TeleportToEntity00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0);
- cEntity* a_Entity = ((cEntity*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__TeleportToEntity'", NULL);
-#endif
- {
- self->cPawn__TeleportToEntity(a_Entity);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPawn__TeleportToEntity'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPawn__TeleportTo of class Lua__cPawn */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__TeleportTo00
-static int tolua_AllToLua_Lua__cPawn_cPawn__TeleportTo00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0);
- const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0));
- const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0));
- const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__TeleportTo'", NULL);
-#endif
- {
- self->cPawn__TeleportTo(a_PosX,a_PosY,a_PosZ);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosX);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosY);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosZ);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPawn__TeleportTo'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPawn__TakeDamage of class Lua__cPawn */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__TakeDamage00
-static int tolua_AllToLua_Lua__cPawn_cPawn__TakeDamage00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0);
- int a_Damage = ((int) tolua_tonumber(tolua_S,2,0));
- cEntity* a_Instigator = ((cEntity*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__TakeDamage'", NULL);
-#endif
- {
- self->cPawn__TakeDamage(a_Damage,a_Instigator);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPawn__TakeDamage'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPawn__KilledBy of class Lua__cPawn */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__KilledBy00
-static int tolua_AllToLua_Lua__cPawn_cPawn__KilledBy00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0);
- cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__KilledBy'", NULL);
-#endif
- {
- self->cPawn__KilledBy(a_Killer);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPawn__KilledBy'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Initialize of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Initialize00
-static int tolua_AllToLua_cPlayer_Initialize00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL);
-#endif
- {
- self->Initialize(a_World);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetEyeHeight of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetEyeHeight00
-static int tolua_AllToLua_cPlayer_GetEyeHeight00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEyeHeight'", NULL);
-#endif
- {
- double tolua_ret = (double) self->GetEyeHeight();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetEyeHeight'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetEyePosition of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetEyePosition00
-static int tolua_AllToLua_cPlayer_GetEyePosition00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEyePosition'", NULL);
-#endif
- {
- Vector3d tolua_ret = (Vector3d) self->GetEyePosition();
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetEyePosition'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetFlying of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetFlying00
-static int tolua_AllToLua_cPlayer_GetFlying00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFlying'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->GetFlying();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetFlying'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetStance of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetStance00
-static int tolua_AllToLua_cPlayer_GetStance00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStance'", NULL);
-#endif
- {
- const double tolua_ret = (const double) self->GetStance();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetStance'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetInventory of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetInventory00
-static int tolua_AllToLua_cPlayer_GetInventory00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetInventory'", NULL);
-#endif
- {
- cInventory& tolua_ret = (cInventory&) self->GetInventory();
- tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cInventory");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetInventory'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: TeleportTo of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_TeleportTo00
-static int tolua_AllToLua_cPlayer_TeleportTo00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0));
- const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0));
- const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TeleportTo'", NULL);
-#endif
- {
- self->TeleportTo(a_PosX,a_PosY,a_PosZ);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosX);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosY);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosZ);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'TeleportTo'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetGameMode of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetGameMode00
-static int tolua_AllToLua_cPlayer_GetGameMode00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGameMode'", NULL);
-#endif
- {
- eGameMode tolua_ret = (eGameMode) self->GetGameMode();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetGameMode'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetIP of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetIP00
-static int tolua_AllToLua_cPlayer_GetIP00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIP'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->GetIP();
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetIP'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetLastBlockActionTime of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetLastBlockActionTime00
-static int tolua_AllToLua_cPlayer_GetLastBlockActionTime00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLastBlockActionTime'", NULL);
-#endif
- {
- float tolua_ret = (float) self->GetLastBlockActionTime();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetLastBlockActionTime'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetLastBlockActionCnt of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetLastBlockActionCnt00
-static int tolua_AllToLua_cPlayer_GetLastBlockActionCnt00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLastBlockActionCnt'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetLastBlockActionCnt();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetLastBlockActionCnt'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetLastBlockActionCnt of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetLastBlockActionCnt00
-static int tolua_AllToLua_cPlayer_SetLastBlockActionCnt00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- int tolua_var_1 = ((int) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetLastBlockActionCnt'", NULL);
-#endif
- {
- self->SetLastBlockActionCnt(tolua_var_1);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetLastBlockActionCnt'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetLastBlockActionTime of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetLastBlockActionTime00
-static int tolua_AllToLua_cPlayer_SetLastBlockActionTime00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetLastBlockActionTime'", NULL);
-#endif
- {
- self->SetLastBlockActionTime();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetLastBlockActionTime'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetGameMode of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetGameMode00
-static int tolua_AllToLua_cPlayer_SetGameMode00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- eGameMode a_GameMode = ((eGameMode) (int) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetGameMode'", NULL);
-#endif
- {
- self->SetGameMode(a_GameMode);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetGameMode'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: MoveTo of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_MoveTo00
-static int tolua_AllToLua_cPlayer_MoveTo00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- const Vector3d* a_NewPos = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'MoveTo'", NULL);
-#endif
- {
- self->MoveTo(*a_NewPos);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'MoveTo'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetClientHandle of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetClientHandle00
-static int tolua_AllToLua_cPlayer_GetClientHandle00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetClientHandle'", NULL);
-#endif
- {
- cClientHandle* tolua_ret = (cClientHandle*) self->GetClientHandle();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cClientHandle");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetClientHandle'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SendMessage of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SendMessage00
-static int tolua_AllToLua_cPlayer_SendMessage00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- const char* a_Message = ((const char*) tolua_tostring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL);
-#endif
- {
- self->SendMessage(a_Message);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetName of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetName00
-static int tolua_AllToLua_cPlayer_GetName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL);
-#endif
- {
- const AString tolua_ret = (const AString) self->GetName();
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetName of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetName00
-static int tolua_AllToLua_cPlayer_SetName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- const AString a_Name = ((const AString) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL);
-#endif
- {
- self->SetName(a_Name);
- tolua_pushcppstring(tolua_S,(const char*)a_Name);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: AddToGroup of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_AddToGroup00
-static int tolua_AllToLua_cPlayer_AddToGroup00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- const char* a_GroupName = ((const char*) tolua_tostring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddToGroup'", NULL);
-#endif
- {
- self->AddToGroup(a_GroupName);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'AddToGroup'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: CanUseCommand of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_CanUseCommand00
-static int tolua_AllToLua_cPlayer_CanUseCommand00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- const char* a_Command = ((const char*) tolua_tostring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CanUseCommand'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->CanUseCommand(a_Command);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'CanUseCommand'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: HasPermission of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_HasPermission00
-static int tolua_AllToLua_cPlayer_HasPermission00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- const char* a_Permission = ((const char*) tolua_tostring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasPermission'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->HasPermission(a_Permission);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'HasPermission'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: IsInGroup of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsInGroup00
-static int tolua_AllToLua_cPlayer_IsInGroup00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- const char* a_Group = ((const char*) tolua_tostring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInGroup'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->IsInGroup(a_Group);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsInGroup'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetColor of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetColor00
-static int tolua_AllToLua_cPlayer_GetColor00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetColor'", NULL);
-#endif
- {
- AString tolua_ret = (AString) self->GetColor();
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetColor'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: TossItem of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_TossItem00
-static int tolua_AllToLua_cPlayer_TossItem00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isboolean(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- bool a_bDraggingItem = ((bool) tolua_toboolean(tolua_S,2,0));
- int a_Amount = ((int) tolua_tonumber(tolua_S,3,1));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TossItem'", NULL);
-#endif
- {
- self->TossItem(a_bDraggingItem,a_Amount);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'TossItem'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Heal of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Heal00
-static int tolua_AllToLua_cPlayer_Heal00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- int a_Health = ((int) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Heal'", NULL);
-#endif
- {
- self->Heal(a_Health);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Heal'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: TakeDamage of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_TakeDamage00
-static int tolua_AllToLua_cPlayer_TakeDamage00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- int a_Damage = ((int) tolua_tonumber(tolua_S,2,0));
- cEntity* a_Instigator = ((cEntity*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TakeDamage'", NULL);
-#endif
- {
- self->TakeDamage(a_Damage,a_Instigator);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'TakeDamage'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: KilledBy of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_KilledBy00
-static int tolua_AllToLua_cPlayer_KilledBy00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KilledBy'", NULL);
-#endif
- {
- self->KilledBy(a_Killer);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'KilledBy'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Respawn of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Respawn00
-static int tolua_AllToLua_cPlayer_Respawn00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Respawn'", NULL);
-#endif
- {
- self->Respawn();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Respawn'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetVisible of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetVisible00
-static int tolua_AllToLua_cPlayer_SetVisible00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isboolean(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- bool a_bVisible = ((bool) tolua_toboolean(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetVisible'", NULL);
-#endif
- {
- self->SetVisible(a_bVisible);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetVisible'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: IsVisible of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsVisible00
-static int tolua_AllToLua_cPlayer_IsVisible00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsVisible'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->IsVisible();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsVisible'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: MoveToWorld of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_MoveToWorld00
-static int tolua_AllToLua_cPlayer_MoveToWorld00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
- const char* a_WorldName = ((const char*) tolua_tostring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'MoveToWorld'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->MoveToWorld(a_WorldName);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'MoveToWorld'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: LoadPermissionsFromDisk of class cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00
-static int tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'LoadPermissionsFromDisk'", NULL);
-#endif
- {
- self->LoadPermissionsFromDisk();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'LoadPermissionsFromDisk'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
- class Lua__cPlayer : public cPlayer, public ToluaBase {
-public:
- void Initialize( cWorld* a_World) {
- if (push_method("Initialize", tolua_AllToLua_cPlayer_Initialize00)) {
- tolua_pushusertype(lua_state, (void*)a_World, "cWorld");
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cPlayer:: Initialize(a_World);
- };
- };
- void TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) {
- if (push_method("TeleportTo", tolua_AllToLua_cPlayer_TeleportTo00)) {
- tolua_pushnumber(lua_state, (lua_Number)a_PosX);
- tolua_pushnumber(lua_state, (lua_Number)a_PosY);
- tolua_pushnumber(lua_state, (lua_Number)a_PosZ);
- ToluaBase::dbcall(lua_state, 4, 0);
- } else {
- return ( void ) cPlayer:: TeleportTo(a_PosX,a_PosY,a_PosZ);
- };
- };
- void MoveTo( const Vector3d& a_NewPos) {
- if (push_method("MoveTo", tolua_AllToLua_cPlayer_MoveTo00)) {
- tolua_pushusertype(lua_state, (void*)&a_NewPos, "const Vector3d");
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cPlayer:: MoveTo(a_NewPos);
- };
- };
- void TeleportToEntity( cEntity* a_Entity) {
- if (push_method("TeleportToEntity", tolua_AllToLua_cPawn_TeleportToEntity00)) {
- tolua_pushusertype(lua_state, (void*)a_Entity, "cEntity");
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cPlayer:: TeleportToEntity(a_Entity);
- };
- };
- void TakeDamage( int a_Damage, cEntity* a_Instigator) {
- if (push_method("TakeDamage", tolua_AllToLua_cPawn_TakeDamage00)) {
- tolua_pushnumber(lua_state, (lua_Number)a_Damage);
- tolua_pushusertype(lua_state, (void*)a_Instigator, "cEntity");
- ToluaBase::dbcall(lua_state, 3, 0);
- } else {
- return ( void ) cPlayer:: TakeDamage(a_Damage,a_Instigator);
- };
- };
- void KilledBy( cEntity* a_Killer) {
- if (push_method("KilledBy", tolua_AllToLua_cPawn_KilledBy00)) {
- tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity");
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cPlayer:: KilledBy(a_Killer);
- };
- };
- unsigned int GetEntityType( void ) {
- if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) {
- ToluaBase::dbcall(lua_state, 1, 1);
- unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return (unsigned int ) cPlayer:: GetEntityType();
- };
- };
- bool IsA( const char* a_EntityType) {
- if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) {
- tolua_pushstring(lua_state, (const char*)a_EntityType);
- ToluaBase::dbcall(lua_state, 2, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlayer:: IsA(a_EntityType);
- };
- };
- const char* GetClass( void ) {
- if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) {
- ToluaBase::dbcall(lua_state, 1, 1);
- const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( const char* ) cPlayer:: GetClass();
- };
- };
- void Tick( float a_Dt) {
- if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) {
- tolua_pushnumber(lua_state, (lua_Number)a_Dt);
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- if (lua_state)
- LOG("pure-virtual method cPlayer::Tick not implemented.");
- else {
- LOG("pure-virtual method cPlayer::Tick called with no lua_state. Aborting");
- ::abort();
- };
- return ( void )0;
- };
- };
-
- void cPlayer__Initialize( cWorld* a_World) {
- return ( void )cPlayer::Initialize(a_World);
- };
- void cPlayer__TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) {
- return ( void )cPlayer::TeleportTo(a_PosX,a_PosY,a_PosZ);
- };
- void cPlayer__MoveTo( const Vector3d& a_NewPos) {
- return ( void )cPlayer::MoveTo(a_NewPos);
- };
- void cPlayer__TeleportToEntity( cEntity* a_Entity) {
- return ( void )cPlayer::TeleportToEntity(a_Entity);
- };
- void cPlayer__TakeDamage( int a_Damage, cEntity* a_Instigator) {
- return ( void )cPlayer::TakeDamage(a_Damage,a_Instigator);
- };
- void cPlayer__KilledBy( cEntity* a_Killer) {
- return ( void )cPlayer::KilledBy(a_Killer);
- };
- unsigned int cPlayer__GetEntityType( void ) {
- return (unsigned int )cPlayer::GetEntityType();
- };
- bool cPlayer__IsA( const char* a_EntityType) {
- return ( bool )cPlayer::IsA(a_EntityType);
- };
- const char* cPlayer__GetClass( void ) {
- return ( const char* )cPlayer::GetClass();
- };
-};
-
-/* method: tolua__set_instance of class Lua__cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_tolua__set_instance00
-static int tolua_AllToLua_Lua__cPlayer_tolua__set_instance00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0);
- lua_State* L = tolua_S;
- lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL);
-#endif
- {
- self->tolua__set_instance(L,lo);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlayer__Initialize of class Lua__cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00
-static int tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0);
- cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlayer__Initialize'", NULL);
-#endif
- {
- self->cPlayer__Initialize(a_World);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlayer__Initialize'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlayer__TeleportTo of class Lua__cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_cPlayer__TeleportTo00
-static int tolua_AllToLua_Lua__cPlayer_cPlayer__TeleportTo00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0);
- const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0));
- const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0));
- const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlayer__TeleportTo'", NULL);
-#endif
- {
- self->cPlayer__TeleportTo(a_PosX,a_PosY,a_PosZ);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosX);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosY);
- tolua_pushnumber(tolua_S,(lua_Number)a_PosZ);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlayer__TeleportTo'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlayer__MoveTo of class Lua__cPlayer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00
-static int tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0);
- const Vector3d* a_NewPos = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlayer__MoveTo'", NULL);
-#endif
- {
- self->cPlayer__MoveTo(*a_NewPos);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlayer__MoveTo'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetPluginManager of class cPluginManager */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetPluginManager00
-static int tolua_AllToLua_cPluginManager_GetPluginManager00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cPluginManager",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- cPluginManager* tolua_ret = (cPluginManager*) cPluginManager::GetPluginManager();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPluginManager");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetPluginManager'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetPlugin of class cPluginManager */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetPlugin00
-static int tolua_AllToLua_cPluginManager_GetPlugin00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cPluginManager",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cPluginManager* self = (const cPluginManager*) tolua_tousertype(tolua_S,1,0);
- const char* a_Plugin = ((const char*) tolua_tostring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPlugin'", NULL);
-#endif
- {
- cPlugin* tolua_ret = (cPlugin*) self->GetPlugin(a_Plugin);
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlugin");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetPlugin'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: ReloadPlugins of class cPluginManager */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_ReloadPlugins00
-static int tolua_AllToLua_cPluginManager_ReloadPlugins00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ReloadPlugins'", NULL);
-#endif
- {
- self->ReloadPlugins();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'ReloadPlugins'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: AddPlugin of class cPluginManager */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_AddPlugin00
-static int tolua_AllToLua_cPluginManager_AddPlugin00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
- lua_State* a_LuaState = tolua_S;
- cPlugin* a_Plugin = ((cPlugin*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddPlugin'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->AddPlugin(a_LuaState,a_Plugin);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'AddPlugin'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: AddHook of class cPluginManager */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_AddHook00
-static int tolua_AllToLua_cPluginManager_AddHook00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPlugin",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
- cPlugin* a_Plugin = ((cPlugin*) tolua_tousertype(tolua_S,2,0));
- cPluginManager::PluginHook a_Hook = ((cPluginManager::PluginHook) (int) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddHook'", NULL);
-#endif
- {
- self->AddHook(a_Plugin,a_Hook);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'AddHook'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetNumPlugins of class cPluginManager */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetNumPlugins00
-static int tolua_AllToLua_cPluginManager_GetNumPlugins00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cPluginManager",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cPluginManager* self = (const cPluginManager*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumPlugins'", NULL);
-#endif
- {
- unsigned int tolua_ret = (unsigned int) self->GetNumPlugins();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetNumPlugins'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: RemovePlugin of class cPluginManager */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_RemovePlugin00
-static int tolua_AllToLua_cPluginManager_RemovePlugin00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPlugin",0,&tolua_err) ||
- !tolua_isboolean(tolua_S,3,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
- cPlugin* a_Plugin = ((cPlugin*) tolua_tousertype(tolua_S,2,0));
- bool a_bDelete = ((bool) tolua_toboolean(tolua_S,3,false));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RemovePlugin'", NULL);
-#endif
- {
- self->RemovePlugin(a_Plugin,a_bDelete);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'RemovePlugin'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: RemoveLuaPlugin of class cPluginManager */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_RemoveLuaPlugin00
-static int tolua_AllToLua_cPluginManager_RemoveLuaPlugin00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
- std::string a_FileName = ((std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RemoveLuaPlugin'", NULL);
-#endif
- {
- self->RemoveLuaPlugin(a_FileName);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'RemoveLuaPlugin'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetLuaPlugin of class cPluginManager */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetLuaPlugin00
-static int tolua_AllToLua_cPluginManager_GetLuaPlugin00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
- lua_State* a_State = tolua_S;
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLuaPlugin'", NULL);
-#endif
- {
- cPlugin_Lua* tolua_ret = (cPlugin_Lua*) self->GetLuaPlugin(a_State);
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlugin_Lua");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetLuaPlugin'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: delete of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_delete00
-static int tolua_AllToLua_cPlugin_delete00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL);
-#endif
- Mtolua_delete(self);
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnDisable of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnDisable00
-static int tolua_AllToLua_cPlugin_OnDisable00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisable'", NULL);
-#endif
- {
- self->OnDisable();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnDisable'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Initialize of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_Initialize00
-static int tolua_AllToLua_cPlugin_Initialize00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->Initialize();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Tick of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_Tick00
-static int tolua_AllToLua_cPlugin_Tick00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- float a_Dt = ((float) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Tick'", NULL);
-#endif
- {
- self->Tick(a_Dt);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Tick'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnCollectItem of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnCollectItem00
-static int tolua_AllToLua_cPlugin_OnCollectItem00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPickup",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPickup* a_Pickup = ((cPickup*) tolua_tousertype(tolua_S,2,0));
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnCollectItem'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->OnCollectItem(a_Pickup,a_Player);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnCollectItem'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnDisconnect of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnDisconnect00
-static int tolua_AllToLua_cPlugin_OnDisconnect00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0));
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisconnect'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->OnDisconnect(a_Reason,a_Player);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)a_Reason);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnDisconnect'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnBlockPlace of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnBlockPlace00
-static int tolua_AllToLua_cPlugin_OnBlockPlace00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPacket_BlockPlace",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPacket_BlockPlace* a_PacketData = ((cPacket_BlockPlace*) tolua_tousertype(tolua_S,2,0));
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnBlockPlace'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->OnBlockPlace(a_PacketData,a_Player);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnBlockPlace'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnBlockDig of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnBlockDig00
-static int tolua_AllToLua_cPlugin_OnBlockDig00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPacket_BlockDig",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,4,"cItem",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPacket_BlockDig* a_PacketData = ((cPacket_BlockDig*) tolua_tousertype(tolua_S,2,0));
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
- cItem* a_PickupItem = ((cItem*) tolua_tousertype(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnBlockDig'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->OnBlockDig(a_PacketData,a_Player,a_PickupItem);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnBlockDig'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnChat of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnChat00
-static int tolua_AllToLua_cPlugin_OnChat00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- const char* a_Chat = ((const char*) tolua_tostring(tolua_S,2,0));
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnChat'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->OnChat(a_Chat,a_Player);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnChat'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnLogin of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnLogin00
-static int tolua_AllToLua_cPlugin_OnLogin00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPacket_Login",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPacket_Login* a_PacketData = ((cPacket_Login*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnLogin'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->OnLogin(a_PacketData);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnLogin'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnPlayerSpawn of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPlayerSpawn00
-static int tolua_AllToLua_cPlugin_OnPlayerSpawn00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPlayerSpawn'", NULL);
-#endif
- {
- self->OnPlayerSpawn(a_Player);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnPlayerSpawn'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnPlayerJoin of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPlayerJoin00
-static int tolua_AllToLua_cPlugin_OnPlayerJoin00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPlayerJoin'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->OnPlayerJoin(a_Player);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnPlayerJoin'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnPlayerMove of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPlayerMove00
-static int tolua_AllToLua_cPlugin_OnPlayerMove00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPlayerMove'", NULL);
-#endif
- {
- self->OnPlayerMove(a_Player);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnPlayerMove'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnTakeDamage of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnTakeDamage00
-static int tolua_AllToLua_cPlugin_OnTakeDamage00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"TakeDamageInfo",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPawn* a_Pawn = ((cPawn*) tolua_tousertype(tolua_S,2,0));
- TakeDamageInfo* a_TakeDamageInfo = ((TakeDamageInfo*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnTakeDamage'", NULL);
-#endif
- {
- self->OnTakeDamage(a_Pawn,a_TakeDamageInfo);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnTakeDamage'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnKilled of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnKilled00
-static int tolua_AllToLua_cPlugin_OnKilled00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPawn* a_Killed = ((cPawn*) tolua_tousertype(tolua_S,2,0));
- cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnKilled'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->OnKilled(a_Killed,a_Killer);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnKilled'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnChunkGenerated of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnChunkGenerated00
-static int tolua_AllToLua_cPlugin_OnChunkGenerated00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0));
- int a_ChunkX = ((int) tolua_tonumber(tolua_S,3,0));
- int a_ChunkZ = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnChunkGenerated'", NULL);
-#endif
- {
- self->OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnChunkGenerated'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnChunkGenerating of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnChunkGenerating00
-static int tolua_AllToLua_cPlugin_OnChunkGenerating00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isusertype(tolua_S,4,"cLuaChunk",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0));
- int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0));
- cLuaChunk* a_pLuaChunk = ((cLuaChunk*) tolua_tousertype(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnChunkGenerating'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnChunkGenerating'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnPreCrafting of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPreCrafting00
-static int tolua_AllToLua_cPlugin_OnPreCrafting00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0));
- const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0));
- cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPreCrafting'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->OnPreCrafting(a_Player,a_Grid,a_Recipe);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnPreCrafting'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnCraftingNoRecipe of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnCraftingNoRecipe00
-static int tolua_AllToLua_cPlugin_OnCraftingNoRecipe00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0));
- const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0));
- cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnCraftingNoRecipe'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnCraftingNoRecipe'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnPostCrafting of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPostCrafting00
-static int tolua_AllToLua_cPlugin_OnPostCrafting00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0));
- const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0));
- cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPostCrafting'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->OnPostCrafting(a_Player,a_Grid,a_Recipe);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnPostCrafting'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: OnBlockToPickup of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnBlockToPickup00
-static int tolua_AllToLua_cPlugin_OnBlockToPickup00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"BLOCKTYPE",0,&tolua_err)) ||
- (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"NIBBLETYPE",0,&tolua_err)) ||
- !tolua_isusertype(tolua_S,4,"const cPlayer",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) ||
- (tolua_isvaluenil(tolua_S,6,&tolua_err) || !tolua_isusertype(tolua_S,6,"cItems",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,7,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- BLOCKTYPE a_BlockType = *((BLOCKTYPE*) tolua_tousertype(tolua_S,2,0));
- NIBBLETYPE a_BlockMeta = *((NIBBLETYPE*) tolua_tousertype(tolua_S,3,0));
- const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,4,0));
- const cItem* a_EquippedItem = ((const cItem*) tolua_tousertype(tolua_S,5,0));
- cItems* a_Pickups = ((cItems*) tolua_tousertype(tolua_S,6,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnBlockToPickup'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,*a_EquippedItem,*a_Pickups);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnBlockToPickup'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetName of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_GetName00
-static int tolua_AllToLua_cPlugin_GetName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cPlugin* self = (const cPlugin*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL);
-#endif
- {
- const char* tolua_ret = (const char*) self->GetName();
- tolua_pushstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetName of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_SetName00
-static int tolua_AllToLua_cPlugin_SetName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- const char* a_Name = ((const char*) tolua_tostring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL);
-#endif
- {
- self->SetName(a_Name);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetVersion of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_GetVersion00
-static int tolua_AllToLua_cPlugin_GetVersion00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cPlugin* self = (const cPlugin*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetVersion'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetVersion();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetVersion'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetVersion of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_SetVersion00
-static int tolua_AllToLua_cPlugin_SetVersion00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- int a_Version = ((int) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetVersion'", NULL);
-#endif
- {
- self->SetVersion(a_Version);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetVersion'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Command of class CommandStruct */
-#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Command
-static int tolua_get_cPlugin__CommandStruct_Command(lua_State* tolua_S)
-{
- cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Command'",NULL);
-#endif
- tolua_pushcppstring(tolua_S,(const char*)self->Command);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: Command of class CommandStruct */
-#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Command
-static int tolua_set_cPlugin__CommandStruct_Command(lua_State* tolua_S)
-{
- cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Command'",NULL);
- if (!tolua_iscppstring(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->Command = ((std::string) tolua_tocppstring(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Description of class CommandStruct */
-#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Description
-static int tolua_get_cPlugin__CommandStruct_Description(lua_State* tolua_S)
-{
- cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Description'",NULL);
-#endif
- tolua_pushcppstring(tolua_S,(const char*)self->Description);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: Description of class CommandStruct */
-#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Description
-static int tolua_set_cPlugin__CommandStruct_Description(lua_State* tolua_S)
-{
- cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Description'",NULL);
- if (!tolua_iscppstring(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->Description = ((std::string) tolua_tocppstring(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Permission of class CommandStruct */
-#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Permission
-static int tolua_get_cPlugin__CommandStruct_Permission(lua_State* tolua_S)
-{
- cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Permission'",NULL);
-#endif
- tolua_pushcppstring(tolua_S,(const char*)self->Permission);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: Permission of class CommandStruct */
-#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Permission
-static int tolua_set_cPlugin__CommandStruct_Permission(lua_State* tolua_S)
-{
- cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Permission'",NULL);
- if (!tolua_iscppstring(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->Permission = ((std::string) tolua_tocppstring(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: AddCommand of class cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_AddCommand00
-static int tolua_AllToLua_cPlugin_AddCommand00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- std::string a_Command = ((std::string) tolua_tocppstring(tolua_S,2,0));
- std::string a_Description = ((std::string) tolua_tocppstring(tolua_S,3,0));
- std::string a_Permission = ((std::string) tolua_tocppstring(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddCommand'", NULL);
-#endif
- {
- self->AddCommand(a_Command,a_Description,a_Permission);
- tolua_pushcppstring(tolua_S,(const char*)a_Command);
- tolua_pushcppstring(tolua_S,(const char*)a_Description);
- tolua_pushcppstring(tolua_S,(const char*)a_Permission);
- }
- }
- return 3;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'AddCommand'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
- class Lua__cPlugin : public cPlugin, public ToluaBase {
-public:
- void OnDisable( void ) {
- if (push_method("OnDisable", tolua_AllToLua_cPlugin_OnDisable00)) {
- ToluaBase::dbcall(lua_state, 1, 0);
- } else {
- return ( void ) cPlugin:: OnDisable();
- };
- };
- bool Initialize( void ) {
- if (push_method("Initialize", tolua_AllToLua_cPlugin_Initialize00)) {
- ToluaBase::dbcall(lua_state, 1, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- if (lua_state)
- LOG("pure-virtual method cPlugin::Initialize not implemented.");
- else {
- LOG("pure-virtual method cPlugin::Initialize called with no lua_state. Aborting");
- ::abort();
- };
- return ( bool )0;
- };
- };
- void Tick( float a_Dt) {
- if (push_method("Tick", tolua_AllToLua_cPlugin_Tick00)) {
- tolua_pushnumber(lua_state, (lua_Number)a_Dt);
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cPlugin:: Tick(a_Dt);
- };
- };
- bool OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) {
- if (push_method("OnCollectItem", tolua_AllToLua_cPlugin_OnCollectItem00)) {
- tolua_pushusertype(lua_state, (void*)a_Pickup, "cPickup");
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- ToluaBase::dbcall(lua_state, 3, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin:: OnCollectItem(a_Pickup,a_Player);
- };
- };
- bool OnDisconnect( const AString& a_Reason, cPlayer* a_Player) {
- if (push_method("OnDisconnect", tolua_AllToLua_cPlugin_OnDisconnect00)) {
- tolua_pushcppstring(lua_state, (const char*)a_Reason);
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- ToluaBase::dbcall(lua_state, 3, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin:: OnDisconnect(a_Reason,a_Player);
- };
- };
- bool OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) {
- if (push_method("OnBlockPlace", tolua_AllToLua_cPlugin_OnBlockPlace00)) {
- tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockPlace");
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- ToluaBase::dbcall(lua_state, 3, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin:: OnBlockPlace(a_PacketData,a_Player);
- };
- };
- bool OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) {
- if (push_method("OnBlockDig", tolua_AllToLua_cPlugin_OnBlockDig00)) {
- tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockDig");
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- tolua_pushusertype(lua_state, (void*)a_PickupItem, "cItem");
- ToluaBase::dbcall(lua_state, 4, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin:: OnBlockDig(a_PacketData,a_Player,a_PickupItem);
- };
- };
- bool OnChat( const char* a_Chat, cPlayer* a_Player) {
- if (push_method("OnChat", tolua_AllToLua_cPlugin_OnChat00)) {
- tolua_pushstring(lua_state, (const char*)a_Chat);
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- ToluaBase::dbcall(lua_state, 3, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin:: OnChat(a_Chat,a_Player);
- };
- };
- bool OnLogin( cPacket_Login* a_PacketData) {
- if (push_method("OnLogin", tolua_AllToLua_cPlugin_OnLogin00)) {
- tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_Login");
- ToluaBase::dbcall(lua_state, 2, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin:: OnLogin(a_PacketData);
- };
- };
- void OnPlayerSpawn( cPlayer* a_Player) {
- if (push_method("OnPlayerSpawn", tolua_AllToLua_cPlugin_OnPlayerSpawn00)) {
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cPlugin:: OnPlayerSpawn(a_Player);
- };
- };
- bool OnPlayerJoin( cPlayer* a_Player) {
- if (push_method("OnPlayerJoin", tolua_AllToLua_cPlugin_OnPlayerJoin00)) {
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- ToluaBase::dbcall(lua_state, 2, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin:: OnPlayerJoin(a_Player);
- };
- };
- void OnPlayerMove( cPlayer* a_Player) {
- if (push_method("OnPlayerMove", tolua_AllToLua_cPlugin_OnPlayerMove00)) {
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cPlugin:: OnPlayerMove(a_Player);
- };
- };
- void OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) {
- if (push_method("OnTakeDamage", tolua_AllToLua_cPlugin_OnTakeDamage00)) {
- tolua_pushusertype(lua_state, (void*)a_Pawn, "cPawn");
- tolua_pushusertype(lua_state, (void*)a_TakeDamageInfo, "TakeDamageInfo");
- ToluaBase::dbcall(lua_state, 3, 0);
- } else {
- return ( void ) cPlugin:: OnTakeDamage(a_Pawn,a_TakeDamageInfo);
- };
- };
- bool OnKilled( cPawn* a_Killed, cEntity* a_Killer) {
- if (push_method("OnKilled", tolua_AllToLua_cPlugin_OnKilled00)) {
- tolua_pushusertype(lua_state, (void*)a_Killed, "cPawn");
- tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity");
- ToluaBase::dbcall(lua_state, 3, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin:: OnKilled(a_Killed,a_Killer);
- };
- };
- void OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) {
- if (push_method("OnChunkGenerated", tolua_AllToLua_cPlugin_OnChunkGenerated00)) {
- tolua_pushusertype(lua_state, (void*)a_World, "cWorld");
- tolua_pushnumber(lua_state, (lua_Number)a_ChunkX);
- tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ);
- ToluaBase::dbcall(lua_state, 4, 0);
- } else {
- return ( void ) cPlugin:: OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ);
- };
- };
- bool OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) {
- if (push_method("OnChunkGenerating", tolua_AllToLua_cPlugin_OnChunkGenerating00)) {
- tolua_pushnumber(lua_state, (lua_Number)a_ChunkX);
- tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ);
- tolua_pushusertype(lua_state, (void*)a_pLuaChunk, "cLuaChunk");
- ToluaBase::dbcall(lua_state, 4, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin:: OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk);
- };
- };
- bool OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
- if (push_method("OnPreCrafting", tolua_AllToLua_cPlugin_OnPreCrafting00)) {
- tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer");
- tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid");
- tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe");
- ToluaBase::dbcall(lua_state, 4, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin:: OnPreCrafting(a_Player,a_Grid,a_Recipe);
- };
- };
- bool OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
- if (push_method("OnCraftingNoRecipe", tolua_AllToLua_cPlugin_OnCraftingNoRecipe00)) {
- tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer");
- tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid");
- tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe");
- ToluaBase::dbcall(lua_state, 4, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin:: OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe);
- };
- };
- bool OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
- if (push_method("OnPostCrafting", tolua_AllToLua_cPlugin_OnPostCrafting00)) {
- tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer");
- tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid");
- tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe");
- ToluaBase::dbcall(lua_state, 4, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin:: OnPostCrafting(a_Player,a_Grid,a_Recipe);
- };
- };
- bool OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) {
- if (push_method("OnBlockToPickup", tolua_AllToLua_cPlugin_OnBlockToPickup00)) {
- void* tolua_obj0 = (void*)new BLOCKTYPE(a_BlockType);
- tolua_pushusertype_and_takeownership(lua_state, tolua_obj0, "BLOCKTYPE");
- void* tolua_obj1 = (void*)new NIBBLETYPE(a_BlockMeta);
- tolua_pushusertype_and_takeownership(lua_state, tolua_obj1, "NIBBLETYPE");
- tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer");
- tolua_pushusertype(lua_state, (void*)&a_EquippedItem, "const cItem");
- tolua_pushusertype(lua_state, (void*)&a_Pickups, "cItems");
- ToluaBase::dbcall(lua_state, 6, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin:: OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups);
- };
- };
-
- void cPlugin__OnDisable( void ) {
- return ( void )cPlugin::OnDisable();
- };
- void cPlugin__Tick( float a_Dt) {
- return ( void )cPlugin::Tick(a_Dt);
- };
- bool cPlugin__OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) {
- return ( bool )cPlugin::OnCollectItem(a_Pickup,a_Player);
- };
- bool cPlugin__OnDisconnect( const AString& a_Reason, cPlayer* a_Player) {
- return ( bool )cPlugin::OnDisconnect(a_Reason,a_Player);
- };
- bool cPlugin__OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) {
- return ( bool )cPlugin::OnBlockPlace(a_PacketData,a_Player);
- };
- bool cPlugin__OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) {
- return ( bool )cPlugin::OnBlockDig(a_PacketData,a_Player,a_PickupItem);
- };
- bool cPlugin__OnChat( const char* a_Chat, cPlayer* a_Player) {
- return ( bool )cPlugin::OnChat(a_Chat,a_Player);
- };
- bool cPlugin__OnLogin( cPacket_Login* a_PacketData) {
- return ( bool )cPlugin::OnLogin(a_PacketData);
- };
- void cPlugin__OnPlayerSpawn( cPlayer* a_Player) {
- return ( void )cPlugin::OnPlayerSpawn(a_Player);
- };
- bool cPlugin__OnPlayerJoin( cPlayer* a_Player) {
- return ( bool )cPlugin::OnPlayerJoin(a_Player);
- };
- void cPlugin__OnPlayerMove( cPlayer* a_Player) {
- return ( void )cPlugin::OnPlayerMove(a_Player);
- };
- void cPlugin__OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) {
- return ( void )cPlugin::OnTakeDamage(a_Pawn,a_TakeDamageInfo);
- };
- bool cPlugin__OnKilled( cPawn* a_Killed, cEntity* a_Killer) {
- return ( bool )cPlugin::OnKilled(a_Killed,a_Killer);
- };
- void cPlugin__OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) {
- return ( void )cPlugin::OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ);
- };
- bool cPlugin__OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) {
- return ( bool )cPlugin::OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk);
- };
- bool cPlugin__OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
- return ( bool )cPlugin::OnPreCrafting(a_Player,a_Grid,a_Recipe);
- };
- bool cPlugin__OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
- return ( bool )cPlugin::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe);
- };
- bool cPlugin__OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
- return ( bool )cPlugin::OnPostCrafting(a_Player,a_Grid,a_Recipe);
- };
- bool cPlugin__OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) {
- return ( bool )cPlugin::OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups);
- };
- Lua__cPlugin( void ): cPlugin(){};
-};
-
-/* method: tolua__set_instance of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_tolua__set_instance00
-static int tolua_AllToLua_Lua__cPlugin_tolua__set_instance00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- lua_State* L = tolua_S;
- lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL);
-#endif
- {
- self->tolua__set_instance(L,lo);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnDisable of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisable00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisable00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnDisable'", NULL);
-#endif
- {
- self->cPlugin__OnDisable();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnDisable'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__Tick of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__Tick00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__Tick00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- float a_Dt = ((float) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__Tick'", NULL);
-#endif
- {
- self->cPlugin__Tick(a_Dt);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__Tick'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnCollectItem of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnCollectItem00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnCollectItem00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPickup",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPickup* a_Pickup = ((cPickup*) tolua_tousertype(tolua_S,2,0));
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnCollectItem'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPlugin__OnCollectItem(a_Pickup,a_Player);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnCollectItem'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnDisconnect of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0));
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnDisconnect'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPlugin__OnDisconnect(a_Reason,a_Player);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)a_Reason);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnDisconnect'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnBlockPlace of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockPlace00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockPlace00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPacket_BlockPlace",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPacket_BlockPlace* a_PacketData = ((cPacket_BlockPlace*) tolua_tousertype(tolua_S,2,0));
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnBlockPlace'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPlugin__OnBlockPlace(a_PacketData,a_Player);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnBlockPlace'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnBlockDig of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockDig00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockDig00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPacket_BlockDig",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,4,"cItem",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPacket_BlockDig* a_PacketData = ((cPacket_BlockDig*) tolua_tousertype(tolua_S,2,0));
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
- cItem* a_PickupItem = ((cItem*) tolua_tousertype(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnBlockDig'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPlugin__OnBlockDig(a_PacketData,a_Player,a_PickupItem);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnBlockDig'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnChat of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- const char* a_Chat = ((const char*) tolua_tostring(tolua_S,2,0));
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnChat'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPlugin__OnChat(a_Chat,a_Player);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnChat'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnLogin of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnLogin00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnLogin00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPacket_Login",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPacket_Login* a_PacketData = ((cPacket_Login*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnLogin'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPlugin__OnLogin(a_PacketData);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnLogin'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnPlayerSpawn of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerSpawn00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerSpawn00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPlayerSpawn'", NULL);
-#endif
- {
- self->cPlugin__OnPlayerSpawn(a_Player);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPlayerSpawn'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnPlayerJoin of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerJoin00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerJoin00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPlayerJoin'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPlugin__OnPlayerJoin(a_Player);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPlayerJoin'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnPlayerMove of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerMove00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerMove00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPlayerMove'", NULL);
-#endif
- {
- self->cPlugin__OnPlayerMove(a_Player);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPlayerMove'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnTakeDamage of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnTakeDamage00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnTakeDamage00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"TakeDamageInfo",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPawn* a_Pawn = ((cPawn*) tolua_tousertype(tolua_S,2,0));
- TakeDamageInfo* a_TakeDamageInfo = ((TakeDamageInfo*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnTakeDamage'", NULL);
-#endif
- {
- self->cPlugin__OnTakeDamage(a_Pawn,a_TakeDamageInfo);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnTakeDamage'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnKilled of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnKilled00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnKilled00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPawn* a_Killed = ((cPawn*) tolua_tousertype(tolua_S,2,0));
- cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnKilled'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPlugin__OnKilled(a_Killed,a_Killer);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnKilled'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnChunkGenerated of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerated00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerated00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0));
- int a_ChunkX = ((int) tolua_tonumber(tolua_S,3,0));
- int a_ChunkZ = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnChunkGenerated'", NULL);
-#endif
- {
- self->cPlugin__OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnChunkGenerated'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnChunkGenerating of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerating00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerating00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isusertype(tolua_S,4,"cLuaChunk",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0));
- int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0));
- cLuaChunk* a_pLuaChunk = ((cLuaChunk*) tolua_tousertype(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnChunkGenerating'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPlugin__OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnChunkGenerating'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnPreCrafting of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPreCrafting00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPreCrafting00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0));
- const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0));
- cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPreCrafting'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPlugin__OnPreCrafting(a_Player,a_Grid,a_Recipe);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPreCrafting'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnCraftingNoRecipe of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnCraftingNoRecipe00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnCraftingNoRecipe00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0));
- const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0));
- cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnCraftingNoRecipe'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPlugin__OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnCraftingNoRecipe'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnPostCrafting of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPostCrafting00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPostCrafting00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0));
- const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0));
- cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPostCrafting'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPlugin__OnPostCrafting(a_Player,a_Grid,a_Recipe);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPostCrafting'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin__OnBlockToPickup of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockToPickup00
-static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockToPickup00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"BLOCKTYPE",0,&tolua_err)) ||
- (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"NIBBLETYPE",0,&tolua_err)) ||
- !tolua_isusertype(tolua_S,4,"const cPlayer",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) ||
- (tolua_isvaluenil(tolua_S,6,&tolua_err) || !tolua_isusertype(tolua_S,6,"cItems",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,7,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- BLOCKTYPE a_BlockType = *((BLOCKTYPE*) tolua_tousertype(tolua_S,2,0));
- NIBBLETYPE a_BlockMeta = *((NIBBLETYPE*) tolua_tousertype(tolua_S,3,0));
- const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,4,0));
- const cItem* a_EquippedItem = ((const cItem*) tolua_tousertype(tolua_S,5,0));
- cItems* a_Pickups = ((cItems*) tolua_tousertype(tolua_S,6,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnBlockToPickup'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPlugin__OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,*a_EquippedItem,*a_Pickups);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin__OnBlockToPickup'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_new00
-static int tolua_AllToLua_Lua__cPlugin_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- Lua__cPlugin* tolua_ret = (Lua__cPlugin*) Mtolua_new((Lua__cPlugin)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPlugin");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_new00_local
-static int tolua_AllToLua_Lua__cPlugin_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- Lua__cPlugin* tolua_ret = (Lua__cPlugin*) Mtolua_new((Lua__cPlugin)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPlugin");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: delete of class Lua__cPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_delete00
-static int tolua_AllToLua_Lua__cPlugin_delete00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL);
-#endif
- Mtolua_delete(self);
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-
-/* function to release collected object via destructor */
-#ifdef __cplusplus
-
-static int tolua_collect_Lua__cPlugin (lua_State* tolua_S)
-{
- Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
- delete self;
- return 0;
-}
-#endif
-
-/* method: OnDisable of class cPlugin_NewLua */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_OnDisable00
-static int tolua_AllToLua_cPlugin_NewLua_OnDisable00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisable'", NULL);
-#endif
- {
- self->OnDisable();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'OnDisable'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Initialize of class cPlugin_NewLua */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_Initialize00
-static int tolua_AllToLua_cPlugin_NewLua_Initialize00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->Initialize();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Tick of class cPlugin_NewLua */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_Tick00
-static int tolua_AllToLua_cPlugin_NewLua_Tick00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0);
- float a_Dt = ((float) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Tick'", NULL);
-#endif
- {
- self->Tick(a_Dt);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Tick'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: CreateWebPlugin of class cPlugin_NewLua */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_CreateWebPlugin00
-static int tolua_AllToLua_cPlugin_NewLua_CreateWebPlugin00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0);
- lua_State* a_LuaState = tolua_S;
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CreateWebPlugin'", NULL);
-#endif
- {
- cWebPlugin_Lua* tolua_ret = (cWebPlugin_Lua*) self->CreateWebPlugin(a_LuaState);
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWebPlugin_Lua");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'CreateWebPlugin'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
- class Lua__cPlugin_NewLua : public cPlugin_NewLua, public ToluaBase {
-public:
- void OnDisable( void ) {
- if (push_method("OnDisable", tolua_AllToLua_cPlugin_NewLua_OnDisable00)) {
- ToluaBase::dbcall(lua_state, 1, 0);
- } else {
- return ( void ) cPlugin_NewLua:: OnDisable();
- };
- };
- bool Initialize( void ) {
- if (push_method("Initialize", tolua_AllToLua_cPlugin_NewLua_Initialize00)) {
- ToluaBase::dbcall(lua_state, 1, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin_NewLua:: Initialize();
- };
- };
- void Tick( float a_Dt) {
- if (push_method("Tick", tolua_AllToLua_cPlugin_NewLua_Tick00)) {
- tolua_pushnumber(lua_state, (lua_Number)a_Dt);
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cPlugin_NewLua:: Tick(a_Dt);
- };
- };
- bool OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) {
- if (push_method("OnCollectItem", tolua_AllToLua_cPlugin_OnCollectItem00)) {
- tolua_pushusertype(lua_state, (void*)a_Pickup, "cPickup");
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- ToluaBase::dbcall(lua_state, 3, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin_NewLua:: OnCollectItem(a_Pickup,a_Player);
- };
- };
- bool OnDisconnect( const AString& a_Reason, cPlayer* a_Player) {
- if (push_method("OnDisconnect", tolua_AllToLua_cPlugin_OnDisconnect00)) {
- tolua_pushcppstring(lua_state, (const char*)a_Reason);
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- ToluaBase::dbcall(lua_state, 3, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin_NewLua:: OnDisconnect(a_Reason,a_Player);
- };
- };
- bool OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) {
- if (push_method("OnBlockPlace", tolua_AllToLua_cPlugin_OnBlockPlace00)) {
- tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockPlace");
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- ToluaBase::dbcall(lua_state, 3, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin_NewLua:: OnBlockPlace(a_PacketData,a_Player);
- };
- };
- bool OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) {
- if (push_method("OnBlockDig", tolua_AllToLua_cPlugin_OnBlockDig00)) {
- tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockDig");
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- tolua_pushusertype(lua_state, (void*)a_PickupItem, "cItem");
- ToluaBase::dbcall(lua_state, 4, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin_NewLua:: OnBlockDig(a_PacketData,a_Player,a_PickupItem);
- };
- };
- bool OnChat( const char* a_Chat, cPlayer* a_Player) {
- if (push_method("OnChat", tolua_AllToLua_cPlugin_OnChat00)) {
- tolua_pushstring(lua_state, (const char*)a_Chat);
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- ToluaBase::dbcall(lua_state, 3, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin_NewLua:: OnChat(a_Chat,a_Player);
- };
- };
- bool OnLogin( cPacket_Login* a_PacketData) {
- if (push_method("OnLogin", tolua_AllToLua_cPlugin_OnLogin00)) {
- tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_Login");
- ToluaBase::dbcall(lua_state, 2, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin_NewLua:: OnLogin(a_PacketData);
- };
- };
- void OnPlayerSpawn( cPlayer* a_Player) {
- if (push_method("OnPlayerSpawn", tolua_AllToLua_cPlugin_OnPlayerSpawn00)) {
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cPlugin_NewLua:: OnPlayerSpawn(a_Player);
- };
- };
- bool OnPlayerJoin( cPlayer* a_Player) {
- if (push_method("OnPlayerJoin", tolua_AllToLua_cPlugin_OnPlayerJoin00)) {
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- ToluaBase::dbcall(lua_state, 2, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin_NewLua:: OnPlayerJoin(a_Player);
- };
- };
- void OnPlayerMove( cPlayer* a_Player) {
- if (push_method("OnPlayerMove", tolua_AllToLua_cPlugin_OnPlayerMove00)) {
- tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cPlugin_NewLua:: OnPlayerMove(a_Player);
- };
- };
- void OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) {
- if (push_method("OnTakeDamage", tolua_AllToLua_cPlugin_OnTakeDamage00)) {
- tolua_pushusertype(lua_state, (void*)a_Pawn, "cPawn");
- tolua_pushusertype(lua_state, (void*)a_TakeDamageInfo, "TakeDamageInfo");
- ToluaBase::dbcall(lua_state, 3, 0);
- } else {
- return ( void ) cPlugin_NewLua:: OnTakeDamage(a_Pawn,a_TakeDamageInfo);
- };
- };
- bool OnKilled( cPawn* a_Killed, cEntity* a_Killer) {
- if (push_method("OnKilled", tolua_AllToLua_cPlugin_OnKilled00)) {
- tolua_pushusertype(lua_state, (void*)a_Killed, "cPawn");
- tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity");
- ToluaBase::dbcall(lua_state, 3, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin_NewLua:: OnKilled(a_Killed,a_Killer);
- };
- };
- void OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) {
- if (push_method("OnChunkGenerated", tolua_AllToLua_cPlugin_OnChunkGenerated00)) {
- tolua_pushusertype(lua_state, (void*)a_World, "cWorld");
- tolua_pushnumber(lua_state, (lua_Number)a_ChunkX);
- tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ);
- ToluaBase::dbcall(lua_state, 4, 0);
- } else {
- return ( void ) cPlugin_NewLua:: OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ);
- };
- };
- bool OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) {
- if (push_method("OnChunkGenerating", tolua_AllToLua_cPlugin_OnChunkGenerating00)) {
- tolua_pushnumber(lua_state, (lua_Number)a_ChunkX);
- tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ);
- tolua_pushusertype(lua_state, (void*)a_pLuaChunk, "cLuaChunk");
- ToluaBase::dbcall(lua_state, 4, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin_NewLua:: OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk);
- };
- };
- bool OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
- if (push_method("OnPreCrafting", tolua_AllToLua_cPlugin_OnPreCrafting00)) {
- tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer");
- tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid");
- tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe");
- ToluaBase::dbcall(lua_state, 4, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin_NewLua:: OnPreCrafting(a_Player,a_Grid,a_Recipe);
- };
- };
- bool OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
- if (push_method("OnCraftingNoRecipe", tolua_AllToLua_cPlugin_OnCraftingNoRecipe00)) {
- tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer");
- tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid");
- tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe");
- ToluaBase::dbcall(lua_state, 4, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin_NewLua:: OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe);
- };
- };
- bool OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
- if (push_method("OnPostCrafting", tolua_AllToLua_cPlugin_OnPostCrafting00)) {
- tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer");
- tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid");
- tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe");
- ToluaBase::dbcall(lua_state, 4, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin_NewLua:: OnPostCrafting(a_Player,a_Grid,a_Recipe);
- };
- };
- bool OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) {
- if (push_method("OnBlockToPickup", tolua_AllToLua_cPlugin_OnBlockToPickup00)) {
- void* tolua_obj0 = (void*)new BLOCKTYPE(a_BlockType);
- tolua_pushusertype_and_takeownership(lua_state, tolua_obj0, "BLOCKTYPE");
- void* tolua_obj1 = (void*)new NIBBLETYPE(a_BlockMeta);
- tolua_pushusertype_and_takeownership(lua_state, tolua_obj1, "NIBBLETYPE");
- tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer");
- tolua_pushusertype(lua_state, (void*)&a_EquippedItem, "const cItem");
- tolua_pushusertype(lua_state, (void*)&a_Pickups, "cItems");
- ToluaBase::dbcall(lua_state, 6, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPlugin_NewLua:: OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups);
- };
- };
-
- void cPlugin_NewLua__OnDisable( void ) {
- return ( void )cPlugin_NewLua::OnDisable();
- };
- bool cPlugin_NewLua__Initialize( void ) {
- return ( bool )cPlugin_NewLua::Initialize();
- };
- void cPlugin_NewLua__Tick( float a_Dt) {
- return ( void )cPlugin_NewLua::Tick(a_Dt);
- };
- bool cPlugin_NewLua__OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) {
- return ( bool )cPlugin_NewLua::OnCollectItem(a_Pickup,a_Player);
- };
- bool cPlugin_NewLua__OnDisconnect( const AString& a_Reason, cPlayer* a_Player) {
- return ( bool )cPlugin_NewLua::OnDisconnect(a_Reason,a_Player);
- };
- bool cPlugin_NewLua__OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) {
- return ( bool )cPlugin_NewLua::OnBlockPlace(a_PacketData,a_Player);
- };
- bool cPlugin_NewLua__OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) {
- return ( bool )cPlugin_NewLua::OnBlockDig(a_PacketData,a_Player,a_PickupItem);
- };
- bool cPlugin_NewLua__OnChat( const char* a_Chat, cPlayer* a_Player) {
- return ( bool )cPlugin_NewLua::OnChat(a_Chat,a_Player);
- };
- bool cPlugin_NewLua__OnLogin( cPacket_Login* a_PacketData) {
- return ( bool )cPlugin_NewLua::OnLogin(a_PacketData);
- };
- void cPlugin_NewLua__OnPlayerSpawn( cPlayer* a_Player) {
- return ( void )cPlugin_NewLua::OnPlayerSpawn(a_Player);
- };
- bool cPlugin_NewLua__OnPlayerJoin( cPlayer* a_Player) {
- return ( bool )cPlugin_NewLua::OnPlayerJoin(a_Player);
- };
- void cPlugin_NewLua__OnPlayerMove( cPlayer* a_Player) {
- return ( void )cPlugin_NewLua::OnPlayerMove(a_Player);
- };
- void cPlugin_NewLua__OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) {
- return ( void )cPlugin_NewLua::OnTakeDamage(a_Pawn,a_TakeDamageInfo);
- };
- bool cPlugin_NewLua__OnKilled( cPawn* a_Killed, cEntity* a_Killer) {
- return ( bool )cPlugin_NewLua::OnKilled(a_Killed,a_Killer);
- };
- void cPlugin_NewLua__OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) {
- return ( void )cPlugin_NewLua::OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ);
- };
- bool cPlugin_NewLua__OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) {
- return ( bool )cPlugin_NewLua::OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk);
- };
- bool cPlugin_NewLua__OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
- return ( bool )cPlugin_NewLua::OnPreCrafting(a_Player,a_Grid,a_Recipe);
- };
- bool cPlugin_NewLua__OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
- return ( bool )cPlugin_NewLua::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe);
- };
- bool cPlugin_NewLua__OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
- return ( bool )cPlugin_NewLua::OnPostCrafting(a_Player,a_Grid,a_Recipe);
- };
- bool cPlugin_NewLua__OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) {
- return ( bool )cPlugin_NewLua::OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups);
- };
-};
-
-/* method: tolua__set_instance of class Lua__cPlugin_NewLua */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_tolua__set_instance00
-static int tolua_AllToLua_Lua__cPlugin_NewLua_tolua__set_instance00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0);
- lua_State* L = tolua_S;
- lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL);
-#endif
- {
- self->tolua__set_instance(L,lo);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin_NewLua__OnDisable of class Lua__cPlugin_NewLua */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__OnDisable00
-static int tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__OnDisable00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin_NewLua__OnDisable'", NULL);
-#endif
- {
- self->cPlugin_NewLua__OnDisable();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin_NewLua__OnDisable'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin_NewLua__Initialize of class Lua__cPlugin_NewLua */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Initialize00
-static int tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Initialize00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin_NewLua__Initialize'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPlugin_NewLua__Initialize();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin_NewLua__Initialize'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPlugin_NewLua__Tick of class Lua__cPlugin_NewLua */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Tick00
-static int tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Tick00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0);
- float a_Dt = ((float) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin_NewLua__Tick'", NULL);
-#endif
- {
- self->cPlugin_NewLua__Tick(a_Dt);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPlugin_NewLua__Tick'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetFileName of class cPlugin_Lua */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_Lua_GetFileName00
-static int tolua_AllToLua_cPlugin_Lua_GetFileName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPlugin_Lua",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPlugin_Lua* self = (cPlugin_Lua*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFileName'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->GetFileName();
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetFileName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetServer of class cServer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_GetServer00
-static int tolua_AllToLua_cServer_GetServer00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cServer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- cServer* tolua_ret = (cServer*) cServer::GetServer();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cServer");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetServer'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: ServerCommand of class cServer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_ServerCommand00
-static int tolua_AllToLua_cServer_ServerCommand00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cServer",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cServer* self = (cServer*) tolua_tousertype(tolua_S,1,0);
- const char* a_Cmd = ((const char*) tolua_tostring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ServerCommand'", NULL);
-#endif
- {
- self->ServerCommand(a_Cmd);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'ServerCommand'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SendMessage of class cServer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_SendMessage00
-static int tolua_AllToLua_cServer_SendMessage00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cServer",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isusertype(tolua_S,3,"cPlayer",1,&tolua_err) ||
- !tolua_isboolean(tolua_S,4,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cServer* self = (cServer*) tolua_tousertype(tolua_S,1,0);
- const char* a_Message = ((const char*) tolua_tostring(tolua_S,2,0));
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
- bool a_bExclude = ((bool) tolua_toboolean(tolua_S,4,false));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL);
-#endif
- {
- self->SendMessage(a_Message,a_Player,a_bExclude);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetTime of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetTime00
-static int tolua_AllToLua_cWorld_GetTime00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- float tolua_ret = (float) cWorld::GetTime();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetTime'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetGameMode of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetGameMode00
-static int tolua_AllToLua_cWorld_GetGameMode00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGameMode'", NULL);
-#endif
- {
- eGameMode tolua_ret = (eGameMode) self->GetGameMode();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetGameMode'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetWorldTime of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetWorldTime00
-static int tolua_AllToLua_cWorld_SetWorldTime00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- long long a_WorldTime = ((long long) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetWorldTime'", NULL);
-#endif
- {
- self->SetWorldTime(a_WorldTime);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetWorldTime'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetHeight of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetHeight00
-static int tolua_AllToLua_cWorld_GetHeight00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHeight'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetHeight(a_X,a_Z);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetHeight'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: UnloadUnusedChunks of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_UnloadUnusedChunks00
-static int tolua_AllToLua_cWorld_UnloadUnusedChunks00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'UnloadUnusedChunks'", NULL);
-#endif
- {
- self->UnloadUnusedChunks();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'UnloadUnusedChunks'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetMaxPlayers of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetMaxPlayers00
-static int tolua_AllToLua_cWorld_GetMaxPlayers00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxPlayers'", NULL);
-#endif
- {
- unsigned int tolua_ret = (unsigned int) self->GetMaxPlayers();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetMaxPlayers'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetMaxPlayers of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetMaxPlayers00
-static int tolua_AllToLua_cWorld_SetMaxPlayers00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int iMax = ((int) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetMaxPlayers'", NULL);
-#endif
- {
- self->SetMaxPlayers(iMax);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetMaxPlayers'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetNumPlayers of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetNumPlayers00
-static int tolua_AllToLua_cWorld_GetNumPlayers00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumPlayers'", NULL);
-#endif
- {
- unsigned int tolua_ret = (unsigned int) self->GetNumPlayers();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetNumPlayers'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetPlayer of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetPlayer00
-static int tolua_AllToLua_cWorld_GetPlayer00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- const char* a_PlayerName = ((const char*) tolua_tostring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPlayer'", NULL);
-#endif
- {
- cPlayer* tolua_ret = (cPlayer*) self->GetPlayer(a_PlayerName);
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlayer");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetPlayer'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: UpdateSign of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_UpdateSign00
-static int tolua_AllToLua_cWorld_UpdateSign00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,5,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,6,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,7,0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,8,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,9,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
- const AString a_Line1 = ((const AString) tolua_tocppstring(tolua_S,5,0));
- const AString a_Line2 = ((const AString) tolua_tocppstring(tolua_S,6,0));
- const AString a_Line3 = ((const AString) tolua_tocppstring(tolua_S,7,0));
- const AString a_Line4 = ((const AString) tolua_tocppstring(tolua_S,8,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'UpdateSign'", NULL);
-#endif
- {
- self->UpdateSign(a_X,a_Y,a_Z,a_Line1,a_Line2,a_Line3,a_Line4);
- tolua_pushcppstring(tolua_S,(const char*)a_Line1);
- tolua_pushcppstring(tolua_S,(const char*)a_Line2);
- tolua_pushcppstring(tolua_S,(const char*)a_Line3);
- tolua_pushcppstring(tolua_S,(const char*)a_Line4);
- }
- }
- return 4;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'UpdateSign'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: RegenerateChunk of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_RegenerateChunk00
-static int tolua_AllToLua_cWorld_RegenerateChunk00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0));
- int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RegenerateChunk'", NULL);
-#endif
- {
- self->RegenerateChunk(a_ChunkX,a_ChunkZ);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'RegenerateChunk'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GenerateChunk of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GenerateChunk00
-static int tolua_AllToLua_cWorld_GenerateChunk00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0));
- int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GenerateChunk'", NULL);
-#endif
- {
- self->GenerateChunk(a_ChunkX,a_ChunkZ);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GenerateChunk'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetBlock of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetBlock00
-static int tolua_AllToLua_cWorld_SetBlock00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,5,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,6,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,7,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
- char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0));
- char a_BlockMeta = ((char) tolua_tonumber(tolua_S,6,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlock'", NULL);
-#endif
- {
- self->SetBlock(a_X,a_Y,a_Z,a_BlockType,a_BlockMeta);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetBlock'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: FastSetBlock of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_FastSetBlock00
-static int tolua_AllToLua_cWorld_FastSetBlock00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,5,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,6,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,7,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
- char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0));
- char a_BlockMeta = ((char) tolua_tonumber(tolua_S,6,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FastSetBlock'", NULL);
-#endif
- {
- self->FastSetBlock(a_X,a_Y,a_Z,a_BlockType,a_BlockMeta);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'FastSetBlock'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetBlock of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlock00
-static int tolua_AllToLua_cWorld_GetBlock00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlock'", NULL);
-#endif
- {
- char tolua_ret = (char) self->GetBlock(a_X,a_Y,a_Z);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetBlock'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetBlock of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlock01
-static int tolua_AllToLua_cWorld_GetBlock01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- const Vector3i* a_Pos = ((const Vector3i*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlock'", NULL);
-#endif
- {
- char tolua_ret = (char) self->GetBlock(*a_Pos);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cWorld_GetBlock00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetBlockMeta of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockMeta00
-static int tolua_AllToLua_cWorld_GetBlockMeta00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockMeta'", NULL);
-#endif
- {
- char tolua_ret = (char) self->GetBlockMeta(a_X,a_Y,a_Z);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetBlockMeta'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetBlockMeta of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockMeta01
-static int tolua_AllToLua_cWorld_GetBlockMeta01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- const Vector3i* a_Pos = ((const Vector3i*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockMeta'", NULL);
-#endif
- {
- char tolua_ret = (char) self->GetBlockMeta(*a_Pos);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cWorld_GetBlockMeta00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetBlockMeta of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetBlockMeta00
-static int tolua_AllToLua_cWorld_SetBlockMeta00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,5,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,6,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
- char a_MetaData = ((char) tolua_tonumber(tolua_S,5,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlockMeta'", NULL);
-#endif
- {
- self->SetBlockMeta(a_X,a_Y,a_Z,a_MetaData);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetBlockMeta'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetBlockMeta of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetBlockMeta01
-static int tolua_AllToLua_cWorld_SetBlockMeta01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- const Vector3i* a_Pos = ((const Vector3i*) tolua_tousertype(tolua_S,2,0));
- char a_MetaData = ((char) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlockMeta'", NULL);
-#endif
- {
- self->SetBlockMeta(*a_Pos,a_MetaData);
- }
- }
- return 0;
-tolua_lerror:
- return tolua_AllToLua_cWorld_SetBlockMeta00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetBlockSkyLight of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockSkyLight00
-static int tolua_AllToLua_cWorld_GetBlockSkyLight00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockSkyLight'", NULL);
-#endif
- {
- char tolua_ret = (char) self->GetBlockSkyLight(a_X,a_Y,a_Z);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetBlockSkyLight'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetBlockTypeMeta of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockTypeMeta00
-static int tolua_AllToLua_cWorld_GetBlockTypeMeta00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,5,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,6,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,7,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0));
- int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0));
- int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0));
- char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0));
- unsigned char a_BlockMeta = ((unsigned char) tolua_tonumber(tolua_S,6,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockTypeMeta'", NULL);
-#endif
- {
- self->GetBlockTypeMeta(a_BlockX,a_BlockY,a_BlockZ,a_BlockType,a_BlockMeta);
- tolua_pushnumber(tolua_S,(lua_Number)a_BlockType);
- tolua_pushnumber(tolua_S,(lua_Number)a_BlockMeta);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetBlockTypeMeta'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: DigBlock of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_DigBlock00
-static int tolua_AllToLua_cWorld_DigBlock00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DigBlock'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->DigBlock(a_X,a_Y,a_Z);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'DigBlock'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SendBlockTo of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SendBlockTo00
-static int tolua_AllToLua_cWorld_SendBlockTo00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isusertype(tolua_S,5,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,6,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
- cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,5,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendBlockTo'", NULL);
-#endif
- {
- self->SendBlockTo(a_X,a_Y,a_Z,a_Player);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SendBlockTo'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetSpawnX of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSpawnX00
-static int tolua_AllToLua_cWorld_GetSpawnX00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSpawnX'", NULL);
-#endif
- {
- const double tolua_ret = (const double) self->GetSpawnX();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetSpawnX'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetSpawnY of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSpawnY00
-static int tolua_AllToLua_cWorld_GetSpawnY00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSpawnY'", NULL);
-#endif
- {
- const double tolua_ret = (const double) self->GetSpawnY();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetSpawnY'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetSpawnZ of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSpawnZ00
-static int tolua_AllToLua_cWorld_GetSpawnZ00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSpawnZ'", NULL);
-#endif
- {
- const double tolua_ret = (const double) self->GetSpawnZ();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetSpawnZ'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetBlockEntity of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockEntity00
-static int tolua_AllToLua_cWorld_GetBlockEntity00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockEntity'", NULL);
-#endif
- {
- OBSOLETE cBlockEntity* tolua_ret = (OBSOLETE cBlockEntity*) self->GetBlockEntity(a_X,a_Y,a_Z);
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cBlockEntity");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetBlockEntity'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GrowTree of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowTree00
-static int tolua_AllToLua_cWorld_GrowTree00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0));
- int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0));
- int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowTree'", NULL);
-#endif
- {
- self->GrowTree(a_BlockX,a_BlockY,a_BlockZ);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GrowTree'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GrowTreeFromSapling of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowTreeFromSapling00
-static int tolua_AllToLua_cWorld_GrowTreeFromSapling00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,5,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,6,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0));
- int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0));
- int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0));
- char a_SaplingMeta = ((char) tolua_tonumber(tolua_S,5,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowTreeFromSapling'", NULL);
-#endif
- {
- self->GrowTreeFromSapling(a_BlockX,a_BlockY,a_BlockZ,a_SaplingMeta);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GrowTreeFromSapling'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GrowTreeByBiome of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowTreeByBiome00
-static int tolua_AllToLua_cWorld_GrowTreeByBiome00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0));
- int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0));
- int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowTreeByBiome'", NULL);
-#endif
- {
- self->GrowTreeByBiome(a_BlockX,a_BlockY,a_BlockZ);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GrowTreeByBiome'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GrowPlant of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowPlant00
-static int tolua_AllToLua_cWorld_GrowPlant00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isboolean(tolua_S,5,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,6,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0));
- int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0));
- int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0));
- bool a_IsByBonemeal = ((bool) tolua_toboolean(tolua_S,5,false));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowPlant'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->GrowPlant(a_BlockX,a_BlockY,a_BlockZ,a_IsByBonemeal);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GrowPlant'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GrowMelonPumpkin of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowMelonPumpkin00
-static int tolua_AllToLua_cWorld_GrowMelonPumpkin00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,5,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,6,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0));
- int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0));
- int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0));
- char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowMelonPumpkin'", NULL);
-#endif
- {
- self->GrowMelonPumpkin(a_BlockX,a_BlockY,a_BlockZ,a_BlockType);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GrowMelonPumpkin'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetBiomeAt of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBiomeAt00
-static int tolua_AllToLua_cWorld_GetBiomeAt00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0));
- int a_BlockZ = ((int) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBiomeAt'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetBiomeAt(a_BlockX,a_BlockZ);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetBiomeAt'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetName of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetName00
-static int tolua_AllToLua_cWorld_GetName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL);
-#endif
- {
- const AString tolua_ret = (const AString) self->GetName();
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SaveAllChunks of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SaveAllChunks00
-static int tolua_AllToLua_cWorld_SaveAllChunks00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SaveAllChunks'", NULL);
-#endif
- {
- self->SaveAllChunks();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SaveAllChunks'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetNumChunks of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetNumChunks00
-static int tolua_AllToLua_cWorld_GetNumChunks00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumChunks'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetNumChunks();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetNumChunks'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetGeneratorQueueLength of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetGeneratorQueueLength00
-static int tolua_AllToLua_cWorld_GetGeneratorQueueLength00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGeneratorQueueLength'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetGeneratorQueueLength();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetGeneratorQueueLength'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetLightingQueueLength of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetLightingQueueLength00
-static int tolua_AllToLua_cWorld_GetLightingQueueLength00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLightingQueueLength'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetLightingQueueLength();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetLightingQueueLength'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetStorageLoadQueueLength of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetStorageLoadQueueLength00
-static int tolua_AllToLua_cWorld_GetStorageLoadQueueLength00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStorageLoadQueueLength'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetStorageLoadQueueLength();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetStorageLoadQueueLength'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetStorageSaveQueueLength of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetStorageSaveQueueLength00
-static int tolua_AllToLua_cWorld_GetStorageSaveQueueLength00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStorageSaveQueueLength'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetStorageSaveQueueLength();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetStorageSaveQueueLength'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: CastThunderbolt of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_CastThunderbolt00
-static int tolua_AllToLua_cWorld_CastThunderbolt00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CastThunderbolt'", NULL);
-#endif
- {
- self->CastThunderbolt(a_X,a_Y,a_Z);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'CastThunderbolt'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetWeather of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetWeather00
-static int tolua_AllToLua_cWorld_SetWeather00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- eWeather a_Weather = ((eWeather) (int) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetWeather'", NULL);
-#endif
- {
- self->SetWeather(a_Weather);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetWeather'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: ChangeWeather of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_ChangeWeather00
-static int tolua_AllToLua_cWorld_ChangeWeather00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ChangeWeather'", NULL);
-#endif
- {
- self->ChangeWeather();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'ChangeWeather'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetWeather of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetWeather00
-static int tolua_AllToLua_cWorld_GetWeather00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWeather'", NULL);
-#endif
- {
- eWeather tolua_ret = (eWeather) self->GetWeather();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetWeather'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetNextBlockTick of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetNextBlockTick00
-static int tolua_AllToLua_cWorld_SetNextBlockTick00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0));
- int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0));
- int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetNextBlockTick'", NULL);
-#endif
- {
- self->SetNextBlockTick(a_BlockX,a_BlockY,a_BlockZ);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetNextBlockTick'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetMaxSugarcaneHeight of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetMaxSugarcaneHeight00
-static int tolua_AllToLua_cWorld_GetMaxSugarcaneHeight00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxSugarcaneHeight'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetMaxSugarcaneHeight();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetMaxSugarcaneHeight'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetMaxCactusHeight of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetMaxCactusHeight00
-static int tolua_AllToLua_cWorld_GetMaxCactusHeight00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxCactusHeight'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetMaxCactusHeight();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetMaxCactusHeight'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Clear of class cInventory */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_Clear00
-static int tolua_AllToLua_cInventory_Clear00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL);
-#endif
- {
- self->Clear();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: AddItem of class cInventory */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_AddItem00
-static int tolua_AllToLua_cInventory_AddItem00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0);
- cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItem'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->AddItem(*a_Item);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'AddItem'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: RemoveItem of class cInventory */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_RemoveItem00
-static int tolua_AllToLua_cInventory_RemoveItem00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0);
- cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RemoveItem'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->RemoveItem(*a_Item);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'RemoveItem'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetSlot of class cInventory */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetSlot00
-static int tolua_AllToLua_cInventory_GetSlot00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0);
- int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSlot'", NULL);
-#endif
- {
- cItem* tolua_ret = (cItem*) self->GetSlot(a_SlotNum);
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetSlot'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetFromHotBar of class cInventory */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetFromHotBar00
-static int tolua_AllToLua_cInventory_GetFromHotBar00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0);
- int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFromHotBar'", NULL);
-#endif
- {
- cItem* tolua_ret = (cItem*) self->GetFromHotBar(a_SlotNum);
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetFromHotBar'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetEquippedItem of class cInventory */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetEquippedItem00
-static int tolua_AllToLua_cInventory_GetEquippedItem00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEquippedItem'", NULL);
-#endif
- {
- cItem& tolua_ret = (cItem&) self->GetEquippedItem();
- tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetEquippedItem'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetEquippedSlot of class cInventory */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_SetEquippedSlot00
-static int tolua_AllToLua_cInventory_SetEquippedSlot00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0);
- int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetEquippedSlot'", NULL);
-#endif
- {
- self->SetEquippedSlot(a_SlotNum);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetEquippedSlot'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetEquippedSlot of class cInventory */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetEquippedSlot00
-static int tolua_AllToLua_cInventory_GetEquippedSlot00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEquippedSlot'", NULL);
-#endif
- {
- short tolua_ret = (short) self->GetEquippedSlot();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetEquippedSlot'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SendSlot of class cInventory */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_SendSlot00
-static int tolua_AllToLua_cInventory_SendSlot00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0);
- int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendSlot'", NULL);
-#endif
- {
- self->SendSlot(a_SlotNum);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SendSlot'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class cItem */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_new00
-static int tolua_AllToLua_cItem_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cItem",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,1,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,1,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,E_ITEM_EMPTY));
- char a_ItemCount = ((char) tolua_tonumber(tolua_S,3,0));
- short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0));
- {
- cItem* tolua_ret = (cItem*) Mtolua_new((cItem)(a_ItemID,a_ItemCount,a_ItemHealth));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class cItem */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_new00_local
-static int tolua_AllToLua_cItem_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cItem",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,1,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,1,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,E_ITEM_EMPTY));
- char a_ItemCount = ((char) tolua_tonumber(tolua_S,3,0));
- short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0));
- {
- cItem* tolua_ret = (cItem*) Mtolua_new((cItem)(a_ItemID,a_ItemCount,a_ItemHealth));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Empty of class cItem */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_Empty00
-static int tolua_AllToLua_cItem_Empty00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Empty'", NULL);
-#endif
- {
- self->Empty();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Empty'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Clear of class cItem */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_Clear00
-static int tolua_AllToLua_cItem_Clear00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL);
-#endif
- {
- self->Clear();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: IsEmpty of class cItem */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_IsEmpty00
-static int tolua_AllToLua_cItem_IsEmpty00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsEmpty'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->IsEmpty();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsEmpty'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Equals of class cItem */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_Equals00
-static int tolua_AllToLua_cItem_Equals00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0);
- cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->Equals(*a_Item);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetMaxDuration of class cItem */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_GetMaxDuration00
-static int tolua_AllToLua_cItem_GetMaxDuration00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxDuration'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetMaxDuration();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetMaxDuration'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: DamageItem of class cItem */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_DamageItem00
-static int tolua_AllToLua_cItem_DamageItem00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DamageItem'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->DamageItem();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'DamageItem'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: HasDuration of class cItem */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_HasDuration00
-static int tolua_AllToLua_cItem_HasDuration00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasDuration'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->HasDuration();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'HasDuration'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetJson of class cItem */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_GetJson00
-static int tolua_AllToLua_cItem_GetJson00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Json::Value",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0);
- Json::Value* a_OutValue = ((Json::Value*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetJson'", NULL);
-#endif
- {
- self->GetJson(*a_OutValue);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetJson'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: FromJson of class cItem */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_FromJson00
-static int tolua_AllToLua_cItem_FromJson00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Json::Value",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0);
- const Json::Value* a_Value = ((const Json::Value*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FromJson'", NULL);
-#endif
- {
- self->FromJson(*a_Value);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'FromJson'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: IsEnchantable of class cItem */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_IsEnchantable00
-static int tolua_AllToLua_cItem_IsEnchantable00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cItem",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- ENUM_ITEM_ID item = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0));
- {
- bool tolua_ret = (bool) cItem::IsEnchantable(item);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsEnchantable'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_ItemID of class cItem */
-#ifndef TOLUA_DISABLE_tolua_get_cItem_m_ItemID
-static int tolua_get_cItem_m_ItemID(lua_State* tolua_S)
-{
- cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemID'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemID);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_ItemID of class cItem */
-#ifndef TOLUA_DISABLE_tolua_set_cItem_m_ItemID
-static int tolua_set_cItem_m_ItemID(lua_State* tolua_S)
-{
- cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemID'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_ItemCount of class cItem */
-#ifndef TOLUA_DISABLE_tolua_get_cItem_m_ItemCount
-static int tolua_get_cItem_m_ItemCount(lua_State* tolua_S)
-{
- cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemCount'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemCount);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_ItemCount of class cItem */
-#ifndef TOLUA_DISABLE_tolua_set_cItem_m_ItemCount
-static int tolua_set_cItem_m_ItemCount(lua_State* tolua_S)
-{
- cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemCount'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_ItemCount = ((char) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_ItemHealth of class cItem */
-#ifndef TOLUA_DISABLE_tolua_get_cItem_m_ItemHealth
-static int tolua_get_cItem_m_ItemHealth(lua_State* tolua_S)
-{
- cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemHealth'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemHealth);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_ItemHealth of class cItem */
-#ifndef TOLUA_DISABLE_tolua_set_cItem_m_ItemHealth
-static int tolua_set_cItem_m_ItemHealth(lua_State* tolua_S)
-{
- cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemHealth'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_ItemHealth = ((short) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Name of class HTTPFormData */
-#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Name
-static int tolua_get_HTTPFormData_Name(lua_State* tolua_S)
-{
- HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Name'",NULL);
-#endif
- tolua_pushcppstring(tolua_S,(const char*)self->Name);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: Name of class HTTPFormData */
-#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Name
-static int tolua_set_HTTPFormData_Name(lua_State* tolua_S)
-{
- HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Name'",NULL);
- if (!tolua_iscppstring(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->Name = ((std::string) tolua_tocppstring(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Value of class HTTPFormData */
-#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Value
-static int tolua_get_HTTPFormData_Value(lua_State* tolua_S)
-{
- HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Value'",NULL);
-#endif
- tolua_pushcppstring(tolua_S,(const char*)self->Value);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: Value of class HTTPFormData */
-#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Value
-static int tolua_set_HTTPFormData_Value(lua_State* tolua_S)
-{
- HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Value'",NULL);
- if (!tolua_iscppstring(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->Value = ((std::string) tolua_tocppstring(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Type of class HTTPFormData */
-#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Type
-static int tolua_get_HTTPFormData_Type(lua_State* tolua_S)
-{
- HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Type'",NULL);
-#endif
- tolua_pushcppstring(tolua_S,(const char*)self->Type);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: Type of class HTTPFormData */
-#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Type
-static int tolua_set_HTTPFormData_Type(lua_State* tolua_S)
-{
- HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Type'",NULL);
- if (!tolua_iscppstring(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->Type = ((std::string) tolua_tocppstring(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Method of class HTTPRequest */
-#ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Method
-static int tolua_get_HTTPRequest_Method(lua_State* tolua_S)
-{
- HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Method'",NULL);
-#endif
- tolua_pushcppstring(tolua_S,(const char*)self->Method);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: Method of class HTTPRequest */
-#ifndef TOLUA_DISABLE_tolua_set_HTTPRequest_Method
-static int tolua_set_HTTPRequest_Method(lua_State* tolua_S)
-{
- HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Method'",NULL);
- if (!tolua_iscppstring(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->Method = ((std::string) tolua_tocppstring(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Path of class HTTPRequest */
-#ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Path
-static int tolua_get_HTTPRequest_Path(lua_State* tolua_S)
-{
- HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Path'",NULL);
-#endif
- tolua_pushcppstring(tolua_S,(const char*)self->Path);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: Path of class HTTPRequest */
-#ifndef TOLUA_DISABLE_tolua_set_HTTPRequest_Path
-static int tolua_set_HTTPRequest_Path(lua_State* tolua_S)
-{
- HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Path'",NULL);
- if (!tolua_iscppstring(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->Path = ((std::string) tolua_tocppstring(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: Username of class HTTPRequest */
-#ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Username
-static int tolua_get_HTTPRequest_Username(lua_State* tolua_S)
-{
- HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Username'",NULL);
-#endif
- tolua_pushcppstring(tolua_S,(const char*)self->Username);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: Username of class HTTPRequest */
-#ifndef TOLUA_DISABLE_tolua_set_HTTPRequest_Username
-static int tolua_set_HTTPRequest_Username(lua_State* tolua_S)
-{
- HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Username'",NULL);
- if (!tolua_iscppstring(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->Username = ((std::string) tolua_tocppstring(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: delete of class cWebPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_delete00
-static int tolua_AllToLua_cWebPlugin_delete00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL);
-#endif
- Mtolua_delete(self);
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetName of class cWebPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_SetName00
-static int tolua_AllToLua_cWebPlugin_SetName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0);
- std::string a_Name = ((std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL);
-#endif
- {
- self->SetName(a_Name);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetName of class cWebPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_GetName00
-static int tolua_AllToLua_cWebPlugin_GetName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->GetName();
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: HandleRequest of class cWebPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_HandleRequest00
-static int tolua_AllToLua_cWebPlugin_HandleRequest00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"HTTPRequest",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0);
- HTTPRequest* a_Request = ((HTTPRequest*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HandleRequest'", NULL);
-#endif
- {
- std::string tolua_ret = (std::string) self->HandleRequest(a_Request);
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'HandleRequest'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Initialize of class cWebPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_Initialize00
-static int tolua_AllToLua_cWebPlugin_Initialize00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL);
-#endif
- {
- self->Initialize();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
- class Lua__cWebPlugin : public cWebPlugin, public ToluaBase {
-public:
- std::string HandleRequest( HTTPRequest* a_Request) {
- if (push_method("HandleRequest", tolua_AllToLua_cWebPlugin_HandleRequest00)) {
- tolua_pushusertype(lua_state, (void*)a_Request, "HTTPRequest");
- ToluaBase::dbcall(lua_state, 2, 1);
- std::string tolua_ret = ( std::string )tolua_tocppstring(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- if (lua_state)
- LOG("pure-virtual method cWebPlugin::HandleRequest not implemented.");
- else {
- LOG("pure-virtual method cWebPlugin::HandleRequest called with no lua_state. Aborting");
- ::abort();
- };
- return "";
- };
- };
- void Initialize( void ) {
- if (push_method("Initialize", tolua_AllToLua_cWebPlugin_Initialize00)) {
- ToluaBase::dbcall(lua_state, 1, 0);
- } else {
- if (lua_state)
- LOG("pure-virtual method cWebPlugin::Initialize not implemented.");
- else {
- LOG("pure-virtual method cWebPlugin::Initialize called with no lua_state. Aborting");
- ::abort();
- };
- return ( void )0;
- };
- };
-
- Lua__cWebPlugin( lua_State* L): cWebPlugin(L){};
-};
-
-/* method: tolua__set_instance of class Lua__cWebPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_tolua__set_instance00
-static int tolua_AllToLua_Lua__cWebPlugin_tolua__set_instance00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cWebPlugin* self = (Lua__cWebPlugin*) tolua_tousertype(tolua_S,1,0);
- lua_State* L = tolua_S;
- lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL);
-#endif
- {
- self->tolua__set_instance(L,lo);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Lua__cWebPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_new00
-static int tolua_AllToLua_Lua__cWebPlugin_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- lua_State* L = tolua_S;
- {
- Lua__cWebPlugin* tolua_ret = (Lua__cWebPlugin*) Mtolua_new((Lua__cWebPlugin)(L));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cWebPlugin");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Lua__cWebPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_new00_local
-static int tolua_AllToLua_Lua__cWebPlugin_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- lua_State* L = tolua_S;
- {
- Lua__cWebPlugin* tolua_ret = (Lua__cWebPlugin*) Mtolua_new((Lua__cWebPlugin)(L));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cWebPlugin");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: delete of class Lua__cWebPlugin */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_delete00
-static int tolua_AllToLua_Lua__cWebPlugin_delete00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cWebPlugin* self = (Lua__cWebPlugin*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL);
-#endif
- Mtolua_delete(self);
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-
-/* function to release collected object via destructor */
-#ifdef __cplusplus
-
-static int tolua_collect_Lua__cWebPlugin (lua_State* tolua_S)
-{
- Lua__cWebPlugin* self = (Lua__cWebPlugin*) tolua_tousertype(tolua_S,1,0);
- delete self;
- return 0;
-}
-#endif
-
-/* method: new of class cPickup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new00
-static int tolua_AllToLua_cPickup_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) ||
- !tolua_isnumber(tolua_S,6,1,&tolua_err) ||
- !tolua_isnumber(tolua_S,7,1,&tolua_err) ||
- !tolua_isnumber(tolua_S,8,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,9,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
- const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0));
- float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f));
- float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f));
- float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f));
- {
- cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class cPickup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new00_local
-static int tolua_AllToLua_cPickup_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) ||
- !tolua_isnumber(tolua_S,6,1,&tolua_err) ||
- !tolua_isnumber(tolua_S,7,1,&tolua_err) ||
- !tolua_isnumber(tolua_S,8,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,9,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
- const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0));
- float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f));
- float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f));
- float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f));
- {
- cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class cPickup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new01
-static int tolua_AllToLua_cPickup_new01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0));
- {
- cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_PickupSpawnPacket));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup");
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cPickup_new00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class cPickup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new01_local
-static int tolua_AllToLua_cPickup_new01_local(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0));
- {
- cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_PickupSpawnPacket));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cPickup_new00_local(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: delete of class cPickup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_delete00
-static int tolua_AllToLua_cPickup_delete00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPickup",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL);
-#endif
- Mtolua_delete(self);
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetItem of class cPickup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_GetItem00
-static int tolua_AllToLua_cPickup_GetItem00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPickup",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetItem'", NULL);
-#endif
- {
- cItem* tolua_ret = (cItem*) self->GetItem();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetItem'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: CollectedBy of class cPickup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_CollectedBy00
-static int tolua_AllToLua_cPickup_CollectedBy00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cPickup",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0);
- cPlayer* a_Dest = ((cPlayer*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CollectedBy'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->CollectedBy(a_Dest);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'CollectedBy'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
- class Lua__cPickup : public cPickup, public ToluaBase {
-public:
- bool CollectedBy( cPlayer* a_Dest) {
- if (push_method("CollectedBy", tolua_AllToLua_cPickup_CollectedBy00)) {
- tolua_pushusertype(lua_state, (void*)a_Dest, "cPlayer");
- ToluaBase::dbcall(lua_state, 2, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPickup:: CollectedBy(a_Dest);
- };
- };
- void Initialize( cWorld* a_World) {
- if (push_method("Initialize", tolua_AllToLua_cEntity_Initialize00)) {
- tolua_pushusertype(lua_state, (void*)a_World, "cWorld");
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- return ( void ) cPickup:: Initialize(a_World);
- };
- };
- unsigned int GetEntityType( void ) {
- if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) {
- ToluaBase::dbcall(lua_state, 1, 1);
- unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return (unsigned int ) cPickup:: GetEntityType();
- };
- };
- bool IsA( const char* a_EntityType) {
- if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) {
- tolua_pushstring(lua_state, (const char*)a_EntityType);
- ToluaBase::dbcall(lua_state, 2, 1);
- bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( bool ) cPickup:: IsA(a_EntityType);
- };
- };
- const char* GetClass( void ) {
- if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) {
- ToluaBase::dbcall(lua_state, 1, 1);
- const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( const char* ) cPickup:: GetClass();
- };
- };
- void Tick( float a_Dt) {
- if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) {
- tolua_pushnumber(lua_state, (lua_Number)a_Dt);
- ToluaBase::dbcall(lua_state, 2, 0);
- } else {
- if (lua_state)
- LOG("pure-virtual method cPickup::Tick not implemented.");
- else {
- LOG("pure-virtual method cPickup::Tick called with no lua_state. Aborting");
- ::abort();
- };
- return ( void )0;
- };
- };
-
- bool cPickup__CollectedBy( cPlayer* a_Dest) {
- return ( bool )cPickup::CollectedBy(a_Dest);
- };
- void cPickup__Initialize( cWorld* a_World) {
- return ( void )cPickup::Initialize(a_World);
- };
- unsigned int cPickup__GetEntityType( void ) {
- return (unsigned int )cPickup::GetEntityType();
- };
- bool cPickup__IsA( const char* a_EntityType) {
- return ( bool )cPickup::IsA(a_EntityType);
- };
- const char* cPickup__GetClass( void ) {
- return ( const char* )cPickup::GetClass();
- };
- Lua__cPickup( int a_X, int a_Y, int a_Z, const cItem& a_Item, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f): cPickup(a_X,a_Y,a_Z,a_Item,a_SpeedX,a_SpeedY,a_SpeedZ){};
- Lua__cPickup( cPacket_PickupSpawn* a_PickupSpawnPacket): cPickup(a_PickupSpawnPacket){};
-};
-
-/* method: tolua__set_instance of class Lua__cPickup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_tolua__set_instance00
-static int tolua_AllToLua_Lua__cPickup_tolua__set_instance00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPickup",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0);
- lua_State* L = tolua_S;
- lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL);
-#endif
- {
- self->tolua__set_instance(L,lo);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPickup__CollectedBy of class Lua__cPickup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_cPickup__CollectedBy00
-static int tolua_AllToLua_Lua__cPickup_cPickup__CollectedBy00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPickup",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0);
- cPlayer* a_Dest = ((cPlayer*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPickup__CollectedBy'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->cPickup__CollectedBy(a_Dest);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPickup__CollectedBy'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Lua__cPickup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new00
-static int tolua_AllToLua_Lua__cPickup_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"cItem",0,&tolua_err)) ||
- !tolua_isnumber(tolua_S,6,1,&tolua_err) ||
- !tolua_isnumber(tolua_S,7,1,&tolua_err) ||
- !tolua_isnumber(tolua_S,8,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,9,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
- const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0));
- float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f));
- float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f));
- float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f));
- {
- Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Lua__cPickup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new00_local
-static int tolua_AllToLua_Lua__cPickup_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"cItem",0,&tolua_err)) ||
- !tolua_isnumber(tolua_S,6,1,&tolua_err) ||
- !tolua_isnumber(tolua_S,7,1,&tolua_err) ||
- !tolua_isnumber(tolua_S,8,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,9,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
- const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0));
- float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f));
- float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f));
- float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f));
- {
- Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Lua__cPickup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new01
-static int tolua_AllToLua_Lua__cPickup_new01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0));
- {
- Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_PickupSpawnPacket));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup");
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Lua__cPickup_new00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Lua__cPickup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new01_local
-static int tolua_AllToLua_Lua__cPickup_new01_local(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0));
- {
- Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_PickupSpawnPacket));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Lua__cPickup_new00_local(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: delete of class Lua__cPickup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_delete00
-static int tolua_AllToLua_Lua__cPickup_delete00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPickup",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL);
-#endif
- Mtolua_delete(self);
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-
-/* function to release collected object via destructor */
-#ifdef __cplusplus
-
-static int tolua_collect_Lua__cPickup (lua_State* tolua_S)
-{
- Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0);
- delete self;
- return 0;
-}
-#endif
-
-/* method: Get of class cRoot */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_Get00
-static int tolua_AllToLua_cRoot_Get00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cRoot",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- cRoot* tolua_ret = (cRoot*) cRoot::Get();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cRoot");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Get'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetServer of class cRoot */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetServer00
-static int tolua_AllToLua_cRoot_GetServer00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetServer'", NULL);
-#endif
- {
- cServer* tolua_ret = (cServer*) self->GetServer();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cServer");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetServer'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetDefaultWorld of class cRoot */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetDefaultWorld00
-static int tolua_AllToLua_cRoot_GetDefaultWorld00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetDefaultWorld'", NULL);
-#endif
- {
- cWorld* tolua_ret = (cWorld*) self->GetDefaultWorld();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetDefaultWorld'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetWorld of class cRoot */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetWorld00
-static int tolua_AllToLua_cRoot_GetWorld00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0);
- const AString a_WorldName = ((const AString) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWorld'", NULL);
-#endif
- {
- cWorld* tolua_ret = (cWorld*) self->GetWorld(a_WorldName);
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld");
- tolua_pushcppstring(tolua_S,(const char*)a_WorldName);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetWorld'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetGroupManager of class cRoot */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetGroupManager00
-static int tolua_AllToLua_cRoot_GetGroupManager00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGroupManager'", NULL);
-#endif
- {
- cGroupManager* tolua_ret = (cGroupManager*) self->GetGroupManager();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cGroupManager");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetGroupManager'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetCraftingRecipes of class cRoot */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetCraftingRecipes00
-static int tolua_AllToLua_cRoot_GetCraftingRecipes00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetCraftingRecipes'", NULL);
-#endif
- {
- cCraftingRecipes* tolua_ret = (cCraftingRecipes*) self->GetCraftingRecipes();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCraftingRecipes");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetCraftingRecipes'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetFurnaceRecipe of class cRoot */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetFurnaceRecipe00
-static int tolua_AllToLua_cRoot_GetFurnaceRecipe00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFurnaceRecipe'", NULL);
-#endif
- {
- cFurnaceRecipe* tolua_ret = (cFurnaceRecipe*) self->GetFurnaceRecipe();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cFurnaceRecipe");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetFurnaceRecipe'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetWebAdmin of class cRoot */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetWebAdmin00
-static int tolua_AllToLua_cRoot_GetWebAdmin00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWebAdmin'", NULL);
-#endif
- {
- cWebAdmin* tolua_ret = (cWebAdmin*) self->GetWebAdmin();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWebAdmin");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetWebAdmin'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetPluginManager of class cRoot */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetPluginManager00
-static int tolua_AllToLua_cRoot_GetPluginManager00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPluginManager'", NULL);
-#endif
- {
- cPluginManager* tolua_ret = (cPluginManager*) self->GetPluginManager();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPluginManager");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetPluginManager'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: ServerCommand of class cRoot */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_ServerCommand00
-static int tolua_AllToLua_cRoot_ServerCommand00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0);
- const char* a_Cmd = ((const char*) tolua_tostring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ServerCommand'", NULL);
-#endif
- {
- self->ServerCommand(a_Cmd);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'ServerCommand'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetTotalChunkCount of class cRoot */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetTotalChunkCount00
-static int tolua_AllToLua_cRoot_GetTotalChunkCount00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetTotalChunkCount'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetTotalChunkCount();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetTotalChunkCount'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: delete of class cTCPLink */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_delete00
-static int tolua_AllToLua_cTCPLink_delete00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL);
-#endif
- Mtolua_delete(self);
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Connect of class cTCPLink */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_Connect00
-static int tolua_AllToLua_cTCPLink_Connect00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0);
- const AString a_Address = ((const AString) tolua_tocppstring(tolua_S,2,0));
- unsigned int a_Port = ((unsigned int) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Connect'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->Connect(a_Address,a_Port);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- tolua_pushcppstring(tolua_S,(const char*)a_Address);
- }
- }
- return 2;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Connect'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Send of class cTCPLink */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_Send00
-static int tolua_AllToLua_cTCPLink_Send00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0);
- const char* a_Data = ((const char*) tolua_tostring(tolua_S,2,0));
- unsigned int a_Size = ((unsigned int) tolua_tonumber(tolua_S,3,0));
- int a_Flags = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Send'", NULL);
-#endif
- {
- int tolua_ret = (int) self->Send(a_Data,a_Size,a_Flags);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Send'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SendMessage of class cTCPLink */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_SendMessage00
-static int tolua_AllToLua_cTCPLink_SendMessage00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0);
- const char* a_Message = ((const char*) tolua_tostring(tolua_S,2,0));
- int a_Flags = ((int) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL);
-#endif
- {
- int tolua_ret = (int) self->SendMessage(a_Message,a_Flags);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: CloseSocket of class cTCPLink */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_CloseSocket00
-static int tolua_AllToLua_cTCPLink_CloseSocket00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CloseSocket'", NULL);
-#endif
- {
- self->CloseSocket();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'CloseSocket'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
- class Lua__cTCPLink : public cTCPLink, public ToluaBase {
-public:
- void ReceivedData( char* a_Data, int a_Size) {
- if (push_method("ReceivedData", NULL)) {
- tolua_pushstring(lua_state, (const char*)a_Data);
- tolua_pushnumber(lua_state, (lua_Number)a_Size);
- ToluaBase::dbcall(lua_state, 3, 0);
- } else {
- if (lua_state)
- LOG("pure-virtual method cTCPLink::ReceivedData not implemented.");
- else {
- LOG("pure-virtual method cTCPLink::ReceivedData called with no lua_state. Aborting");
- ::abort();
- };
- return ( void )0;
- };
- };
-
- Lua__cTCPLink( void ): cTCPLink(){};
-};
-
-/* method: tolua__set_instance of class Lua__cTCPLink */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_tolua__set_instance00
-static int tolua_AllToLua_Lua__cTCPLink_tolua__set_instance00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cTCPLink* self = (Lua__cTCPLink*) tolua_tousertype(tolua_S,1,0);
- lua_State* L = tolua_S;
- lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL);
-#endif
- {
- self->tolua__set_instance(L,lo);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Lua__cTCPLink */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_new00
-static int tolua_AllToLua_Lua__cTCPLink_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- Lua__cTCPLink* tolua_ret = (Lua__cTCPLink*) Mtolua_new((Lua__cTCPLink)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cTCPLink");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Lua__cTCPLink */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_new00_local
-static int tolua_AllToLua_Lua__cTCPLink_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- Lua__cTCPLink* tolua_ret = (Lua__cTCPLink*) Mtolua_new((Lua__cTCPLink)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cTCPLink");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: delete of class Lua__cTCPLink */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_delete00
-static int tolua_AllToLua_Lua__cTCPLink_delete00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cTCPLink* self = (Lua__cTCPLink*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL);
-#endif
- Mtolua_delete(self);
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-
-/* function to release collected object via destructor */
-#ifdef __cplusplus
-
-static int tolua_collect_Lua__cTCPLink (lua_State* tolua_S)
-{
- Lua__cTCPLink* self = (Lua__cTCPLink*) tolua_tousertype(tolua_S,1,0);
- delete self;
- return 0;
-}
-#endif
-
-/* method: new of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new00
-static int tolua_AllToLua_Vector3f_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
- {
- Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new00_local
-static int tolua_AllToLua_Vector3f_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
- {
- Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new01
-static int tolua_AllToLua_Vector3f_new01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
- {
- Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f");
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3f_new00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new01_local
-static int tolua_AllToLua_Vector3f_new01_local(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
- {
- Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3f_new00_local(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new02
-static int tolua_AllToLua_Vector3f_new02(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0));
- {
- Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f");
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3f_new01(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new02_local
-static int tolua_AllToLua_Vector3f_new02_local(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0));
- {
- Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3f_new01_local(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new03
-static int tolua_AllToLua_Vector3f_new03(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0));
- {
- Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f");
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3f_new02(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new03_local
-static int tolua_AllToLua_Vector3f_new03_local(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0));
- {
- Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3f_new02_local(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new04
-static int tolua_AllToLua_Vector3f_new04(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- {
- Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f");
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3f_new03(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new04_local
-static int tolua_AllToLua_Vector3f_new04_local(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- {
- Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3f_new03_local(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new05
-static int tolua_AllToLua_Vector3f_new05(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- float a_x = ((float) tolua_tonumber(tolua_S,2,0));
- float a_y = ((float) tolua_tonumber(tolua_S,3,0));
- float a_z = ((float) tolua_tonumber(tolua_S,4,0));
- {
- Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(a_x,a_y,a_z));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f");
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3f_new04(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new05_local
-static int tolua_AllToLua_Vector3f_new05_local(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- float a_x = ((float) tolua_tonumber(tolua_S,2,0));
- float a_y = ((float) tolua_tonumber(tolua_S,3,0));
- float a_z = ((float) tolua_tonumber(tolua_S,4,0));
- {
- Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(a_x,a_y,a_z));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3f_new04_local(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Set of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Set00
-static int tolua_AllToLua_Vector3f_Set00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Vector3f",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0);
- float a_x = ((float) tolua_tonumber(tolua_S,2,0));
- float a_y = ((float) tolua_tonumber(tolua_S,3,0));
- float a_z = ((float) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL);
-#endif
- {
- self->Set(a_x,a_y,a_z);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Normalize of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Normalize00
-static int tolua_AllToLua_Vector3f_Normalize00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Vector3f",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Normalize'", NULL);
-#endif
- {
- self->Normalize();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Normalize'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: NormalizeCopy of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_NormalizeCopy00
-static int tolua_AllToLua_Vector3f_NormalizeCopy00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL);
-#endif
- {
- Vector3f tolua_ret = (Vector3f) self->NormalizeCopy();
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'NormalizeCopy'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: NormalizeCopy of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_NormalizeCopy01
-static int tolua_AllToLua_Vector3f_NormalizeCopy01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0);
- Vector3f* a_V = ((Vector3f*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL);
-#endif
- {
- self->NormalizeCopy(*a_V);
- }
- }
- return 0;
-tolua_lerror:
- return tolua_AllToLua_Vector3f_NormalizeCopy00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Length of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Length00
-static int tolua_AllToLua_Vector3f_Length00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Length'", NULL);
-#endif
- {
- float tolua_ret = (float) self->Length();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Length'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SqrLength of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_SqrLength00
-static int tolua_AllToLua_Vector3f_SqrLength00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SqrLength'", NULL);
-#endif
- {
- float tolua_ret = (float) self->SqrLength();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SqrLength'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Dot of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Dot00
-static int tolua_AllToLua_Vector3f_Dot00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0);
- const Vector3f* a_V = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dot'", NULL);
-#endif
- {
- float tolua_ret = (float) self->Dot(*a_V);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Dot'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Cross of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Cross00
-static int tolua_AllToLua_Vector3f_Cross00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0);
- const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Cross'", NULL);
-#endif
- {
- Vector3f tolua_ret = (Vector3f) self->Cross(*v);
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Cross'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Equals of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Equals00
-static int tolua_AllToLua_Vector3f_Equals00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0);
- const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->Equals(*v);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: operator+ of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__add00
-static int tolua_AllToLua_Vector3f__add00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0);
- const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL);
-#endif
- {
- Vector3f tolua_ret = (Vector3f) self->operator+(*v2);
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function '.add'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: operator+ of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__add01
-static int tolua_AllToLua_Vector3f__add01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0);
- const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL);
-#endif
- {
- Vector3f tolua_ret = (Vector3f) self->operator+(v2);
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3f__add00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: operator- of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__sub00
-static int tolua_AllToLua_Vector3f__sub00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0);
- const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL);
-#endif
- {
- Vector3f tolua_ret = (Vector3f) self->operator-(*v2);
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function '.sub'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: operator- of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__sub01
-static int tolua_AllToLua_Vector3f__sub01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0);
- const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL);
-#endif
- {
- Vector3f tolua_ret = (Vector3f) self->operator-(v2);
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3f__sub00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: operator* of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__mul00
-static int tolua_AllToLua_Vector3f__mul00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0);
- const float f = ((const float) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL);
-#endif
- {
- Vector3f tolua_ret = (Vector3f) self->operator*(f);
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function '.mul'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: operator* of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__mul01
-static int tolua_AllToLua_Vector3f__mul01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0);
- const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL);
-#endif
- {
- Vector3f tolua_ret = (Vector3f) self->operator*(*v2);
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3f");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3f__mul00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: x of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_get_Vector3f_x
-static int tolua_get_Vector3f_x(lua_State* tolua_S)
-{
- Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->x);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: x of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_set_Vector3f_x
-static int tolua_set_Vector3f_x(lua_State* tolua_S)
-{
- Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->x = ((float) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: y of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_get_Vector3f_y
-static int tolua_get_Vector3f_y(lua_State* tolua_S)
-{
- Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->y);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: y of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_set_Vector3f_y
-static int tolua_set_Vector3f_y(lua_State* tolua_S)
-{
- Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->y = ((float) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: z of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_get_Vector3f_z
-static int tolua_get_Vector3f_z(lua_State* tolua_S)
-{
- Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->z);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: z of class Vector3f */
-#ifndef TOLUA_DISABLE_tolua_set_Vector3f_z
-static int tolua_set_Vector3f_z(lua_State* tolua_S)
-{
- Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->z = ((float) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new00
-static int tolua_AllToLua_Vector3d_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
- {
- Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(*v));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new00_local
-static int tolua_AllToLua_Vector3d_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
- {
- Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(*v));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new01
-static int tolua_AllToLua_Vector3d_new01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
- {
- Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(v));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d");
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3d_new00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new01_local
-static int tolua_AllToLua_Vector3d_new01_local(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
- {
- Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(v));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3d_new00_local(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new02
-static int tolua_AllToLua_Vector3d_new02(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- {
- Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d");
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3d_new01(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new02_local
-static int tolua_AllToLua_Vector3d_new02_local(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- {
- Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3d_new01_local(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new03
-static int tolua_AllToLua_Vector3d_new03(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- double a_x = ((double) tolua_tonumber(tolua_S,2,0));
- double a_y = ((double) tolua_tonumber(tolua_S,3,0));
- double a_z = ((double) tolua_tonumber(tolua_S,4,0));
- {
- Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(a_x,a_y,a_z));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d");
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3d_new02(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new03_local
-static int tolua_AllToLua_Vector3d_new03_local(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- double a_x = ((double) tolua_tonumber(tolua_S,2,0));
- double a_y = ((double) tolua_tonumber(tolua_S,3,0));
- double a_z = ((double) tolua_tonumber(tolua_S,4,0));
- {
- Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(a_x,a_y,a_z));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3d_new02_local(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Set of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Set00
-static int tolua_AllToLua_Vector3d_Set00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0);
- double a_x = ((double) tolua_tonumber(tolua_S,2,0));
- double a_y = ((double) tolua_tonumber(tolua_S,3,0));
- double a_z = ((double) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL);
-#endif
- {
- self->Set(a_x,a_y,a_z);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Normalize of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Normalize00
-static int tolua_AllToLua_Vector3d_Normalize00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Normalize'", NULL);
-#endif
- {
- self->Normalize();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Normalize'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: NormalizeCopy of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_NormalizeCopy00
-static int tolua_AllToLua_Vector3d_NormalizeCopy00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL);
-#endif
- {
- Vector3d tolua_ret = (Vector3d) self->NormalizeCopy();
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'NormalizeCopy'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: NormalizeCopy of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_NormalizeCopy01
-static int tolua_AllToLua_Vector3d_NormalizeCopy01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0);
- Vector3d* a_V = ((Vector3d*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL);
-#endif
- {
- self->NormalizeCopy(*a_V);
- }
- }
- return 0;
-tolua_lerror:
- return tolua_AllToLua_Vector3d_NormalizeCopy00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Length of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Length00
-static int tolua_AllToLua_Vector3d_Length00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Length'", NULL);
-#endif
- {
- double tolua_ret = (double) self->Length();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Length'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SqrLength of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_SqrLength00
-static int tolua_AllToLua_Vector3d_SqrLength00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SqrLength'", NULL);
-#endif
- {
- double tolua_ret = (double) self->SqrLength();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SqrLength'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Dot of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Dot00
-static int tolua_AllToLua_Vector3d_Dot00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0);
- const Vector3d* a_V = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dot'", NULL);
-#endif
- {
- double tolua_ret = (double) self->Dot(*a_V);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Dot'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Cross of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Cross00
-static int tolua_AllToLua_Vector3d_Cross00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0);
- const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Cross'", NULL);
-#endif
- {
- Vector3d tolua_ret = (Vector3d) self->Cross(*v);
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Cross'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Equals of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Equals00
-static int tolua_AllToLua_Vector3d_Equals00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0);
- const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->Equals(*v);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: operator+ of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__add00
-static int tolua_AllToLua_Vector3d__add00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0);
- const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL);
-#endif
- {
- Vector3d tolua_ret = (Vector3d) self->operator+(*v2);
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function '.add'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: operator+ of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__add01
-static int tolua_AllToLua_Vector3d__add01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0);
- const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL);
-#endif
- {
- Vector3d tolua_ret = (Vector3d) self->operator+(v2);
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3d__add00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: operator- of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__sub00
-static int tolua_AllToLua_Vector3d__sub00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0);
- const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL);
-#endif
- {
- Vector3d tolua_ret = (Vector3d) self->operator-(*v2);
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function '.sub'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: operator- of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__sub01
-static int tolua_AllToLua_Vector3d__sub01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0);
- const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL);
-#endif
- {
- Vector3d tolua_ret = (Vector3d) self->operator-(v2);
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3d__sub00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: operator* of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__mul00
-static int tolua_AllToLua_Vector3d__mul00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0);
- const double f = ((const double) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL);
-#endif
- {
- Vector3d tolua_ret = (Vector3d) self->operator*(f);
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function '.mul'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: operator* of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__mul01
-static int tolua_AllToLua_Vector3d__mul01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0);
- const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL);
-#endif
- {
- Vector3d tolua_ret = (Vector3d) self->operator*(*v2);
- {
-#ifdef __cplusplus
- void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#else
- void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d));
- tolua_pushusertype(tolua_S,tolua_obj,"Vector3d");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
-#endif
- }
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3d__mul00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: x of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_get_Vector3d_x
-static int tolua_get_Vector3d_x(lua_State* tolua_S)
-{
- Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->x);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: x of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_set_Vector3d_x
-static int tolua_set_Vector3d_x(lua_State* tolua_S)
-{
- Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->x = ((double) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: y of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_get_Vector3d_y
-static int tolua_get_Vector3d_y(lua_State* tolua_S)
-{
- Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->y);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: y of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_set_Vector3d_y
-static int tolua_set_Vector3d_y(lua_State* tolua_S)
-{
- Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->y = ((double) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: z of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_get_Vector3d_z
-static int tolua_get_Vector3d_z(lua_State* tolua_S)
-{
- Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->z);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: z of class Vector3d */
-#ifndef TOLUA_DISABLE_tolua_set_Vector3d_z
-static int tolua_set_Vector3d_z(lua_State* tolua_S)
-{
- Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->z = ((double) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new00
-static int tolua_AllToLua_Vector3i_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
- {
- Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(*v));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new00_local
-static int tolua_AllToLua_Vector3i_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
- {
- Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(*v));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new01
-static int tolua_AllToLua_Vector3i_new01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- {
- Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i");
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3i_new00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new01_local
-static int tolua_AllToLua_Vector3i_new01_local(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- {
- Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3i_new00_local(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new02
-static int tolua_AllToLua_Vector3i_new02(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- int a_x = ((int) tolua_tonumber(tolua_S,2,0));
- int a_y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_z = ((int) tolua_tonumber(tolua_S,4,0));
- {
- Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(a_x,a_y,a_z));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i");
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3i_new01(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new02_local
-static int tolua_AllToLua_Vector3i_new02_local(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- int a_x = ((int) tolua_tonumber(tolua_S,2,0));
- int a_y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_z = ((int) tolua_tonumber(tolua_S,4,0));
- {
- Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(a_x,a_y,a_z));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3i_new01_local(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Set of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Set00
-static int tolua_AllToLua_Vector3i_Set00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Vector3i",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0);
- int a_x = ((int) tolua_tonumber(tolua_S,2,0));
- int a_y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_z = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL);
-#endif
- {
- self->Set(a_x,a_y,a_z);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Length of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Length00
-static int tolua_AllToLua_Vector3i_Length00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Length'", NULL);
-#endif
- {
- float tolua_ret = (float) self->Length();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Length'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SqrLength of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_SqrLength00
-static int tolua_AllToLua_Vector3i_SqrLength00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SqrLength'", NULL);
-#endif
- {
- int tolua_ret = (int) self->SqrLength();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SqrLength'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Equals of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Equals00
-static int tolua_AllToLua_Vector3i_Equals00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0);
- const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->Equals(*v);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Equals of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Equals01
-static int tolua_AllToLua_Vector3i_Equals01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0);
- const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->Equals(v);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_Vector3i_Equals00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: x of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_get_Vector3i_x
-static int tolua_get_Vector3i_x(lua_State* tolua_S)
-{
- Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->x);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: x of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_set_Vector3i_x
-static int tolua_set_Vector3i_x(lua_State* tolua_S)
-{
- Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->x = ((int) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: y of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_get_Vector3i_y
-static int tolua_get_Vector3i_y(lua_State* tolua_S)
-{
- Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->y);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: y of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_set_Vector3i_y
-static int tolua_set_Vector3i_y(lua_State* tolua_S)
-{
- Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->y = ((int) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: z of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_get_Vector3i_z
-static int tolua_get_Vector3i_z(lua_State* tolua_S)
-{
- Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->z);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: z of class Vector3i */
-#ifndef TOLUA_DISABLE_tolua_set_Vector3i_z
-static int tolua_set_Vector3i_z(lua_State* tolua_S)
-{
- Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->z = ((int) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class cCuboid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new00
-static int tolua_AllToLua_cCuboid_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class cCuboid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new00_local
-static int tolua_AllToLua_cCuboid_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class cCuboid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new01
-static int tolua_AllToLua_cCuboid_new01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cCuboid",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const cCuboid* a_Cuboid = ((const cCuboid*) tolua_tousertype(tolua_S,2,0));
- {
- cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_Cuboid));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid");
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cCuboid_new00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class cCuboid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new01_local
-static int tolua_AllToLua_cCuboid_new01_local(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cCuboid",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const cCuboid* a_Cuboid = ((const cCuboid*) tolua_tousertype(tolua_S,2,0));
- {
- cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_Cuboid));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cCuboid_new00_local(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class cCuboid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new02
-static int tolua_AllToLua_cCuboid_new02(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) ||
- (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3i",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3i* a_p1 = ((const Vector3i*) tolua_tousertype(tolua_S,2,0));
- const Vector3i* a_p2 = ((const Vector3i*) tolua_tousertype(tolua_S,3,0));
- {
- cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_p1,*a_p2));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid");
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cCuboid_new01(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class cCuboid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new02_local
-static int tolua_AllToLua_cCuboid_new02_local(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) ||
- (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3i",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const Vector3i* a_p1 = ((const Vector3i*) tolua_tousertype(tolua_S,2,0));
- const Vector3i* a_p2 = ((const Vector3i*) tolua_tousertype(tolua_S,3,0));
- {
- cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_p1,*a_p2));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cCuboid_new01_local(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: p1 of class cCuboid */
-#ifndef TOLUA_DISABLE_tolua_get_cCuboid_p1
-static int tolua_get_cCuboid_p1(lua_State* tolua_S)
-{
- cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p1'",NULL);
-#endif
- tolua_pushusertype(tolua_S,(void*)&self->p1,"Vector3i");
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: p1 of class cCuboid */
-#ifndef TOLUA_DISABLE_tolua_set_cCuboid_p1
-static int tolua_set_cCuboid_p1(lua_State* tolua_S)
-{
- cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p1'",NULL);
- if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3i",0,&tolua_err)))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->p1 = *((Vector3i*) tolua_tousertype(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: p2 of class cCuboid */
-#ifndef TOLUA_DISABLE_tolua_get_cCuboid_p2
-static int tolua_get_cCuboid_p2(lua_State* tolua_S)
-{
- cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p2'",NULL);
-#endif
- tolua_pushusertype(tolua_S,(void*)&self->p2,"Vector3i");
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: p2 of class cCuboid */
-#ifndef TOLUA_DISABLE_tolua_set_cCuboid_p2
-static int tolua_set_cCuboid_p2(lua_State* tolua_S)
-{
- cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p2'",NULL);
- if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3i",0,&tolua_err)))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->p2 = *((Vector3i*) tolua_tousertype(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Sort of class cCuboid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_Sort00
-static int tolua_AllToLua_cCuboid_Sort00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cCuboid",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Sort'", NULL);
-#endif
- {
- self->Sort();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Sort'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: IsInside of class cCuboid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_IsInside00
-static int tolua_AllToLua_cCuboid_IsInside00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cCuboid",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cCuboid* self = (const cCuboid*) tolua_tousertype(tolua_S,1,0);
- const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInside'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->IsInside(*v);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsInside'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: IsInside of class cCuboid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_IsInside01
-static int tolua_AllToLua_cCuboid_IsInside01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cCuboid",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- const cCuboid* self = (const cCuboid*) tolua_tousertype(tolua_S,1,0);
- const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInside'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->IsInside(*v);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-tolua_lerror:
- return tolua_AllToLua_cCuboid_IsInside00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class cMCLogger */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_new00
-static int tolua_AllToLua_cMCLogger_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cMCLogger",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- char* a_File = ((char*) tolua_tostring(tolua_S,2,0));
- {
- cMCLogger* tolua_ret = (cMCLogger*) Mtolua_new((cMCLogger)(a_File));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cMCLogger");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class cMCLogger */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_new00_local
-static int tolua_AllToLua_cMCLogger_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cMCLogger",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- char* a_File = ((char*) tolua_tostring(tolua_S,2,0));
- {
- cMCLogger* tolua_ret = (cMCLogger*) Mtolua_new((cMCLogger)(a_File));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cMCLogger");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: delete of class cMCLogger */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_delete00
-static int tolua_AllToLua_cMCLogger_delete00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cMCLogger",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cMCLogger* self = (cMCLogger*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL);
-#endif
- Mtolua_delete(self);
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: LogSimple of class cMCLogger */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_LogSimple00
-static int tolua_AllToLua_cMCLogger_LogSimple00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cMCLogger",0,&tolua_err) ||
- !tolua_isstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,1,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cMCLogger* self = (cMCLogger*) tolua_tousertype(tolua_S,1,0);
- const char* a_Text = ((const char*) tolua_tostring(tolua_S,2,0));
- int a_LogType = ((int) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'LogSimple'", NULL);
-#endif
- {
- self->LogSimple(a_Text,a_LogType);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'LogSimple'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class cTracer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_new00
-static int tolua_AllToLua_cTracer_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cTracer",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0));
- {
- cTracer* tolua_ret = (cTracer*) Mtolua_new((cTracer)(a_World));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cTracer");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class cTracer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_new00_local
-static int tolua_AllToLua_cTracer_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cTracer",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0));
- {
- cTracer* tolua_ret = (cTracer*) Mtolua_new((cTracer)(a_World));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cTracer");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: delete of class cTracer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_delete00
-static int tolua_AllToLua_cTracer_delete00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cTracer",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL);
-#endif
- Mtolua_delete(self);
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Trace of class cTracer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_Trace00
-static int tolua_AllToLua_cTracer_Trace00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cTracer",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) ||
- (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3f",0,&tolua_err)) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0);
- const Vector3f* a_Start = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
- const Vector3f* a_Direction = ((const Vector3f*) tolua_tousertype(tolua_S,3,0));
- int a_Distance = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Trace'", NULL);
-#endif
- {
- int tolua_ret = (int) self->Trace(*a_Start,*a_Direction,a_Distance);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Trace'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetValues of class cTracer */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_SetValues00
-static int tolua_AllToLua_cTracer_SetValues00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cTracer",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) ||
- (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3f",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0);
- const Vector3f* a_Start = ((const Vector3f*) tolua_tousertype(tolua_S,2,0));
- const Vector3f* a_Direction = ((const Vector3f*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValues'", NULL);
-#endif
- {
- self->SetValues(*a_Start,*a_Direction);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetValues'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: BlockHitPosition of class cTracer */
-#ifndef TOLUA_DISABLE_tolua_get_cTracer_BlockHitPosition
-static int tolua_get_cTracer_BlockHitPosition(lua_State* tolua_S)
-{
- cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'BlockHitPosition'",NULL);
-#endif
- tolua_pushusertype(tolua_S,(void*)&self->BlockHitPosition,"Vector3f");
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: BlockHitPosition of class cTracer */
-#ifndef TOLUA_DISABLE_tolua_set_cTracer_BlockHitPosition
-static int tolua_set_cTracer_BlockHitPosition(lua_State* tolua_S)
-{
- cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'BlockHitPosition'",NULL);
- if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err)))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->BlockHitPosition = *((Vector3f*) tolua_tousertype(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: HitNormal of class cTracer */
-#ifndef TOLUA_DISABLE_tolua_get_cTracer_HitNormal
-static int tolua_get_cTracer_HitNormal(lua_State* tolua_S)
-{
- cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'HitNormal'",NULL);
-#endif
- tolua_pushusertype(tolua_S,(void*)&self->HitNormal,"Vector3f");
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: HitNormal of class cTracer */
-#ifndef TOLUA_DISABLE_tolua_set_cTracer_HitNormal
-static int tolua_set_cTracer_HitNormal(lua_State* tolua_S)
-{
- cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'HitNormal'",NULL);
- if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err)))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->HitNormal = *((Vector3f*) tolua_tousertype(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: RealHit of class cTracer */
-#ifndef TOLUA_DISABLE_tolua_get_cTracer_RealHit
-static int tolua_get_cTracer_RealHit(lua_State* tolua_S)
-{
- cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'RealHit'",NULL);
-#endif
- tolua_pushusertype(tolua_S,(void*)&self->RealHit,"Vector3f");
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: RealHit of class cTracer */
-#ifndef TOLUA_DISABLE_tolua_set_cTracer_RealHit
-static int tolua_set_cTracer_RealHit(lua_State* tolua_S)
-{
- cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'RealHit'",NULL);
- if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err)))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->RealHit = *((Vector3f*) tolua_tousertype(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetName of class cGroup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_SetName00
-static int tolua_AllToLua_cGroup_SetName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0);
- std::string a_Name = ((std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL);
-#endif
- {
- self->SetName(a_Name);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetName of class cGroup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_GetName00
-static int tolua_AllToLua_cGroup_GetName00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cGroup",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cGroup* self = (const cGroup*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL);
-#endif
- {
- const std::string tolua_ret = (const std::string) self->GetName();
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetColor of class cGroup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_SetColor00
-static int tolua_AllToLua_cGroup_SetColor00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0);
- std::string a_Color = ((std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetColor'", NULL);
-#endif
- {
- self->SetColor(a_Color);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetColor'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: AddCommand of class cGroup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_AddCommand00
-static int tolua_AllToLua_cGroup_AddCommand00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0);
- std::string a_Command = ((std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddCommand'", NULL);
-#endif
- {
- self->AddCommand(a_Command);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'AddCommand'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: AddPermission of class cGroup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_AddPermission00
-static int tolua_AllToLua_cGroup_AddPermission00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0);
- std::string a_Permission = ((std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddPermission'", NULL);
-#endif
- {
- self->AddPermission(a_Permission);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'AddPermission'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: InheritFrom of class cGroup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_InheritFrom00
-static int tolua_AllToLua_cGroup_InheritFrom00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) ||
- !tolua_isusertype(tolua_S,2,"cGroup",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0);
- cGroup* a_Group = ((cGroup*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'InheritFrom'", NULL);
-#endif
- {
- self->InheritFrom(a_Group);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'InheritFrom'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: HasCommand of class cGroup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_HasCommand00
-static int tolua_AllToLua_cGroup_HasCommand00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) ||
- !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0);
- std::string a_Command = ((std::string) tolua_tocppstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasCommand'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->HasCommand(a_Command);
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'HasCommand'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetColor of class cGroup */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_GetColor00
-static int tolua_AllToLua_cGroup_GetColor00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cGroup",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cGroup* self = (const cGroup*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetColor'", NULL);
-#endif
- {
- const AString tolua_ret = (const AString) self->GetColor();
- tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetColor'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_ProtocolVersion of class cPacket_Login */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_ProtocolVersion
-static int tolua_get_cPacket_Login_m_ProtocolVersion(lua_State* tolua_S)
-{
- cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ProtocolVersion'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_ProtocolVersion);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_ProtocolVersion of class cPacket_Login */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_ProtocolVersion
-static int tolua_set_cPacket_Login_m_ProtocolVersion(lua_State* tolua_S)
-{
- cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ProtocolVersion'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_ProtocolVersion = ((int) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_Username of class cPacket_Login */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_Username
-static int tolua_get_cPacket_Login_m_Username(lua_State* tolua_S)
-{
- cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Username'",NULL);
-#endif
- tolua_pushcppstring(tolua_S,(const char*)self->m_Username);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_Username of class cPacket_Login */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_Username
-static int tolua_set_cPacket_Login_m_Username(lua_State* tolua_S)
-{
- cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Username'",NULL);
- if (!tolua_iscppstring(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_Username = ((AString) tolua_tocppstring(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_LevelType of class cPacket_Login */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_LevelType
-static int tolua_get_cPacket_Login_m_LevelType(lua_State* tolua_S)
-{
- cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_LevelType'",NULL);
-#endif
- tolua_pushcppstring(tolua_S,(const char*)self->m_LevelType);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_LevelType of class cPacket_Login */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_LevelType
-static int tolua_set_cPacket_Login_m_LevelType(lua_State* tolua_S)
-{
- cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_LevelType'",NULL);
- if (!tolua_iscppstring(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_LevelType = ((AString) tolua_tocppstring(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_ServerMode of class cPacket_Login */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_ServerMode
-static int tolua_get_cPacket_Login_m_ServerMode(lua_State* tolua_S)
-{
- cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ServerMode'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_ServerMode);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_ServerMode of class cPacket_Login */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_ServerMode
-static int tolua_set_cPacket_Login_m_ServerMode(lua_State* tolua_S)
-{
- cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ServerMode'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_ServerMode = ((int) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_Difficulty of class cPacket_Login */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_Difficulty
-static int tolua_get_cPacket_Login_m_Difficulty(lua_State* tolua_S)
-{
- cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Difficulty'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_Difficulty);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_Difficulty of class cPacket_Login */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_Difficulty
-static int tolua_set_cPacket_Login_m_Difficulty(lua_State* tolua_S)
-{
- cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Difficulty'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_Difficulty = ((char) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_WorldHeight of class cPacket_Login */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_unsigned_m_WorldHeight
-static int tolua_get_cPacket_Login_unsigned_m_WorldHeight(lua_State* tolua_S)
-{
- cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_WorldHeight'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_WorldHeight);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_WorldHeight of class cPacket_Login */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_unsigned_m_WorldHeight
-static int tolua_set_cPacket_Login_unsigned_m_WorldHeight(lua_State* tolua_S)
-{
- cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_WorldHeight'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_WorldHeight = ((unsigned char) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_MaxPlayers of class cPacket_Login */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_unsigned_m_MaxPlayers
-static int tolua_get_cPacket_Login_unsigned_m_MaxPlayers(lua_State* tolua_S)
-{
- cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_MaxPlayers'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_MaxPlayers);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_MaxPlayers of class cPacket_Login */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_unsigned_m_MaxPlayers
-static int tolua_set_cPacket_Login_unsigned_m_MaxPlayers(lua_State* tolua_S)
-{
- cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_MaxPlayers'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_MaxPlayers = ((unsigned char) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPacket_BlockDig_new00
-static int tolua_AllToLua_cPacket_BlockDig_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cPacket_BlockDig",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- cPacket_BlockDig* tolua_ret = (cPacket_BlockDig*) Mtolua_new((cPacket_BlockDig)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket_BlockDig");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPacket_BlockDig_new00_local
-static int tolua_AllToLua_cPacket_BlockDig_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cPacket_BlockDig",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- cPacket_BlockDig* tolua_ret = (cPacket_BlockDig*) Mtolua_new((cPacket_BlockDig)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket_BlockDig");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Clone of class cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cPacket_BlockDig_Clone00
-static int tolua_AllToLua_cPacket_BlockDig_Clone00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cPacket_BlockDig",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cPacket_BlockDig* self = (const cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clone'", NULL);
-#endif
- {
- cPacket* tolua_ret = (cPacket*) self->Clone();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Clone'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_Status of class cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_Status
-static int tolua_get_cPacket_BlockDig_m_Status(lua_State* tolua_S)
-{
- cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Status'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_Status);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_Status of class cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_Status
-static int tolua_set_cPacket_BlockDig_m_Status(lua_State* tolua_S)
-{
- cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Status'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_Status = ((char) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_PosX of class cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_PosX
-static int tolua_get_cPacket_BlockDig_m_PosX(lua_State* tolua_S)
-{
- cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_PosX);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_PosX of class cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_PosX
-static int tolua_set_cPacket_BlockDig_m_PosX(lua_State* tolua_S)
-{
- cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_PosX = ((int) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_PosY of class cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_PosY
-static int tolua_get_cPacket_BlockDig_m_PosY(lua_State* tolua_S)
-{
- cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_PosY);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_PosY of class cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_PosY
-static int tolua_set_cPacket_BlockDig_m_PosY(lua_State* tolua_S)
-{
- cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_PosY = ((char) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_PosZ of class cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_PosZ
-static int tolua_get_cPacket_BlockDig_m_PosZ(lua_State* tolua_S)
-{
- cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_PosZ);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_PosZ of class cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_PosZ
-static int tolua_set_cPacket_BlockDig_m_PosZ(lua_State* tolua_S)
-{
- cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_PosZ = ((int) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_Direction of class cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_Direction
-static int tolua_get_cPacket_BlockDig_m_Direction(lua_State* tolua_S)
-{
- cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_Direction);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_Direction of class cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_Direction
-static int tolua_set_cPacket_BlockDig_m_Direction(lua_State* tolua_S)
-{
- cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_Direction = ((char) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
- class Lua__cPacket_BlockDig : public cPacket_BlockDig, public ToluaBase {
-public:
- cPacket* Clone( void )const {
- if (push_method("Clone", tolua_AllToLua_cPacket_BlockDig_Clone00)) {
- ToluaBase::dbcall(lua_state, 1, 1);
- cPacket* tolua_ret = ( cPacket* )tolua_tousertype(lua_state, -1, 0);
- lua_pop(lua_state, 1);
- return tolua_ret;
- } else {
- return ( cPacket* ) cPacket_BlockDig:: Clone();
- };
- };
-
- cPacket* cPacket_BlockDig__Clone( void ) {
- return ( cPacket* )cPacket_BlockDig::Clone();
- };
- Lua__cPacket_BlockDig( void ): cPacket_BlockDig(){};
-};
-
-/* method: tolua__set_instance of class Lua__cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_tolua__set_instance00
-static int tolua_AllToLua_Lua__cPacket_BlockDig_tolua__set_instance00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPacket_BlockDig* self = (Lua__cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
- lua_State* L = tolua_S;
- lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL);
-#endif
- {
- self->tolua__set_instance(L,lo);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: cPacket_BlockDig__Clone of class Lua__cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_cPacket_BlockDig__Clone00
-static int tolua_AllToLua_Lua__cPacket_BlockDig_cPacket_BlockDig__Clone00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- Lua__cPacket_BlockDig* self = (Lua__cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPacket_BlockDig__Clone'", NULL);
-#endif
- {
- cPacket* tolua_ret = (cPacket*) self->cPacket_BlockDig__Clone();
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'cPacket_BlockDig__Clone'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class Lua__cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_new00
-static int tolua_AllToLua_Lua__cPacket_BlockDig_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- Lua__cPacket_BlockDig* tolua_ret = (Lua__cPacket_BlockDig*) Mtolua_new((Lua__cPacket_BlockDig)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPacket_BlockDig");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class Lua__cPacket_BlockDig */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_new00_local
-static int tolua_AllToLua_Lua__cPacket_BlockDig_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
- Lua__cPacket_BlockDig* tolua_ret = (Lua__cPacket_BlockDig*) Mtolua_new((Lua__cPacket_BlockDig)());
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPacket_BlockDig");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-
-/* function to release collected object via destructor */
-#ifdef __cplusplus
-
-static int tolua_collect_Lua__cPacket_BlockDig (lua_State* tolua_S)
-{
- Lua__cPacket_BlockDig* self = (Lua__cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0);
- delete self;
- return 0;
-}
-#endif
-
-/* get function: m_PosX of class cPacket_BlockPlace */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_PosX
-static int tolua_get_cPacket_BlockPlace_m_PosX(lua_State* tolua_S)
-{
- cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_PosX);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_PosX of class cPacket_BlockPlace */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_PosX
-static int tolua_set_cPacket_BlockPlace_m_PosX(lua_State* tolua_S)
-{
- cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_PosX = ((int) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_PosY of class cPacket_BlockPlace */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_unsigned_m_PosY
-static int tolua_get_cPacket_BlockPlace_unsigned_m_PosY(lua_State* tolua_S)
-{
- cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_PosY);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_PosY of class cPacket_BlockPlace */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_unsigned_m_PosY
-static int tolua_set_cPacket_BlockPlace_unsigned_m_PosY(lua_State* tolua_S)
-{
- cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_PosY = ((unsigned char) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_PosZ of class cPacket_BlockPlace */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_PosZ
-static int tolua_get_cPacket_BlockPlace_m_PosZ(lua_State* tolua_S)
-{
- cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_PosZ);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_PosZ of class cPacket_BlockPlace */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_PosZ
-static int tolua_set_cPacket_BlockPlace_m_PosZ(lua_State* tolua_S)
-{
- cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_PosZ = ((int) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_Direction of class cPacket_BlockPlace */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_Direction
-static int tolua_get_cPacket_BlockPlace_m_Direction(lua_State* tolua_S)
-{
- cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_Direction);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_Direction of class cPacket_BlockPlace */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_Direction
-static int tolua_set_cPacket_BlockPlace_m_Direction(lua_State* tolua_S)
-{
- cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_Direction = ((char) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_ItemType of class cPacket_BlockPlace */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_ItemType
-static int tolua_get_cPacket_BlockPlace_m_ItemType(lua_State* tolua_S)
-{
- cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemType'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemType);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_ItemType of class cPacket_BlockPlace */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_ItemType
-static int tolua_set_cPacket_BlockPlace_m_ItemType(lua_State* tolua_S)
-{
- cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemType'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_ItemType = ((short) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_Count of class cPacket_BlockPlace */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_Count
-static int tolua_get_cPacket_BlockPlace_m_Count(lua_State* tolua_S)
-{
- cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Count'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_Count);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_Count of class cPacket_BlockPlace */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_Count
-static int tolua_set_cPacket_BlockPlace_m_Count(lua_State* tolua_S)
-{
- cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Count'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_Count = ((char) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* get function: m_Uses of class cPacket_BlockPlace */
-#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_Uses
-static int tolua_get_cPacket_BlockPlace_m_Uses(lua_State* tolua_S)
-{
- cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Uses'",NULL);
-#endif
- tolua_pushnumber(tolua_S,(lua_Number)self->m_Uses);
- return 1;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* set function: m_Uses of class cPacket_BlockPlace */
-#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_Uses
-static int tolua_set_cPacket_BlockPlace_m_Uses(lua_State* tolua_S)
-{
- cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Uses'",NULL);
- if (!tolua_isnumber(tolua_S,2,0,&tolua_err))
- tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
-#endif
- self->m_Uses = ((short) tolua_tonumber(tolua_S,2,0))
-;
- return 0;
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: FillBlocks of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_FillBlocks00
-static int tolua_AllToLua_cLuaChunk_FillBlocks00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
- char a_BlockID = ((char) tolua_tonumber(tolua_S,2,0));
- unsigned char a_BlockMeta = ((unsigned char) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FillBlocks'", NULL);
-#endif
- {
- self->FillBlocks(a_BlockID,a_BlockMeta);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'FillBlocks'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetBlock of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetBlock00
-static int tolua_AllToLua_cLuaChunk_SetBlock00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,5,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,6,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,7,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
- char a_BlockID = ((char) tolua_tonumber(tolua_S,5,0));
- unsigned char a_BlockMeta = ((unsigned char) tolua_tonumber(tolua_S,6,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlock'", NULL);
-#endif
- {
- self->SetBlock(a_X,a_Y,a_Z,a_BlockID,a_BlockMeta);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetBlock'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetBlock of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetBlock00
-static int tolua_AllToLua_cLuaChunk_GetBlock00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlock'", NULL);
-#endif
- {
- char tolua_ret = (char) self->GetBlock(a_X,a_Y,a_Z);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetBlock'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetBlockMeta of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetBlockMeta00
-static int tolua_AllToLua_cLuaChunk_GetBlockMeta00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockMeta'", NULL);
-#endif
- {
- char tolua_ret = (char) self->GetBlockMeta(a_X,a_Y,a_Z);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetBlockMeta'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetBiome of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetBiome00
-static int tolua_AllToLua_cLuaChunk_SetBiome00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,3,0));
- int a_BiomeID = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBiome'", NULL);
-#endif
- {
- self->SetBiome(a_X,a_Z,a_BiomeID);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetBiome'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetBiome of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetBiome00
-static int tolua_AllToLua_cLuaChunk_GetBiome00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBiome'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetBiome(a_X,a_Z);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetBiome'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetHeight of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetHeight00
-static int tolua_AllToLua_cLuaChunk_SetHeight00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Height = ((int) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetHeight'", NULL);
-#endif
- {
- self->SetHeight(a_X,a_Z,a_Height);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetHeight'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetHeight of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetHeight00
-static int tolua_AllToLua_cLuaChunk_GetHeight00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHeight'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetHeight(a_X,a_Z);
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetHeight'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetUseDefaultBiomes of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultBiomes00
-static int tolua_AllToLua_cLuaChunk_SetUseDefaultBiomes00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isboolean(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
- bool a_bUseDefaultBiomes = ((bool) tolua_toboolean(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultBiomes'", NULL);
-#endif
- {
- self->SetUseDefaultBiomes(a_bUseDefaultBiomes);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetUseDefaultBiomes'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: IsUsingDefaultBiomes of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultBiomes00
-static int tolua_AllToLua_cLuaChunk_IsUsingDefaultBiomes00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultBiomes'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->IsUsingDefaultBiomes();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultBiomes'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetUseDefaultComposition of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultComposition00
-static int tolua_AllToLua_cLuaChunk_SetUseDefaultComposition00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isboolean(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
- bool a_bUseDefaultComposition = ((bool) tolua_toboolean(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultComposition'", NULL);
-#endif
- {
- self->SetUseDefaultComposition(a_bUseDefaultComposition);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetUseDefaultComposition'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: IsUsingDefaultComposition of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultComposition00
-static int tolua_AllToLua_cLuaChunk_IsUsingDefaultComposition00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultComposition'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->IsUsingDefaultComposition();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultComposition'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetUseDefaultStructures of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultStructures00
-static int tolua_AllToLua_cLuaChunk_SetUseDefaultStructures00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isboolean(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
- bool a_bUseDefaultStructures = ((bool) tolua_toboolean(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultStructures'", NULL);
-#endif
- {
- self->SetUseDefaultStructures(a_bUseDefaultStructures);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetUseDefaultStructures'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: IsUsingDefaultStructures of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultStructures00
-static int tolua_AllToLua_cLuaChunk_IsUsingDefaultStructures00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultStructures'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->IsUsingDefaultStructures();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultStructures'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetUseDefaultFinish of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultFinish00
-static int tolua_AllToLua_cLuaChunk_SetUseDefaultFinish00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isboolean(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
- bool a_bUseDefaultFinish = ((bool) tolua_toboolean(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultFinish'", NULL);
-#endif
- {
- self->SetUseDefaultFinish(a_bUseDefaultFinish);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetUseDefaultFinish'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: IsUsingDefaultFinish of class cLuaChunk */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultFinish00
-static int tolua_AllToLua_cLuaChunk_IsUsingDefaultFinish00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultFinish'", NULL);
-#endif
- {
- bool tolua_ret = (bool) self->IsUsingDefaultFinish();
- tolua_pushboolean(tolua_S,(bool)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultFinish'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new of class cCraftingGrid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_new00
-static int tolua_AllToLua_cCraftingGrid_new00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cCraftingGrid",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- int a_Width = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Height = ((int) tolua_tonumber(tolua_S,3,0));
- {
- cCraftingGrid* tolua_ret = (cCraftingGrid*) Mtolua_new((cCraftingGrid)(a_Width,a_Height));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCraftingGrid");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: new_local of class cCraftingGrid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_new00_local
-static int tolua_AllToLua_cCraftingGrid_new00_local(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertable(tolua_S,1,"cCraftingGrid",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- int a_Width = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Height = ((int) tolua_tonumber(tolua_S,3,0));
- {
- cCraftingGrid* tolua_ret = (cCraftingGrid*) Mtolua_new((cCraftingGrid)(a_Width,a_Height));
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCraftingGrid");
- tolua_register_gc(tolua_S,lua_gettop(tolua_S));
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetWidth of class cCraftingGrid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_GetWidth00
-static int tolua_AllToLua_cCraftingGrid_GetWidth00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cCraftingGrid",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cCraftingGrid* self = (const cCraftingGrid*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWidth'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetWidth();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetWidth'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetHeight of class cCraftingGrid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_GetHeight00
-static int tolua_AllToLua_cCraftingGrid_GetHeight00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cCraftingGrid",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cCraftingGrid* self = (const cCraftingGrid*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHeight'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetHeight();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetHeight'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetItem of class cCraftingGrid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_GetItem00
-static int tolua_AllToLua_cCraftingGrid_GetItem00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cCraftingGrid",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cCraftingGrid* self = (const cCraftingGrid*) tolua_tousertype(tolua_S,1,0);
- int x = ((int) tolua_tonumber(tolua_S,2,0));
- int y = ((int) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetItem'", NULL);
-#endif
- {
- cItem& tolua_ret = (cItem&) self->GetItem(x,y);
- tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetItem'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetItem of class cCraftingGrid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_SetItem00
-static int tolua_AllToLua_cCraftingGrid_SetItem00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,5,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,6,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,7,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0);
- int x = ((int) tolua_tonumber(tolua_S,2,0));
- int y = ((int) tolua_tonumber(tolua_S,3,0));
- ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,4,0));
- int a_ItemCount = ((int) tolua_tonumber(tolua_S,5,0));
- short a_ItemHealth = ((short) tolua_tonumber(tolua_S,6,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetItem'", NULL);
-#endif
- {
- self->SetItem(x,y,a_ItemType,a_ItemCount,a_ItemHealth);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetItem'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetItem of class cCraftingGrid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_SetItem01
-static int tolua_AllToLua_cCraftingGrid_SetItem01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,4,&tolua_err) || !tolua_isusertype(tolua_S,4,"const cItem",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0);
- int x = ((int) tolua_tonumber(tolua_S,2,0));
- int y = ((int) tolua_tonumber(tolua_S,3,0));
- const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetItem'", NULL);
-#endif
- {
- self->SetItem(x,y,*a_Item);
- }
- }
- return 0;
-tolua_lerror:
- return tolua_AllToLua_cCraftingGrid_SetItem00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Clear of class cCraftingGrid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_Clear00
-static int tolua_AllToLua_cCraftingGrid_Clear00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL);
-#endif
- {
- self->Clear();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: ConsumeGrid of class cCraftingGrid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_ConsumeGrid00
-static int tolua_AllToLua_cCraftingGrid_ConsumeGrid00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cCraftingGrid",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0);
- const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ConsumeGrid'", NULL);
-#endif
- {
- self->ConsumeGrid(*a_Grid);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'ConsumeGrid'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Dump of class cCraftingGrid */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_Dump00
-static int tolua_AllToLua_cCraftingGrid_Dump00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dump'", NULL);
-#endif
- {
- self->Dump();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Dump'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Clear of class cCraftingRecipe */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_Clear00
-static int tolua_AllToLua_cCraftingRecipe_Clear00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL);
-#endif
- {
- self->Clear();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetIngredientsWidth of class cCraftingRecipe */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetIngredientsWidth00
-static int tolua_AllToLua_cCraftingRecipe_GetIngredientsWidth00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIngredientsWidth'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetIngredientsWidth();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetIngredientsWidth'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetIngredientsHeight of class cCraftingRecipe */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetIngredientsHeight00
-static int tolua_AllToLua_cCraftingRecipe_GetIngredientsHeight00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIngredientsHeight'", NULL);
-#endif
- {
- int tolua_ret = (int) self->GetIngredientsHeight();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetIngredientsHeight'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetIngredient of class cCraftingRecipe */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetIngredient00
-static int tolua_AllToLua_cCraftingRecipe_GetIngredient00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0);
- int x = ((int) tolua_tonumber(tolua_S,2,0));
- int y = ((int) tolua_tonumber(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIngredient'", NULL);
-#endif
- {
- cItem& tolua_ret = (cItem&) self->GetIngredient(x,y);
- tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetIngredient'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: GetResult of class cCraftingRecipe */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetResult00
-static int tolua_AllToLua_cCraftingRecipe_GetResult00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetResult'", NULL);
-#endif
- {
- const cItem& tolua_ret = (const cItem&) self->GetResult();
- tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const cItem");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetResult'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetResult of class cCraftingRecipe */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetResult00
-static int tolua_AllToLua_cCraftingRecipe_SetResult00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0);
- ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0));
- int a_ItemCount = ((int) tolua_tonumber(tolua_S,3,0));
- short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetResult'", NULL);
-#endif
- {
- self->SetResult(a_ItemType,a_ItemCount,a_ItemHealth);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetResult'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetResult of class cCraftingRecipe */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetResult01
-static int tolua_AllToLua_cCraftingRecipe_SetResult01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0);
- const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetResult'", NULL);
-#endif
- {
- self->SetResult(*a_Item);
- }
- }
- return 0;
-tolua_lerror:
- return tolua_AllToLua_cCraftingRecipe_SetResult00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetIngredient of class cCraftingRecipe */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetIngredient00
-static int tolua_AllToLua_cCraftingRecipe_SetIngredient00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,5,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,6,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,7,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0);
- int x = ((int) tolua_tonumber(tolua_S,2,0));
- int y = ((int) tolua_tonumber(tolua_S,3,0));
- ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,4,0));
- int a_ItemCount = ((int) tolua_tonumber(tolua_S,5,0));
- short a_ItemHealth = ((short) tolua_tonumber(tolua_S,6,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetIngredient'", NULL);
-#endif
- {
- self->SetIngredient(x,y,a_ItemType,a_ItemCount,a_ItemHealth);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SetIngredient'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: SetIngredient of class cCraftingRecipe */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetIngredient01
-static int tolua_AllToLua_cCraftingRecipe_SetIngredient01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,4,&tolua_err) || !tolua_isusertype(tolua_S,4,"const cItem",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0);
- int x = ((int) tolua_tonumber(tolua_S,2,0));
- int y = ((int) tolua_tonumber(tolua_S,3,0));
- const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetIngredient'", NULL);
-#endif
- {
- self->SetIngredient(x,y,*a_Item);
- }
- }
- return 0;
-tolua_lerror:
- return tolua_AllToLua_cCraftingRecipe_SetIngredient00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: ConsumeIngredients of class cCraftingRecipe */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_ConsumeIngredients00
-static int tolua_AllToLua_cCraftingRecipe_ConsumeIngredients00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cCraftingGrid",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0);
- cCraftingGrid* a_CraftingGrid = ((cCraftingGrid*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ConsumeIngredients'", NULL);
-#endif
- {
- self->ConsumeIngredients(*a_CraftingGrid);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'ConsumeIngredients'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Dump of class cCraftingRecipe */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_Dump00
-static int tolua_AllToLua_cCraftingRecipe_Dump00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dump'", NULL);
-#endif
- {
- self->Dump();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Dump'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Get of class cLuaItems */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Get00
-static int tolua_AllToLua_cLuaItems_Get00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0);
- int a_Idx = ((int) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Get'", NULL);
-#endif
- {
- cItem& tolua_ret = (cItem&) self->Get(a_Idx);
- tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem");
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Get'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Set of class cLuaItems */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Set00
-static int tolua_AllToLua_cLuaItems_Set00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const cItem",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0);
- int a_Idx = ((int) tolua_tonumber(tolua_S,2,0));
- const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL);
-#endif
- {
- self->Set(a_Idx,*a_Item);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Add of class cLuaItems */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Add00
-static int tolua_AllToLua_cLuaItems_Add00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0);
- const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Add'", NULL);
-#endif
- {
- self->Add(*a_Item);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Add'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Delete of class cLuaItems */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Delete00
-static int tolua_AllToLua_cLuaItems_Delete00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0);
- int a_Idx = ((int) tolua_tonumber(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Delete'", NULL);
-#endif
- {
- self->Delete(a_Idx);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Delete'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Clear of class cLuaItems */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Clear00
-static int tolua_AllToLua_cLuaItems_Clear00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL);
-#endif
- {
- self->Clear();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Size of class cLuaItems */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Size00
-static int tolua_AllToLua_cLuaItems_Size00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0);
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Size'", NULL);
-#endif
- {
- int tolua_ret = (int) self->Size();
- tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
- }
- }
- return 1;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'Size'.",&tolua_err);
- return 0;
-#endif
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Add of class cLuaItems */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Add01
-static int tolua_AllToLua_cLuaItems_Add01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,5,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0);
- ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0));
- char a_ItemCount = ((char) tolua_tonumber(tolua_S,3,0));
- short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Add'", NULL);
-#endif
- {
- self->Add(a_ItemType,a_ItemCount,a_ItemHealth);
- }
- }
- return 0;
-tolua_lerror:
- return tolua_AllToLua_cLuaItems_Add00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* method: Set of class cLuaItems */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Set01
-static int tolua_AllToLua_cLuaItems_Set01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) ||
- !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
- !tolua_isnumber(tolua_S,5,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,6,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
- cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0);
- int a_Idx = ((int) tolua_tonumber(tolua_S,2,0));
- ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,3,0));
- char a_ItemCount = ((char) tolua_tonumber(tolua_S,4,0));
- short a_ItemHealth = ((short) tolua_tonumber(tolua_S,5,0));
-#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL);
-#endif
- {
- self->Set(a_Idx,a_ItemType,a_ItemCount,a_ItemHealth);
- }
- }
- return 0;
-tolua_lerror:
- return tolua_AllToLua_cLuaItems_Set00(tolua_S);
-}
-#endif //#ifndef TOLUA_DISABLE
-
-/* Open function */
-TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
-{
- tolua_open(tolua_S);
- tolua_reg_types(tolua_S);
- tolua_module(tolua_S,NULL,1);
- tolua_beginmodule(tolua_S,NULL);
- tolua_cclass(tolua_S,"cTorch","cTorch","",NULL);
- tolua_beginmodule(tolua_S,"cTorch");
- tolua_function(tolua_S,"DirectionToMetaData",tolua_AllToLua_cTorch_DirectionToMetaData00);
- tolua_function(tolua_S,"MetaDataToDirection",tolua_AllToLua_cTorch_MetaDataToDirection00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cStairs","cStairs","",NULL);
- tolua_beginmodule(tolua_S,"cStairs");
- tolua_function(tolua_S,"RotationToMetaData",tolua_AllToLua_cStairs_RotationToMetaData00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cStep","cStep","",NULL);
- tolua_beginmodule(tolua_S,"cStep");
- tolua_function(tolua_S,"DirectionToMetaData",tolua_AllToLua_cStep_DirectionToMetaData00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cLadder","cLadder","",NULL);
- tolua_beginmodule(tolua_S,"cLadder");
- tolua_function(tolua_S,"DirectionToMetaData",tolua_AllToLua_cLadder_DirectionToMetaData00);
- tolua_function(tolua_S,"MetaDataToDirection",tolua_AllToLua_cLadder_MetaDataToDirection00);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"cIniFile","cIniFile","",tolua_collect_cIniFile);
- #else
- tolua_cclass(tolua_S,"cIniFile","cIniFile","",NULL);
- #endif
- tolua_beginmodule(tolua_S,"cIniFile");
- tolua_constant(tolua_S,"noID",cIniFile::noID);
- tolua_function(tolua_S,"new",tolua_AllToLua_cIniFile_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_cIniFile_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_cIniFile_new00_local);
- tolua_function(tolua_S,"CaseSensitive",tolua_AllToLua_cIniFile_CaseSensitive00);
- tolua_function(tolua_S,"CaseInsensitive",tolua_AllToLua_cIniFile_CaseInsensitive00);
- tolua_function(tolua_S,"Path",tolua_AllToLua_cIniFile_Path00);
- tolua_function(tolua_S,"Path",tolua_AllToLua_cIniFile_Path01);
- tolua_function(tolua_S,"SetPath",tolua_AllToLua_cIniFile_SetPath00);
- tolua_function(tolua_S,"ReadFile",tolua_AllToLua_cIniFile_ReadFile00);
- tolua_function(tolua_S,"WriteFile",tolua_AllToLua_cIniFile_WriteFile00);
- tolua_function(tolua_S,"Erase",tolua_AllToLua_cIniFile_Erase00);
- tolua_function(tolua_S,"Clear",tolua_AllToLua_cIniFile_Clear00);
- tolua_function(tolua_S,"Reset",tolua_AllToLua_cIniFile_Reset00);
- tolua_function(tolua_S,"FindKey",tolua_AllToLua_cIniFile_FindKey00);
- tolua_function(tolua_S,"FindValue",tolua_AllToLua_cIniFile_FindValue00);
- tolua_function(tolua_S,"NumKeys",tolua_AllToLua_cIniFile_NumKeys00);
- tolua_function(tolua_S,"GetNumKeys",tolua_AllToLua_cIniFile_GetNumKeys00);
- tolua_function(tolua_S,"AddKeyName",tolua_AllToLua_cIniFile_AddKeyName00);
- tolua_function(tolua_S,"KeyName",tolua_AllToLua_cIniFile_KeyName00);
- tolua_function(tolua_S,"GetKeyName",tolua_AllToLua_cIniFile_GetKeyName00);
- tolua_function(tolua_S,"NumValues",tolua_AllToLua_cIniFile_NumValues00);
- tolua_function(tolua_S,"GetNumValues",tolua_AllToLua_cIniFile_GetNumValues00);
- tolua_function(tolua_S,"NumValues",tolua_AllToLua_cIniFile_NumValues01);
- tolua_function(tolua_S,"GetNumValues",tolua_AllToLua_cIniFile_GetNumValues01);
- tolua_function(tolua_S,"ValueName",tolua_AllToLua_cIniFile_ValueName00);
- tolua_function(tolua_S,"GetValueName",tolua_AllToLua_cIniFile_GetValueName00);
- tolua_function(tolua_S,"ValueName",tolua_AllToLua_cIniFile_ValueName01);
- tolua_function(tolua_S,"GetValueName",tolua_AllToLua_cIniFile_GetValueName01);
- tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue00);
- tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue01);
- tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue02);
- tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue03);
- tolua_function(tolua_S,"GetValueF",tolua_AllToLua_cIniFile_GetValueF00);
- tolua_function(tolua_S,"GetValueI",tolua_AllToLua_cIniFile_GetValueI00);
- tolua_function(tolua_S,"GetValueB",tolua_AllToLua_cIniFile_GetValueB00);
- tolua_function(tolua_S,"GetValueSet",tolua_AllToLua_cIniFile_GetValueSet00);
- tolua_function(tolua_S,"GetValueSet",tolua_AllToLua_cIniFile_GetValueSet01);
- tolua_function(tolua_S,"GetValueSetF",tolua_AllToLua_cIniFile_GetValueSetF00);
- tolua_function(tolua_S,"GetValueSetI",tolua_AllToLua_cIniFile_GetValueSetI00);
- tolua_function(tolua_S,"GetValueSetB",tolua_AllToLua_cIniFile_GetValueSetB00);
- tolua_function(tolua_S,"SetValue",tolua_AllToLua_cIniFile_SetValue00);
- tolua_function(tolua_S,"SetValue",tolua_AllToLua_cIniFile_SetValue01);
- tolua_function(tolua_S,"SetValueI",tolua_AllToLua_cIniFile_SetValueI00);
- tolua_function(tolua_S,"SetValueB",tolua_AllToLua_cIniFile_SetValueB00);
- tolua_function(tolua_S,"SetValueF",tolua_AllToLua_cIniFile_SetValueF00);
- tolua_function(tolua_S,"DeleteValueByID",tolua_AllToLua_cIniFile_DeleteValueByID00);
- tolua_function(tolua_S,"DeleteValue",tolua_AllToLua_cIniFile_DeleteValue00);
- tolua_function(tolua_S,"DeleteKey",tolua_AllToLua_cIniFile_DeleteKey00);
- tolua_function(tolua_S,"NumHeaderComments",tolua_AllToLua_cIniFile_NumHeaderComments00);
- tolua_function(tolua_S,"HeaderComment",tolua_AllToLua_cIniFile_HeaderComment00);
- tolua_function(tolua_S,"HeaderComment",tolua_AllToLua_cIniFile_HeaderComment01);
- tolua_function(tolua_S,"DeleteHeaderComment",tolua_AllToLua_cIniFile_DeleteHeaderComment00);
- tolua_function(tolua_S,"DeleteHeaderComments",tolua_AllToLua_cIniFile_DeleteHeaderComments00);
- tolua_function(tolua_S,"NumKeyComments",tolua_AllToLua_cIniFile_NumKeyComments00);
- tolua_function(tolua_S,"NumKeyComments",tolua_AllToLua_cIniFile_NumKeyComments01);
- tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment00);
- tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment01);
- tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment02);
- tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment03);
- tolua_function(tolua_S,"DeleteKeyComment",tolua_AllToLua_cIniFile_DeleteKeyComment00);
- tolua_function(tolua_S,"DeleteKeyComment",tolua_AllToLua_cIniFile_DeleteKeyComment01);
- tolua_function(tolua_S,"DeleteKeyComments",tolua_AllToLua_cIniFile_DeleteKeyComments00);
- tolua_function(tolua_S,"DeleteKeyComments",tolua_AllToLua_cIniFile_DeleteKeyComments01);
- tolua_endmodule(tolua_S);
- tolua_constant(tolua_S,"E_BLOCK_AIR",E_BLOCK_AIR);
- tolua_constant(tolua_S,"E_BLOCK_STONE",E_BLOCK_STONE);
- tolua_constant(tolua_S,"E_BLOCK_GRASS",E_BLOCK_GRASS);
- tolua_constant(tolua_S,"E_BLOCK_DIRT",E_BLOCK_DIRT);
- tolua_constant(tolua_S,"E_BLOCK_COBBLESTONE",E_BLOCK_COBBLESTONE);
- tolua_constant(tolua_S,"E_BLOCK_PLANKS",E_BLOCK_PLANKS);
- tolua_constant(tolua_S,"E_BLOCK_WOOD",E_BLOCK_WOOD);
- tolua_constant(tolua_S,"E_BLOCK_SAPLING",E_BLOCK_SAPLING);
- tolua_constant(tolua_S,"E_BLOCK_BEDROCK",E_BLOCK_BEDROCK);
- tolua_constant(tolua_S,"E_BLOCK_WATER",E_BLOCK_WATER);
- tolua_constant(tolua_S,"E_BLOCK_STATIONARY_WATER",E_BLOCK_STATIONARY_WATER);
- tolua_constant(tolua_S,"E_BLOCK_LAVA",E_BLOCK_LAVA);
- tolua_constant(tolua_S,"E_BLOCK_STATIONARY_LAVA",E_BLOCK_STATIONARY_LAVA);
- tolua_constant(tolua_S,"E_BLOCK_SAND",E_BLOCK_SAND);
- tolua_constant(tolua_S,"E_BLOCK_GRAVEL",E_BLOCK_GRAVEL);
- tolua_constant(tolua_S,"E_BLOCK_GOLD_ORE",E_BLOCK_GOLD_ORE);
- tolua_constant(tolua_S,"E_BLOCK_IRON_ORE",E_BLOCK_IRON_ORE);
- tolua_constant(tolua_S,"E_BLOCK_COAL_ORE",E_BLOCK_COAL_ORE);
- tolua_constant(tolua_S,"E_BLOCK_LOG",E_BLOCK_LOG);
- tolua_constant(tolua_S,"E_BLOCK_LEAVES",E_BLOCK_LEAVES);
- tolua_constant(tolua_S,"E_BLOCK_SPONGE",E_BLOCK_SPONGE);
- tolua_constant(tolua_S,"E_BLOCK_GLASS",E_BLOCK_GLASS);
- tolua_constant(tolua_S,"E_BLOCK_LAPIS_ORE",E_BLOCK_LAPIS_ORE);
- tolua_constant(tolua_S,"E_BLOCK_LAPIS_BLOCK",E_BLOCK_LAPIS_BLOCK);
- tolua_constant(tolua_S,"E_BLOCK_DISPENSER",E_BLOCK_DISPENSER);
- tolua_constant(tolua_S,"E_BLOCK_SANDSTONE",E_BLOCK_SANDSTONE);
- tolua_constant(tolua_S,"E_BLOCK_NOTE_BLOCK",E_BLOCK_NOTE_BLOCK);
- tolua_constant(tolua_S,"E_BLOCK_BED",E_BLOCK_BED);
- tolua_constant(tolua_S,"E_BLOCK_POWERED_RAIL",E_BLOCK_POWERED_RAIL);
- tolua_constant(tolua_S,"E_BLOCK_DETECTOR_RAIL",E_BLOCK_DETECTOR_RAIL);
- tolua_constant(tolua_S,"E_BLOCK_STICKY_PISTON",E_BLOCK_STICKY_PISTON);
- tolua_constant(tolua_S,"E_BLOCK_COBWEB",E_BLOCK_COBWEB);
- tolua_constant(tolua_S,"E_BLOCK_TALL_GRASS",E_BLOCK_TALL_GRASS);
- tolua_constant(tolua_S,"E_BLOCK_DEAD_BUSH",E_BLOCK_DEAD_BUSH);
- tolua_constant(tolua_S,"E_BLOCK_PISTON",E_BLOCK_PISTON);
- tolua_constant(tolua_S,"E_BLOCK_PISTON_EXTENSION",E_BLOCK_PISTON_EXTENSION);
- tolua_constant(tolua_S,"E_BLOCK_WHITE_CLOTH",E_BLOCK_WHITE_CLOTH);
- tolua_constant(tolua_S,"E_BLOCK_WOOL",E_BLOCK_WOOL);
- tolua_constant(tolua_S,"E_BLOCK_PISTON_MOVED_BLOCK",E_BLOCK_PISTON_MOVED_BLOCK);
- tolua_constant(tolua_S,"E_BLOCK_YELLOW_FLOWER",E_BLOCK_YELLOW_FLOWER);
- tolua_constant(tolua_S,"E_BLOCK_RED_ROSE",E_BLOCK_RED_ROSE);
- tolua_constant(tolua_S,"E_BLOCK_BROWN_MUSHROOM",E_BLOCK_BROWN_MUSHROOM);
- tolua_constant(tolua_S,"E_BLOCK_RED_MUSHROOM",E_BLOCK_RED_MUSHROOM);
- tolua_constant(tolua_S,"E_BLOCK_GOLD_BLOCK",E_BLOCK_GOLD_BLOCK);
- tolua_constant(tolua_S,"E_BLOCK_IRON_BLOCK",E_BLOCK_IRON_BLOCK);
- tolua_constant(tolua_S,"E_BLOCK_DOUBLE_STONE_SLAB",E_BLOCK_DOUBLE_STONE_SLAB);
- tolua_constant(tolua_S,"E_BLOCK_DOUBLE_STEP",E_BLOCK_DOUBLE_STEP);
- tolua_constant(tolua_S,"E_BLOCK_STONE_SLAB",E_BLOCK_STONE_SLAB);
- tolua_constant(tolua_S,"E_BLOCK_STEP",E_BLOCK_STEP);
- tolua_constant(tolua_S,"E_BLOCK_BRICK",E_BLOCK_BRICK);
- tolua_constant(tolua_S,"E_BLOCK_TNT",E_BLOCK_TNT);
- tolua_constant(tolua_S,"E_BLOCK_BOOKCASE",E_BLOCK_BOOKCASE);
- tolua_constant(tolua_S,"E_BLOCK_MOSSY_COBBLESTONE",E_BLOCK_MOSSY_COBBLESTONE);
- tolua_constant(tolua_S,"E_BLOCK_OBSIDIAN",E_BLOCK_OBSIDIAN);
- tolua_constant(tolua_S,"E_BLOCK_TORCH",E_BLOCK_TORCH);
- tolua_constant(tolua_S,"E_BLOCK_FIRE",E_BLOCK_FIRE);
- tolua_constant(tolua_S,"E_BLOCK_MOB_SPAWNER",E_BLOCK_MOB_SPAWNER);
- tolua_constant(tolua_S,"E_BLOCK_WOODEN_STAIRS",E_BLOCK_WOODEN_STAIRS);
- tolua_constant(tolua_S,"E_BLOCK_CHEST",E_BLOCK_CHEST);
- tolua_constant(tolua_S,"E_BLOCK_REDSTONE_WIRE",E_BLOCK_REDSTONE_WIRE);
- tolua_constant(tolua_S,"E_BLOCK_DIAMOND_ORE",E_BLOCK_DIAMOND_ORE);
- tolua_constant(tolua_S,"E_BLOCK_DIAMOND_BLOCK",E_BLOCK_DIAMOND_BLOCK);
- tolua_constant(tolua_S,"E_BLOCK_CRAFTING_TABLE",E_BLOCK_CRAFTING_TABLE);
- tolua_constant(tolua_S,"E_BLOCK_WORKBENCH",E_BLOCK_WORKBENCH);
- tolua_constant(tolua_S,"E_BLOCK_CROPS",E_BLOCK_CROPS);
- tolua_constant(tolua_S,"E_BLOCK_SOIL",E_BLOCK_SOIL);
- tolua_constant(tolua_S,"E_BLOCK_FARMLAND",E_BLOCK_FARMLAND);
- tolua_constant(tolua_S,"E_BLOCK_FURNACE",E_BLOCK_FURNACE);
- tolua_constant(tolua_S,"E_BLOCK_LIT_FURNACE",E_BLOCK_LIT_FURNACE);
- tolua_constant(tolua_S,"E_BLOCK_BURNING_FURNACE",E_BLOCK_BURNING_FURNACE);
- tolua_constant(tolua_S,"E_BLOCK_SIGN_POST",E_BLOCK_SIGN_POST);
- tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOOR",E_BLOCK_WOODEN_DOOR);
- tolua_constant(tolua_S,"E_BLOCK_LADDER",E_BLOCK_LADDER);
- tolua_constant(tolua_S,"E_BLOCK_RAIL",E_BLOCK_RAIL);
- tolua_constant(tolua_S,"E_BLOCK_MINECART_TRACKS",E_BLOCK_MINECART_TRACKS);
- tolua_constant(tolua_S,"E_BLOCK_COBBLESTONE_STAIRS",E_BLOCK_COBBLESTONE_STAIRS);
- tolua_constant(tolua_S,"E_BLOCK_WALLSIGN",E_BLOCK_WALLSIGN);
- tolua_constant(tolua_S,"E_BLOCK_LEVER",E_BLOCK_LEVER);
- tolua_constant(tolua_S,"E_BLOCK_STONE_PRESSURE_PLATE",E_BLOCK_STONE_PRESSURE_PLATE);
- tolua_constant(tolua_S,"E_BLOCK_IRON_DOOR",E_BLOCK_IRON_DOOR);
- tolua_constant(tolua_S,"E_BLOCK_WOODEN_PRESSURE_PLATE",E_BLOCK_WOODEN_PRESSURE_PLATE);
- tolua_constant(tolua_S,"E_BLOCK_REDSTONE_ORE",E_BLOCK_REDSTONE_ORE);
- tolua_constant(tolua_S,"E_BLOCK_REDSTONE_ORE_GLOWING",E_BLOCK_REDSTONE_ORE_GLOWING);
- tolua_constant(tolua_S,"E_BLOCK_REDSTONE_TORCH_OFF",E_BLOCK_REDSTONE_TORCH_OFF);
- tolua_constant(tolua_S,"E_BLOCK_REDSTONE_TORCH_ON",E_BLOCK_REDSTONE_TORCH_ON);
- tolua_constant(tolua_S,"E_BLOCK_STONE_BUTTON",E_BLOCK_STONE_BUTTON);
- tolua_constant(tolua_S,"E_BLOCK_SNOW",E_BLOCK_SNOW);
- tolua_constant(tolua_S,"E_BLOCK_ICE",E_BLOCK_ICE);
- tolua_constant(tolua_S,"E_BLOCK_SNOW_BLOCK",E_BLOCK_SNOW_BLOCK);
- tolua_constant(tolua_S,"E_BLOCK_CACTUS",E_BLOCK_CACTUS);
- tolua_constant(tolua_S,"E_BLOCK_CLAY",E_BLOCK_CLAY);
- tolua_constant(tolua_S,"E_BLOCK_SUGARCANE",E_BLOCK_SUGARCANE);
- tolua_constant(tolua_S,"E_BLOCK_REEDS",E_BLOCK_REEDS);
- tolua_constant(tolua_S,"E_BLOCK_JUKEBOX",E_BLOCK_JUKEBOX);
- tolua_constant(tolua_S,"E_BLOCK_FENCE",E_BLOCK_FENCE);
- tolua_constant(tolua_S,"E_BLOCK_PUMPKIN",E_BLOCK_PUMPKIN);
- tolua_constant(tolua_S,"E_BLOCK_BLOODSTONE",E_BLOCK_BLOODSTONE);
- tolua_constant(tolua_S,"E_BLOCK_NETHERRACK",E_BLOCK_NETHERRACK);
- tolua_constant(tolua_S,"E_BLOCK_SOULSAND",E_BLOCK_SOULSAND);
- tolua_constant(tolua_S,"E_BLOCK_GLOWSTONE",E_BLOCK_GLOWSTONE);
- tolua_constant(tolua_S,"E_BLOCK_PORT",E_BLOCK_PORT);
- tolua_constant(tolua_S,"E_BLOCK_NETHER_PORTAL",E_BLOCK_NETHER_PORTAL);
- tolua_constant(tolua_S,"E_BLOCK_JACK_O_LANTERN",E_BLOCK_JACK_O_LANTERN);
- tolua_constant(tolua_S,"E_BLOCK_CAKE",E_BLOCK_CAKE);
- tolua_constant(tolua_S,"E_BLOCK_REDSTONE_REPEATER_OFF",E_BLOCK_REDSTONE_REPEATER_OFF);
- tolua_constant(tolua_S,"E_BLOCK_REDSTONE_REPEATER_ON",E_BLOCK_REDSTONE_REPEATER_ON);
- tolua_constant(tolua_S,"E_BLOCK_LOCKED_CHEST",E_BLOCK_LOCKED_CHEST);
- tolua_constant(tolua_S,"E_BLOCK_TRAPDOOR",E_BLOCK_TRAPDOOR);
- tolua_constant(tolua_S,"E_BLOCK_SILVERFISH_EGG",E_BLOCK_SILVERFISH_EGG);
- tolua_constant(tolua_S,"E_BLOCK_STONE_BRICKS",E_BLOCK_STONE_BRICKS);
- tolua_constant(tolua_S,"E_BLOCK_HUGE_BROWN_MUSHROOM",E_BLOCK_HUGE_BROWN_MUSHROOM);
- tolua_constant(tolua_S,"E_BLOCK_HUGE_RED_MUSHROOM",E_BLOCK_HUGE_RED_MUSHROOM);
- tolua_constant(tolua_S,"E_BLOCK_IRON_BAR",E_BLOCK_IRON_BAR);
- tolua_constant(tolua_S,"E_BLOCK_GLASS_PLANE",E_BLOCK_GLASS_PLANE);
- tolua_constant(tolua_S,"E_BLOCK_MELON",E_BLOCK_MELON);
- tolua_constant(tolua_S,"E_BLOCK_PUMPKIN_STEM",E_BLOCK_PUMPKIN_STEM);
- tolua_constant(tolua_S,"E_BLOCK_MELON_STEM",E_BLOCK_MELON_STEM);
- tolua_constant(tolua_S,"E_BLOCK_VINES",E_BLOCK_VINES);
- tolua_constant(tolua_S,"E_BLOCK_FENCE_GATE",E_BLOCK_FENCE_GATE);
- tolua_constant(tolua_S,"E_BLOCK_BRICK_STAIRS",E_BLOCK_BRICK_STAIRS);
- tolua_constant(tolua_S,"E_BLOCK_STONE_BRICK_STAIRS",E_BLOCK_STONE_BRICK_STAIRS);
- tolua_constant(tolua_S,"E_BLOCK_MYCELIUM",E_BLOCK_MYCELIUM);
- tolua_constant(tolua_S,"E_BLOCK_LILY_PAD",E_BLOCK_LILY_PAD);
- tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK",E_BLOCK_NETHER_BRICK);
- tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK_FENCE",E_BLOCK_NETHER_BRICK_FENCE);
- tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK_STAIRS",E_BLOCK_NETHER_BRICK_STAIRS);
- tolua_constant(tolua_S,"E_BLOCK_NETHER_WART",E_BLOCK_NETHER_WART);
- tolua_constant(tolua_S,"E_BLOCK_ENCHANTMENT_TABLE",E_BLOCK_ENCHANTMENT_TABLE);
- tolua_constant(tolua_S,"E_BLOCK_BREWING_STAND",E_BLOCK_BREWING_STAND);
- tolua_constant(tolua_S,"E_BLOCK_CAULDRON",E_BLOCK_CAULDRON);
- tolua_constant(tolua_S,"E_BLOCK_END_PORTAL",E_BLOCK_END_PORTAL);
- tolua_constant(tolua_S,"E_BLOCK_END_PORTAL_FRAME",E_BLOCK_END_PORTAL_FRAME);
- tolua_constant(tolua_S,"E_BLOCK_END_STONE",E_BLOCK_END_STONE);
- tolua_constant(tolua_S,"E_BLOCK_DRAGON_EGG",E_BLOCK_DRAGON_EGG);
- tolua_constant(tolua_S,"E_BLOCK_REDSTONE_LAMP_OFF",E_BLOCK_REDSTONE_LAMP_OFF);
- tolua_constant(tolua_S,"E_BLOCK_REDSTONE_LAMP_ON",E_BLOCK_REDSTONE_LAMP_ON);
- tolua_constant(tolua_S,"E_BLOCK_DOUBLE_WOODEN_SLAB",E_BLOCK_DOUBLE_WOODEN_SLAB);
- tolua_constant(tolua_S,"E_BLOCK_WOODEN_SLAB",E_BLOCK_WOODEN_SLAB);
- tolua_constant(tolua_S,"E_BLOCK_COCA_PLANT",E_BLOCK_COCA_PLANT);
- tolua_constant(tolua_S,"E_BLOCK_SANDSTONE_STAIRS",E_BLOCK_SANDSTONE_STAIRS);
- tolua_constant(tolua_S,"E_BLOCK_EMERALD_ORE",E_BLOCK_EMERALD_ORE);
- tolua_constant(tolua_S,"E_BLOCK_ENDER_CHEST",E_BLOCK_ENDER_CHEST);
- tolua_constant(tolua_S,"E_BLOCK_TRIPWIRE_HOOK",E_BLOCK_TRIPWIRE_HOOK);
- tolua_constant(tolua_S,"E_BLOCK_TRIPWIRE",E_BLOCK_TRIPWIRE);
- tolua_constant(tolua_S,"E_BLOCK_EMERALD_BLOCK",E_BLOCK_EMERALD_BLOCK);
- tolua_constant(tolua_S,"E_BLOCK_",E_BLOCK_);
- tolua_constant(tolua_S,"E_ITEM_EMPTY",E_ITEM_EMPTY);
- tolua_constant(tolua_S,"E_ITEM_STONE",E_ITEM_STONE);
- tolua_constant(tolua_S,"E_ITEM_GRASS",E_ITEM_GRASS);
- tolua_constant(tolua_S,"E_ITEM_DIRT",E_ITEM_DIRT);
- tolua_constant(tolua_S,"E_ITEM_COBBLESTONE",E_ITEM_COBBLESTONE);
- tolua_constant(tolua_S,"E_ITEM_PLANKS",E_ITEM_PLANKS);
- tolua_constant(tolua_S,"E_ITEM_WOOD",E_ITEM_WOOD);
- tolua_constant(tolua_S,"E_ITEM_SAPLING",E_ITEM_SAPLING);
- tolua_constant(tolua_S,"E_ITEM_BEDROCK",E_ITEM_BEDROCK);
- tolua_constant(tolua_S,"E_ITEM_WATER",E_ITEM_WATER);
- tolua_constant(tolua_S,"E_ITEM_STATIONARY_WATER",E_ITEM_STATIONARY_WATER);
- tolua_constant(tolua_S,"E_ITEM_LAVA",E_ITEM_LAVA);
- tolua_constant(tolua_S,"E_ITEM_STATIONARY_LAVA",E_ITEM_STATIONARY_LAVA);
- tolua_constant(tolua_S,"E_ITEM_SAND",E_ITEM_SAND);
- tolua_constant(tolua_S,"E_ITEM_GRAVEL",E_ITEM_GRAVEL);
- tolua_constant(tolua_S,"E_ITEM_GOLD_ORE",E_ITEM_GOLD_ORE);
- tolua_constant(tolua_S,"E_ITEM_IRON_ORE",E_ITEM_IRON_ORE);
- tolua_constant(tolua_S,"E_ITEM_COAL_ORE",E_ITEM_COAL_ORE);
- tolua_constant(tolua_S,"E_ITEM_LOG",E_ITEM_LOG);
- tolua_constant(tolua_S,"E_ITEM_LEAVES",E_ITEM_LEAVES);
- tolua_constant(tolua_S,"E_ITEM_SPONGE",E_ITEM_SPONGE);
- tolua_constant(tolua_S,"E_ITEM_GLASS",E_ITEM_GLASS);
- tolua_constant(tolua_S,"E_ITEM_LAPIS_ORE",E_ITEM_LAPIS_ORE);
- tolua_constant(tolua_S,"E_ITEM_LAPIS_BLOCK",E_ITEM_LAPIS_BLOCK);
- tolua_constant(tolua_S,"E_ITEM_DISPENSER",E_ITEM_DISPENSER);
- tolua_constant(tolua_S,"E_ITEM_SANDSTONE",E_ITEM_SANDSTONE);
- tolua_constant(tolua_S,"E_ITEM_NOTE_ITEM",E_ITEM_NOTE_ITEM);
- tolua_constant(tolua_S,"E_ITEM_POWERED_RAIL",E_ITEM_POWERED_RAIL);
- tolua_constant(tolua_S,"E_ITEM_DETECTOR_RAIL",E_ITEM_DETECTOR_RAIL);
- tolua_constant(tolua_S,"E_ITEM_STICKY_PISTON",E_ITEM_STICKY_PISTON);
- tolua_constant(tolua_S,"E_ITEM_COBWEB",E_ITEM_COBWEB);
- tolua_constant(tolua_S,"E_ITEM_TALL_GRASS",E_ITEM_TALL_GRASS);
- tolua_constant(tolua_S,"E_ITEM_DEAD_BRUSH",E_ITEM_DEAD_BRUSH);
- tolua_constant(tolua_S,"E_ITEM_PISTON",E_ITEM_PISTON);
- tolua_constant(tolua_S,"E_ITEM_PISTON_EXTENSION",E_ITEM_PISTON_EXTENSION);
- tolua_constant(tolua_S,"E_ITEM_WHITE_CLOTH",E_ITEM_WHITE_CLOTH);
- tolua_constant(tolua_S,"E_ITEM_PISTON_MOVED_BLOCK",E_ITEM_PISTON_MOVED_BLOCK);
- tolua_constant(tolua_S,"E_ITEM_YELLOW_FLOWER",E_ITEM_YELLOW_FLOWER);
- tolua_constant(tolua_S,"E_ITEM_RED_ROSE",E_ITEM_RED_ROSE);
- tolua_constant(tolua_S,"E_ITEM_BROWN_MUSHROOM",E_ITEM_BROWN_MUSHROOM);
- tolua_constant(tolua_S,"E_ITEM_RED_MUSHROOM",E_ITEM_RED_MUSHROOM);
- tolua_constant(tolua_S,"E_ITEM_GOLD_BLOCK",E_ITEM_GOLD_BLOCK);
- tolua_constant(tolua_S,"E_ITEM_IRON_BLOCK",E_ITEM_IRON_BLOCK);
- tolua_constant(tolua_S,"E_ITEM_DOUBLE_STONE_SLAB",E_ITEM_DOUBLE_STONE_SLAB);
- tolua_constant(tolua_S,"E_ITEM_DOUBLE_STEP",E_ITEM_DOUBLE_STEP);
- tolua_constant(tolua_S,"E_ITEM_STONE_SLAB",E_ITEM_STONE_SLAB);
- tolua_constant(tolua_S,"E_ITEM_STEP",E_ITEM_STEP);
- tolua_constant(tolua_S,"E_ITEM_BRICK",E_ITEM_BRICK);
- tolua_constant(tolua_S,"E_ITEM_TNT",E_ITEM_TNT);
- tolua_constant(tolua_S,"E_ITEM_BOOKCASE",E_ITEM_BOOKCASE);
- tolua_constant(tolua_S,"E_ITEM_MOSSY_COBBLESTONE",E_ITEM_MOSSY_COBBLESTONE);
- tolua_constant(tolua_S,"E_ITEM_OBSIDIAN",E_ITEM_OBSIDIAN);
- tolua_constant(tolua_S,"E_ITEM_TORCH",E_ITEM_TORCH);
- tolua_constant(tolua_S,"E_ITEM_FIRE",E_ITEM_FIRE);
- tolua_constant(tolua_S,"E_ITEM_MOB_SPAWNER",E_ITEM_MOB_SPAWNER);
- tolua_constant(tolua_S,"E_ITEM_WOODEN_STAIRS",E_ITEM_WOODEN_STAIRS);
- tolua_constant(tolua_S,"E_ITEM_CHEST",E_ITEM_CHEST);
- tolua_constant(tolua_S,"E_ITEM_REDSTONE_WIRE",E_ITEM_REDSTONE_WIRE);
- tolua_constant(tolua_S,"E_ITEM_DIAMOND_ORE",E_ITEM_DIAMOND_ORE);
- tolua_constant(tolua_S,"E_ITEM_DIAMOND_BLOCK",E_ITEM_DIAMOND_BLOCK);
- tolua_constant(tolua_S,"E_ITEM_WORKBENCH",E_ITEM_WORKBENCH);
- tolua_constant(tolua_S,"E_ITEM_CROPS",E_ITEM_CROPS);
- tolua_constant(tolua_S,"E_ITEM_SOIL",E_ITEM_SOIL);
- tolua_constant(tolua_S,"E_ITEM_FURNACE",E_ITEM_FURNACE);
- tolua_constant(tolua_S,"E_ITEM_BURNING_FURNACE",E_ITEM_BURNING_FURNACE);
- tolua_constant(tolua_S,"E_ITEM_SIGN_POST",E_ITEM_SIGN_POST);
- tolua_constant(tolua_S,"E_ITEM_LADDER",E_ITEM_LADDER);
- tolua_constant(tolua_S,"E_ITEM_MINECART_TRACKS",E_ITEM_MINECART_TRACKS);
- tolua_constant(tolua_S,"E_ITEM_COBBLESTONE_STAIRS",E_ITEM_COBBLESTONE_STAIRS);
- tolua_constant(tolua_S,"E_ITEM_WALLSIGN",E_ITEM_WALLSIGN);
- tolua_constant(tolua_S,"E_ITEM_LEVER",E_ITEM_LEVER);
- tolua_constant(tolua_S,"E_ITEM_STONE_PRESSURE_PLATE",E_ITEM_STONE_PRESSURE_PLATE);
- tolua_constant(tolua_S,"E_ITEM_WOODEN_PRESSURE_PLATE",E_ITEM_WOODEN_PRESSURE_PLATE);
- tolua_constant(tolua_S,"E_ITEM_REDSTONE_ORE",E_ITEM_REDSTONE_ORE);
- tolua_constant(tolua_S,"E_ITEM_REDSTONE_ORE_GLOWING",E_ITEM_REDSTONE_ORE_GLOWING);
- tolua_constant(tolua_S,"E_ITEM_REDSTONE_TORCH_ON",E_ITEM_REDSTONE_TORCH_ON);
- tolua_constant(tolua_S,"E_ITEM_REDSTONE_TORCH_OFF",E_ITEM_REDSTONE_TORCH_OFF);
- tolua_constant(tolua_S,"E_ITEM_STONE_BUTTON",E_ITEM_STONE_BUTTON);
- tolua_constant(tolua_S,"E_ITEM_SNOW",E_ITEM_SNOW);
- tolua_constant(tolua_S,"E_ITEM_ICE",E_ITEM_ICE);
- tolua_constant(tolua_S,"E_ITEM_SNOW_BLOCK",E_ITEM_SNOW_BLOCK);
- tolua_constant(tolua_S,"E_ITEM_CACTUS",E_ITEM_CACTUS);
- tolua_constant(tolua_S,"E_ITEM_REEDS",E_ITEM_REEDS);
- tolua_constant(tolua_S,"E_ITEM_JUKEBOX",E_ITEM_JUKEBOX);
- tolua_constant(tolua_S,"E_ITEM_FENCE",E_ITEM_FENCE);
- tolua_constant(tolua_S,"E_ITEM_PUMPKIN",E_ITEM_PUMPKIN);
- tolua_constant(tolua_S,"E_ITEM_BLOODSTONE",E_ITEM_BLOODSTONE);
- tolua_constant(tolua_S,"E_ITEM_SOULSAND",E_ITEM_SOULSAND);
- tolua_constant(tolua_S,"E_ITEM_GLOWSTONE",E_ITEM_GLOWSTONE);
- tolua_constant(tolua_S,"E_ITEM_PORT",E_ITEM_PORT);
- tolua_constant(tolua_S,"E_ITEM_JACK_O_LANTERN",E_ITEM_JACK_O_LANTERN);
- tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER_OFF",E_ITEM_REDSTONE_REPEATER_OFF);
- tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER_ON",E_ITEM_REDSTONE_REPEATER_ON);
- tolua_constant(tolua_S,"E_ITEM_LOCKED_CHEST",E_ITEM_LOCKED_CHEST);
- tolua_constant(tolua_S,"E_ITEM_TRAPDOOR",E_ITEM_TRAPDOOR);
- tolua_constant(tolua_S,"E_ITEM_SILVERFISH_EGG",E_ITEM_SILVERFISH_EGG);
- tolua_constant(tolua_S,"E_ITEM_STONE_BRICKS",E_ITEM_STONE_BRICKS);
- tolua_constant(tolua_S,"E_ITEM_HUGE_BROWN_MUSHROOM",E_ITEM_HUGE_BROWN_MUSHROOM);
- tolua_constant(tolua_S,"E_ITEM_HUGE_RED_MUSHROOM",E_ITEM_HUGE_RED_MUSHROOM);
- tolua_constant(tolua_S,"E_ITEM_IRON_BAR",E_ITEM_IRON_BAR);
- tolua_constant(tolua_S,"E_ITEM_GLASS_PLANE",E_ITEM_GLASS_PLANE);
- tolua_constant(tolua_S,"E_ITEM_MELON",E_ITEM_MELON);
- tolua_constant(tolua_S,"E_ITEM_PUMPKIN_STEM",E_ITEM_PUMPKIN_STEM);
- tolua_constant(tolua_S,"E_ITEM_MELON_STEM",E_ITEM_MELON_STEM);
- tolua_constant(tolua_S,"E_ITEM_VINES",E_ITEM_VINES);
- tolua_constant(tolua_S,"E_ITEM_FENCE_GATE",E_ITEM_FENCE_GATE);
- tolua_constant(tolua_S,"E_ITEM_BRICK_STAIRS",E_ITEM_BRICK_STAIRS);
- tolua_constant(tolua_S,"E_ITEM_STONE_BRICK_STAIRS",E_ITEM_STONE_BRICK_STAIRS);
- tolua_constant(tolua_S,"E_ITEM_MYCELIUM",E_ITEM_MYCELIUM);
- tolua_constant(tolua_S,"E_ITEM_LILY_PAD",E_ITEM_LILY_PAD);
- tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK",E_ITEM_NETHER_BRICK);
- tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK_FENCE",E_ITEM_NETHER_BRICK_FENCE);
- tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK_STAIRS",E_ITEM_NETHER_BRICK_STAIRS);
- tolua_constant(tolua_S,"E_ITEM_ENCHANTMENT_TABLE",E_ITEM_ENCHANTMENT_TABLE);
- tolua_constant(tolua_S,"E_ITEM_END_PORTAL",E_ITEM_END_PORTAL);
- tolua_constant(tolua_S,"E_ITEM_END_PORTAL_FRAME",E_ITEM_END_PORTAL_FRAME);
- tolua_constant(tolua_S,"E_ITEM_END_STONE",E_ITEM_END_STONE);
- tolua_constant(tolua_S,"E_ITEM_DOUBLE_WOODEN_SLAB",E_ITEM_DOUBLE_WOODEN_SLAB);
- tolua_constant(tolua_S,"E_ITEM_WOODEN_SLAB",E_ITEM_WOODEN_SLAB);
- tolua_constant(tolua_S,"E_ITEM_COCA_PLANT",E_ITEM_COCA_PLANT);
- tolua_constant(tolua_S,"E_ITEM_SANDSTONE_STAIRS",E_ITEM_SANDSTONE_STAIRS);
- tolua_constant(tolua_S,"E_ITEM_EMERALD_ORE",E_ITEM_EMERALD_ORE);
- tolua_constant(tolua_S,"E_ITEM_ENDER_CHEST",E_ITEM_ENDER_CHEST);
- tolua_constant(tolua_S,"E_ITEM_TRIPWIRE_HOOK",E_ITEM_TRIPWIRE_HOOK);
- tolua_constant(tolua_S,"E_ITEM_TRIPWIRE",E_ITEM_TRIPWIRE);
- tolua_constant(tolua_S,"E_ITEM_EMERALD_BLOCK",E_ITEM_EMERALD_BLOCK);
- tolua_constant(tolua_S,"E_ITEM_IRON_SHOVEL",E_ITEM_IRON_SHOVEL);
- tolua_constant(tolua_S,"E_ITEM_IRON_PICKAXE",E_ITEM_IRON_PICKAXE);
- tolua_constant(tolua_S,"E_ITEM_IRON_AXE",E_ITEM_IRON_AXE);
- tolua_constant(tolua_S,"E_ITEM_FLINT_AND_STEEL",E_ITEM_FLINT_AND_STEEL);
- tolua_constant(tolua_S,"E_ITEM_RED_APPLE",E_ITEM_RED_APPLE);
- tolua_constant(tolua_S,"E_ITEM_APPLE",E_ITEM_APPLE);
- tolua_constant(tolua_S,"E_ITEM_BOW",E_ITEM_BOW);
- tolua_constant(tolua_S,"E_ITEM_ARROW",E_ITEM_ARROW);
- tolua_constant(tolua_S,"E_ITEM_COAL",E_ITEM_COAL);
- tolua_constant(tolua_S,"E_ITEM_DIAMOND",E_ITEM_DIAMOND);
- tolua_constant(tolua_S,"E_ITEM_IRON",E_ITEM_IRON);
- tolua_constant(tolua_S,"E_ITEM_GOLD",E_ITEM_GOLD);
- tolua_constant(tolua_S,"E_ITEM_IRON_SWORD",E_ITEM_IRON_SWORD);
- tolua_constant(tolua_S,"E_ITEM_WOODEN_SWORD",E_ITEM_WOODEN_SWORD);
- tolua_constant(tolua_S,"E_ITEM_WOODEN_SHOVEL",E_ITEM_WOODEN_SHOVEL);
- tolua_constant(tolua_S,"E_ITEM_WOODEN_PICKAXE",E_ITEM_WOODEN_PICKAXE);
- tolua_constant(tolua_S,"E_ITEM_WOODEN_AXE",E_ITEM_WOODEN_AXE);
- tolua_constant(tolua_S,"E_ITEM_STONE_SWORD",E_ITEM_STONE_SWORD);
- tolua_constant(tolua_S,"E_ITEM_STONE_SHOVEL",E_ITEM_STONE_SHOVEL);
- tolua_constant(tolua_S,"E_ITEM_STONE_PICKAXE",E_ITEM_STONE_PICKAXE);
- tolua_constant(tolua_S,"E_ITEM_STONE_AXE",E_ITEM_STONE_AXE);
- tolua_constant(tolua_S,"E_ITEM_DIAMOND_SWORD",E_ITEM_DIAMOND_SWORD);
- tolua_constant(tolua_S,"E_ITEM_DIAMOND_SHOVEL",E_ITEM_DIAMOND_SHOVEL);
- tolua_constant(tolua_S,"E_ITEM_DIAMOND_PICKAXE",E_ITEM_DIAMOND_PICKAXE);
- tolua_constant(tolua_S,"E_ITEM_DIAMOND_AXE",E_ITEM_DIAMOND_AXE);
- tolua_constant(tolua_S,"E_ITEM_STICK",E_ITEM_STICK);
- tolua_constant(tolua_S,"E_ITEM_BOWL",E_ITEM_BOWL);
- tolua_constant(tolua_S,"E_ITEM_MUSHROOM_SOUP",E_ITEM_MUSHROOM_SOUP);
- tolua_constant(tolua_S,"E_ITEM_GOLD_SWORD",E_ITEM_GOLD_SWORD);
- tolua_constant(tolua_S,"E_ITEM_GOLD_SHOVEL",E_ITEM_GOLD_SHOVEL);
- tolua_constant(tolua_S,"E_ITEM_GOLD_PICKAXE",E_ITEM_GOLD_PICKAXE);
- tolua_constant(tolua_S,"E_ITEM_GOLD_AXE",E_ITEM_GOLD_AXE);
- tolua_constant(tolua_S,"E_ITEM_STRING",E_ITEM_STRING);
- tolua_constant(tolua_S,"E_ITEM_FEATHER",E_ITEM_FEATHER);
- tolua_constant(tolua_S,"E_ITEM_GUNPOWDER",E_ITEM_GUNPOWDER);
- tolua_constant(tolua_S,"E_ITEM_WOODEN_HOE",E_ITEM_WOODEN_HOE);
- tolua_constant(tolua_S,"E_ITEM_STONE_HOE",E_ITEM_STONE_HOE);
- tolua_constant(tolua_S,"E_ITEM_IRON_HOE",E_ITEM_IRON_HOE);
- tolua_constant(tolua_S,"E_ITEM_DIAMOND_HOE",E_ITEM_DIAMOND_HOE);
- tolua_constant(tolua_S,"E_ITEM_GOLD_HOE",E_ITEM_GOLD_HOE);
- tolua_constant(tolua_S,"E_ITEM_SEEDS",E_ITEM_SEEDS);
- tolua_constant(tolua_S,"E_ITEM_WHEAT",E_ITEM_WHEAT);
- tolua_constant(tolua_S,"E_ITEM_BREAD",E_ITEM_BREAD);
- tolua_constant(tolua_S,"E_ITEM_LEATHER_CAP",E_ITEM_LEATHER_CAP);
- tolua_constant(tolua_S,"E_ITEM_LEATHER_TUNIC",E_ITEM_LEATHER_TUNIC);
- tolua_constant(tolua_S,"E_ITEM_LEATHER_PANTS",E_ITEM_LEATHER_PANTS);
- tolua_constant(tolua_S,"E_ITEM_LEATHER_BOOTS",E_ITEM_LEATHER_BOOTS);
- tolua_constant(tolua_S,"E_ITEM_CHAIN_HELMET",E_ITEM_CHAIN_HELMET);
- tolua_constant(tolua_S,"E_ITEM_CHAIN_CHESTPLATE",E_ITEM_CHAIN_CHESTPLATE);
- tolua_constant(tolua_S,"E_ITEM_CHAIN_LEGGINGS",E_ITEM_CHAIN_LEGGINGS);
- tolua_constant(tolua_S,"E_ITEM_CHAIN_BOOTS",E_ITEM_CHAIN_BOOTS);
- tolua_constant(tolua_S,"E_ITEM_IRON_HELMET",E_ITEM_IRON_HELMET);
- tolua_constant(tolua_S,"E_ITEM_IRON_CHESTPLATE",E_ITEM_IRON_CHESTPLATE);
- tolua_constant(tolua_S,"E_ITEM_IRON_LEGGINGS",E_ITEM_IRON_LEGGINGS);
- tolua_constant(tolua_S,"E_ITEM_IRON_BOOTS",E_ITEM_IRON_BOOTS);
- tolua_constant(tolua_S,"E_ITEM_DIAMOND_HELMET",E_ITEM_DIAMOND_HELMET);
- tolua_constant(tolua_S,"E_ITEM_DIAMOND_CHESTPLATE",E_ITEM_DIAMOND_CHESTPLATE);
- tolua_constant(tolua_S,"E_ITEM_DIAMOND_LEGGINGS",E_ITEM_DIAMOND_LEGGINGS);
- tolua_constant(tolua_S,"E_ITEM_DIAMOND_BOOTS",E_ITEM_DIAMOND_BOOTS);
- tolua_constant(tolua_S,"E_ITEM_GOLD_HELMET",E_ITEM_GOLD_HELMET);
- tolua_constant(tolua_S,"E_ITEM_GOLD_CHESTPLATE",E_ITEM_GOLD_CHESTPLATE);
- tolua_constant(tolua_S,"E_ITEM_GOLD_LEGGINGS",E_ITEM_GOLD_LEGGINGS);
- tolua_constant(tolua_S,"E_ITEM_GOLD_BOOTS",E_ITEM_GOLD_BOOTS);
- tolua_constant(tolua_S,"E_ITEM_FLINT",E_ITEM_FLINT);
- tolua_constant(tolua_S,"E_ITEM_RAW_MEAT",E_ITEM_RAW_MEAT);
- tolua_constant(tolua_S,"E_ITEM_COOKED_MEAT",E_ITEM_COOKED_MEAT);
- tolua_constant(tolua_S,"E_ITEM_PAINTINGS",E_ITEM_PAINTINGS);
- tolua_constant(tolua_S,"E_ITEM_GOLDEN_APPLE",E_ITEM_GOLDEN_APPLE);
- tolua_constant(tolua_S,"E_ITEM_SIGN",E_ITEM_SIGN);
- tolua_constant(tolua_S,"E_ITEM_WOODEN_DOOR",E_ITEM_WOODEN_DOOR);
- tolua_constant(tolua_S,"E_ITEM_BUCKET",E_ITEM_BUCKET);
- tolua_constant(tolua_S,"E_ITEM_WATER_BUCKET",E_ITEM_WATER_BUCKET);
- tolua_constant(tolua_S,"E_ITEM_LAVA_BUCKET",E_ITEM_LAVA_BUCKET);
- tolua_constant(tolua_S,"E_ITEM_MINECART",E_ITEM_MINECART);
- tolua_constant(tolua_S,"E_ITEM_SADDLE",E_ITEM_SADDLE);
- tolua_constant(tolua_S,"E_ITEM_IRON_DOOR",E_ITEM_IRON_DOOR);
- tolua_constant(tolua_S,"E_ITEM_REDSTONE_DUST",E_ITEM_REDSTONE_DUST);
- tolua_constant(tolua_S,"E_ITEM_SNOWBALL",E_ITEM_SNOWBALL);
- tolua_constant(tolua_S,"E_ITEM_BOAT",E_ITEM_BOAT);
- tolua_constant(tolua_S,"E_ITEM_LEATHER",E_ITEM_LEATHER);
- tolua_constant(tolua_S,"E_ITEM_MILK",E_ITEM_MILK);
- tolua_constant(tolua_S,"E_ITEM_CLAY_BRICK",E_ITEM_CLAY_BRICK);
- tolua_constant(tolua_S,"E_ITEM_CLAY",E_ITEM_CLAY);
- tolua_constant(tolua_S,"E_ITEM_SUGARCANE",E_ITEM_SUGARCANE);
- tolua_constant(tolua_S,"E_ITEM_SUGAR_CANE",E_ITEM_SUGAR_CANE);
- tolua_constant(tolua_S,"E_ITEM_PAPER",E_ITEM_PAPER);
- tolua_constant(tolua_S,"E_ITEM_BOOK",E_ITEM_BOOK);
- tolua_constant(tolua_S,"E_ITEM_SLIMEBALL",E_ITEM_SLIMEBALL);
- tolua_constant(tolua_S,"E_ITEM_CHEST_MINECART",E_ITEM_CHEST_MINECART);
- tolua_constant(tolua_S,"E_ITEM_FURNACE_MINECART",E_ITEM_FURNACE_MINECART);
- tolua_constant(tolua_S,"E_ITEM_EGG",E_ITEM_EGG);
- tolua_constant(tolua_S,"E_ITEM_COMPASS",E_ITEM_COMPASS);
- tolua_constant(tolua_S,"E_ITEM_FISHING_ROD",E_ITEM_FISHING_ROD);
- tolua_constant(tolua_S,"E_ITEM_CLOCK",E_ITEM_CLOCK);
- tolua_constant(tolua_S,"E_ITEM_GLOWSTONE_DUST",E_ITEM_GLOWSTONE_DUST);
- tolua_constant(tolua_S,"E_ITEM_RAW_FISH",E_ITEM_RAW_FISH);
- tolua_constant(tolua_S,"E_ITEM_COOKED_FISH",E_ITEM_COOKED_FISH);
- tolua_constant(tolua_S,"E_ITEM_DYE",E_ITEM_DYE);
- tolua_constant(tolua_S,"E_ITEM_BONE",E_ITEM_BONE);
- tolua_constant(tolua_S,"E_ITEM_SUGAR",E_ITEM_SUGAR);
- tolua_constant(tolua_S,"E_ITEM_CAKE",E_ITEM_CAKE);
- tolua_constant(tolua_S,"E_ITEM_BED",E_ITEM_BED);
- tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER",E_ITEM_REDSTONE_REPEATER);
- tolua_constant(tolua_S,"E_ITEM_COOKIE",E_ITEM_COOKIE);
- tolua_constant(tolua_S,"E_ITEM_MAP",E_ITEM_MAP);
- tolua_constant(tolua_S,"E_ITEM_SHEARS",E_ITEM_SHEARS);
- tolua_constant(tolua_S,"E_ITEM_MELON_SLICE",E_ITEM_MELON_SLICE);
- tolua_constant(tolua_S,"E_ITEM_PUMPKIN_SEEDS",E_ITEM_PUMPKIN_SEEDS);
- tolua_constant(tolua_S,"E_ITEM_MELON_SEEDS",E_ITEM_MELON_SEEDS);
- tolua_constant(tolua_S,"E_ITEM_RAW_BEEF",E_ITEM_RAW_BEEF);
- tolua_constant(tolua_S,"E_ITEM_STEAK",E_ITEM_STEAK);
- tolua_constant(tolua_S,"E_ITEM_RAW_CHICKEN",E_ITEM_RAW_CHICKEN);
- tolua_constant(tolua_S,"E_ITEM_COOKED_CHICKEN",E_ITEM_COOKED_CHICKEN);
- tolua_constant(tolua_S,"E_ITEM_ROTTEN_FLESH",E_ITEM_ROTTEN_FLESH);
- tolua_constant(tolua_S,"E_ITEM_ENDER_PEARL",E_ITEM_ENDER_PEARL);
- tolua_constant(tolua_S,"E_ITEM_BLAZE_ROD",E_ITEM_BLAZE_ROD);
- tolua_constant(tolua_S,"E_ITEM_GHAST_TEAR",E_ITEM_GHAST_TEAR);
- tolua_constant(tolua_S,"E_ITEM_GOLD_NUGGET",E_ITEM_GOLD_NUGGET);
- tolua_constant(tolua_S,"E_ITEM_NETHER_WART",E_ITEM_NETHER_WART);
- tolua_constant(tolua_S,"E_ITEM_POTIONS",E_ITEM_POTIONS);
- tolua_constant(tolua_S,"E_ITEM_GLASS_BOTTLE",E_ITEM_GLASS_BOTTLE);
- tolua_constant(tolua_S,"E_ITEM_SPIDER_EYE",E_ITEM_SPIDER_EYE);
- tolua_constant(tolua_S,"E_ITEM_FERMENTED_SPIDER_EYE",E_ITEM_FERMENTED_SPIDER_EYE);
- tolua_constant(tolua_S,"E_ITEM_BLAZE_POWDER",E_ITEM_BLAZE_POWDER);
- tolua_constant(tolua_S,"E_ITEM_MAGMA_CREAM",E_ITEM_MAGMA_CREAM);
- tolua_constant(tolua_S,"E_ITEM_BREWING_STAND",E_ITEM_BREWING_STAND);
- tolua_constant(tolua_S,"E_ITEM_CAULDRON",E_ITEM_CAULDRON);
- tolua_constant(tolua_S,"E_ITEM_EYE_OF_ENDER",E_ITEM_EYE_OF_ENDER);
- tolua_constant(tolua_S,"E_ITEM_GLISTERING_MELON",E_ITEM_GLISTERING_MELON);
- tolua_constant(tolua_S,"E_ITEM_SPAWN_EGG",E_ITEM_SPAWN_EGG);
- tolua_constant(tolua_S,"E_ITEM_BOTTLE_O_ENCHANTING",E_ITEM_BOTTLE_O_ENCHANTING);
- tolua_constant(tolua_S,"E_ITEM_FIRE_CHARGE",E_ITEM_FIRE_CHARGE);
- tolua_constant(tolua_S,"E_ITEM_BOOK_AND_QUILL",E_ITEM_BOOK_AND_QUILL);
- tolua_constant(tolua_S,"E_ITEM_WRITTEN_BOOK",E_ITEM_WRITTEN_BOOK);
- tolua_constant(tolua_S,"E_ITEM_EMERALD",E_ITEM_EMERALD);
- tolua_constant(tolua_S,"E_ITEM_13_DISC",E_ITEM_13_DISC);
- tolua_constant(tolua_S,"E_ITEM_CAT_DISC",E_ITEM_CAT_DISC);
- tolua_constant(tolua_S,"E_ITEM_BLOCKS_DISC",E_ITEM_BLOCKS_DISC);
- tolua_constant(tolua_S,"E_ITEM_CHIRP_DISC",E_ITEM_CHIRP_DISC);
- tolua_constant(tolua_S,"E_ITEM_FAR_DISC",E_ITEM_FAR_DISC);
- tolua_constant(tolua_S,"E_ITEM_MALL_DISC",E_ITEM_MALL_DISC);
- tolua_constant(tolua_S,"E_ITEM_MELLOHI_DISC",E_ITEM_MELLOHI_DISC);
- tolua_constant(tolua_S,"E_ITEM_STAL_DISC",E_ITEM_STAL_DISC);
- tolua_constant(tolua_S,"E_ITEM_STRAD_DISC",E_ITEM_STRAD_DISC);
- tolua_constant(tolua_S,"E_ITEM_WARD_DISC",E_ITEM_WARD_DISC);
- tolua_constant(tolua_S,"E_ITEM_11_DISC",E_ITEM_11_DISC);
- tolua_constant(tolua_S,"E_META_PLANKS_APPLE",E_META_PLANKS_APPLE);
- tolua_constant(tolua_S,"E_META_PLANKS_CONIFER",E_META_PLANKS_CONIFER);
- tolua_constant(tolua_S,"E_META_PLANKS_BIRCH",E_META_PLANKS_BIRCH);
- tolua_constant(tolua_S,"E_META_PLANKS_JUNGLE",E_META_PLANKS_JUNGLE);
- tolua_constant(tolua_S,"E_META_LOG_APPLE",E_META_LOG_APPLE);
- tolua_constant(tolua_S,"E_META_LOG_CONIFER",E_META_LOG_CONIFER);
- tolua_constant(tolua_S,"E_META_LOG_BIRCH",E_META_LOG_BIRCH);
- tolua_constant(tolua_S,"E_META_LOG_JUNGLE",E_META_LOG_JUNGLE);
- tolua_constant(tolua_S,"E_META_LEAVES_APPLE",E_META_LEAVES_APPLE);
- tolua_constant(tolua_S,"E_META_LEAVES_CONIFER",E_META_LEAVES_CONIFER);
- tolua_constant(tolua_S,"E_META_LEAVES_BIRCH",E_META_LEAVES_BIRCH);
- tolua_constant(tolua_S,"E_META_LEAVES_JUNGLE",E_META_LEAVES_JUNGLE);
- tolua_constant(tolua_S,"E_META_SAPLING_APPLE",E_META_SAPLING_APPLE);
- tolua_constant(tolua_S,"E_META_SAPLING_CONIFER",E_META_SAPLING_CONIFER);
- tolua_constant(tolua_S,"E_META_SAPLING_BIRCH",E_META_SAPLING_BIRCH);
- tolua_constant(tolua_S,"E_META_SAPLING_JUNGLE",E_META_SAPLING_JUNGLE);
- tolua_constant(tolua_S,"E_META_TALL_GRASS_DEAD_SHRUB",E_META_TALL_GRASS_DEAD_SHRUB);
- tolua_constant(tolua_S,"E_META_TALL_GRASS_GRASS",E_META_TALL_GRASS_GRASS);
- tolua_constant(tolua_S,"E_META_TALL_GRASS_FERN",E_META_TALL_GRASS_FERN);
- tolua_constant(tolua_S,"E_META_SANDSTONE_NORMAL",E_META_SANDSTONE_NORMAL);
- tolua_constant(tolua_S,"E_META_SANDSTONE_ORNAMENT",E_META_SANDSTONE_ORNAMENT);
- tolua_constant(tolua_S,"E_META_SANDSTONE_SMOOTH",E_META_SANDSTONE_SMOOTH);
- tolua_constant(tolua_S,"E_META_WOOL_WHITE",E_META_WOOL_WHITE);
- tolua_constant(tolua_S,"E_META_WOOL_ORANGE",E_META_WOOL_ORANGE);
- tolua_constant(tolua_S,"E_META_WOOL_MAGENTA",E_META_WOOL_MAGENTA);
- tolua_constant(tolua_S,"E_META_WOOL_LIGHTBLUE",E_META_WOOL_LIGHTBLUE);
- tolua_constant(tolua_S,"E_META_WOOL_YELLOW",E_META_WOOL_YELLOW);
- tolua_constant(tolua_S,"E_META_WOOL_LIGHTGREEN",E_META_WOOL_LIGHTGREEN);
- tolua_constant(tolua_S,"E_META_WOOL_PINK",E_META_WOOL_PINK);
- tolua_constant(tolua_S,"E_META_WOOL_GRAY",E_META_WOOL_GRAY);
- tolua_constant(tolua_S,"E_META_WOOL_LIGHTGRAY",E_META_WOOL_LIGHTGRAY);
- tolua_constant(tolua_S,"E_META_WOOL_CYAN",E_META_WOOL_CYAN);
- tolua_constant(tolua_S,"E_META_WOOL_PURPLE",E_META_WOOL_PURPLE);
- tolua_constant(tolua_S,"E_META_WOOL_BLUE",E_META_WOOL_BLUE);
- tolua_constant(tolua_S,"E_META_WOOL_BROWN",E_META_WOOL_BROWN);
- tolua_constant(tolua_S,"E_META_WOOL_GREEN",E_META_WOOL_GREEN);
- tolua_constant(tolua_S,"E_META_WOOL_RED",E_META_WOOL_RED);
- tolua_constant(tolua_S,"E_META_WOOL_BLACK",E_META_WOOL_BLACK);
- tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE",E_META_DOUBLE_STEP_STONE);
- tolua_constant(tolua_S,"E_META_DOUBLE_STEP_SANDSTONE",E_META_DOUBLE_STEP_SANDSTONE);
- tolua_constant(tolua_S,"E_META_DOUBLE_STEP_WOODEN",E_META_DOUBLE_STEP_WOODEN);
- tolua_constant(tolua_S,"E_META_DOUBLE_STEP_COBBLESTONE",E_META_DOUBLE_STEP_COBBLESTONE);
- tolua_constant(tolua_S,"E_META_DOUBLE_STEP_BRICK",E_META_DOUBLE_STEP_BRICK);
- tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE_BRICK",E_META_DOUBLE_STEP_STONE_BRICK);
- tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE_SECRET",E_META_DOUBLE_STEP_STONE_SECRET);
- tolua_constant(tolua_S,"E_META_STEP_STONE",E_META_STEP_STONE);
- tolua_constant(tolua_S,"E_META_STEP_SANDSTONE",E_META_STEP_SANDSTONE);
- tolua_constant(tolua_S,"E_META_STEP_PLANKS",E_META_STEP_PLANKS);
- tolua_constant(tolua_S,"E_META_STEP_COBBLESTONE",E_META_STEP_COBBLESTONE);
- tolua_constant(tolua_S,"E_META_STEP_BRICK",E_META_STEP_BRICK);
- tolua_constant(tolua_S,"E_META_STEP_STONE_BRICK",E_META_STEP_STONE_BRICK);
- tolua_constant(tolua_S,"E_META_STEP_STONE_SECRET",E_META_STEP_STONE_SECRET);
- tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_STONE",E_META_SILVERFISH_EGG_STONE);
- tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_COBBLESTONE",E_META_SILVERFISH_EGG_COBBLESTONE);
- tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_STONE_BRICK",E_META_SILVERFISH_EGG_STONE_BRICK);
- tolua_constant(tolua_S,"E_META_STONE_BRICK_NORMAL",E_META_STONE_BRICK_NORMAL);
- tolua_constant(tolua_S,"E_META_STONE_BRICK_MOSSY",E_META_STONE_BRICK_MOSSY);
- tolua_constant(tolua_S,"E_META_STONE_BRICK_CRACKED",E_META_STONE_BRICK_CRACKED);
- tolua_constant(tolua_S,"E_META_STONE_BRICK_ORNAMENT",E_META_STONE_BRICK_ORNAMENT);
- tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_APPLE",E_BLOCK_WOODEN_DOUBLE_STEP_APPLE);
- tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER",E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER);
- tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH",E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH);
- tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE",E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE);
- tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_APPLE",E_BLOCK_WOODEN_STEP_APPLE);
- tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_CONIFER",E_BLOCK_WOODEN_STEP_CONIFER);
- tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_BIRCH",E_BLOCK_WOODEN_STEP_BIRCH);
- tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_JUNGLE",E_BLOCK_WOODEN_STEP_JUNGLE);
- tolua_constant(tolua_S,"E_META_COAL_NORMAL",E_META_COAL_NORMAL);
- tolua_constant(tolua_S,"E_META_COAL_CHARCOAL",E_META_COAL_CHARCOAL);
- tolua_constant(tolua_S,"E_META_GOLDEN_APPLE_NORMAL",E_META_GOLDEN_APPLE_NORMAL);
- tolua_constant(tolua_S,"E_META_GOLDEN_APPLE_ENCHANTED",E_META_GOLDEN_APPLE_ENCHANTED);
- tolua_constant(tolua_S,"E_META_DYE_BLACK",E_META_DYE_BLACK);
- tolua_constant(tolua_S,"E_META_DYE_RED",E_META_DYE_RED);
- tolua_constant(tolua_S,"E_META_DYE_GREEN",E_META_DYE_GREEN);
- tolua_constant(tolua_S,"E_META_DYE_BROWN",E_META_DYE_BROWN);
- tolua_constant(tolua_S,"E_META_DYE_BLUE",E_META_DYE_BLUE);
- tolua_constant(tolua_S,"E_META_DYE_PURPLE",E_META_DYE_PURPLE);
- tolua_constant(tolua_S,"E_META_DYE_CYAN",E_META_DYE_CYAN);
- tolua_constant(tolua_S,"E_META_DYE_LIGHTGRAY",E_META_DYE_LIGHTGRAY);
- tolua_constant(tolua_S,"E_META_DYE_GRAY",E_META_DYE_GRAY);
- tolua_constant(tolua_S,"E_META_DYE_PINK",E_META_DYE_PINK);
- tolua_constant(tolua_S,"E_META_DYE_LIGHTGREEN",E_META_DYE_LIGHTGREEN);
- tolua_constant(tolua_S,"E_META_DYE_YELLOW",E_META_DYE_YELLOW);
- tolua_constant(tolua_S,"E_META_DYE_LIGHTBLUE",E_META_DYE_LIGHTBLUE);
- tolua_constant(tolua_S,"E_META_DYE_MAGENTA",E_META_DYE_MAGENTA);
- tolua_constant(tolua_S,"E_META_DYE_ORANGE",E_META_DYE_ORANGE);
- tolua_constant(tolua_S,"E_META_DYE_WHITE",E_META_DYE_WHITE);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_CREEPER",E_META_SPAWN_EGG_CREEPER);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_SKELETON",E_META_SPAWN_EGG_SKELETON);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_SPIDER",E_META_SPAWN_EGG_SPIDER);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_ZOMBIE",E_META_SPAWN_EGG_ZOMBIE);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_SLIME",E_META_SPAWN_EGG_SLIME);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_GHAST",E_META_SPAWN_EGG_GHAST);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_ZOMBIE_PIGMAN",E_META_SPAWN_EGG_ZOMBIE_PIGMAN);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_ENDERMAN",E_META_SPAWN_EGG_ENDERMAN);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_CAVE_SPIDER",E_META_SPAWN_EGG_CAVE_SPIDER);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_SILVERFISH",E_META_SPAWN_EGG_SILVERFISH);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_BLAZE",E_META_SPAWN_EGG_BLAZE);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_MAGMA_CUBE",E_META_SPAWN_EGG_MAGMA_CUBE);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_GIANT",E_META_SPAWN_EGG_GIANT);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_ENDER_DRAGON",E_META_SPAWN_EGG_ENDER_DRAGON);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_PIG",E_META_SPAWN_EGG_PIG);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_SHEEP",E_META_SPAWN_EGG_SHEEP);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_COW",E_META_SPAWN_EGG_COW);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_CHICKEN",E_META_SPAWN_EGG_CHICKEN);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_SQUID",E_META_SPAWN_EGG_SQUID);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_WOLF",E_META_SPAWN_EGG_WOLF);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_MOOSHROOM",E_META_SPAWN_EGG_MOOSHROOM);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_OCELOT",E_META_SPAWN_EGG_OCELOT);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_VILLAGER",E_META_SPAWN_EGG_VILLAGER);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_SNOW_GOLEM",E_META_SPAWN_EGG_SNOW_GOLEM);
- tolua_constant(tolua_S,"E_META_SPAWN_EGG_IRON_GOLEM",E_META_SPAWN_EGG_IRON_GOLEM);
- tolua_function(tolua_S,"BlockStringToType",tolua_AllToLua_BlockStringToType00);
- tolua_function(tolua_S,"StringToItem",tolua_AllToLua_StringToItem00);
- tolua_constant(tolua_S,"E_KEEP_ALIVE",E_KEEP_ALIVE);
- tolua_constant(tolua_S,"E_LOGIN",E_LOGIN);
- tolua_constant(tolua_S,"E_HANDSHAKE",E_HANDSHAKE);
- tolua_constant(tolua_S,"E_CHAT",E_CHAT);
- tolua_constant(tolua_S,"E_UPDATE_TIME",E_UPDATE_TIME);
- tolua_constant(tolua_S,"E_ENTITY_EQUIPMENT",E_ENTITY_EQUIPMENT);
- tolua_constant(tolua_S,"E_USE_ENTITY",E_USE_ENTITY);
- tolua_constant(tolua_S,"E_UPDATE_HEALTH",E_UPDATE_HEALTH);
- tolua_constant(tolua_S,"E_RESPAWN",E_RESPAWN);
- tolua_constant(tolua_S,"E_FLYING",E_FLYING);
- tolua_constant(tolua_S,"E_PLAYERPOS",E_PLAYERPOS);
- tolua_constant(tolua_S,"E_PLAYERLOOK",E_PLAYERLOOK);
- tolua_constant(tolua_S,"E_PLAYERMOVELOOK",E_PLAYERMOVELOOK);
- tolua_constant(tolua_S,"E_BLOCK_DIG",E_BLOCK_DIG);
- tolua_constant(tolua_S,"E_BLOCK_PLACE",E_BLOCK_PLACE);
- tolua_constant(tolua_S,"E_ITEM_SWITCH",E_ITEM_SWITCH);
- tolua_constant(tolua_S,"E_ADD_TO_INV",E_ADD_TO_INV);
- tolua_constant(tolua_S,"E_ANIMATION",E_ANIMATION);
- tolua_constant(tolua_S,"E_PACKET_13",E_PACKET_13);
- tolua_constant(tolua_S,"E_NAMED_ENTITY_SPAWN",E_NAMED_ENTITY_SPAWN);
- tolua_constant(tolua_S,"E_PICKUP_SPAWN",E_PICKUP_SPAWN);
- tolua_constant(tolua_S,"E_COLLECT_ITEM",E_COLLECT_ITEM);
- tolua_constant(tolua_S,"E_ADD_VEHICLE",E_ADD_VEHICLE);
- tolua_constant(tolua_S,"E_SPAWN_MOB",E_SPAWN_MOB);
- tolua_constant(tolua_S,"E_DESTROY_ENT",E_DESTROY_ENT);
- tolua_constant(tolua_S,"E_ENTITY",E_ENTITY);
- tolua_constant(tolua_S,"E_REL_ENT_MOVE",E_REL_ENT_MOVE);
- tolua_constant(tolua_S,"E_ENT_LOOK",E_ENT_LOOK);
- tolua_constant(tolua_S,"E_REL_ENT_MOVE_LOOK",E_REL_ENT_MOVE_LOOK);
- tolua_constant(tolua_S,"E_ENT_TELEPORT",E_ENT_TELEPORT);
- tolua_constant(tolua_S,"E_ENT_HEAD_LOOK",E_ENT_HEAD_LOOK);
- tolua_constant(tolua_S,"E_ENT_STATUS",E_ENT_STATUS);
- tolua_constant(tolua_S,"E_METADATA",E_METADATA);
- tolua_constant(tolua_S,"E_PRE_CHUNK",E_PRE_CHUNK);
- tolua_constant(tolua_S,"E_MAP_CHUNK",E_MAP_CHUNK);
- tolua_constant(tolua_S,"E_MULTI_BLOCK",E_MULTI_BLOCK);
- tolua_constant(tolua_S,"E_BLOCK_CHANGE",E_BLOCK_CHANGE);
- tolua_constant(tolua_S,"E_BLOCK_ACTION",E_BLOCK_ACTION);
- tolua_constant(tolua_S,"E_EXPLOSION",E_EXPLOSION);
- tolua_constant(tolua_S,"E_SOUND_EFFECT",E_SOUND_EFFECT);
- tolua_constant(tolua_S,"E_NEW_INVALID_STATE",E_NEW_INVALID_STATE);
- tolua_constant(tolua_S,"E_THUNDERBOLT",E_THUNDERBOLT);
- tolua_constant(tolua_S,"E_WINDOW_OPEN",E_WINDOW_OPEN);
- tolua_constant(tolua_S,"E_WINDOW_CLOSE",E_WINDOW_CLOSE);
- tolua_constant(tolua_S,"E_WINDOW_CLICK",E_WINDOW_CLICK);
- tolua_constant(tolua_S,"E_INVENTORY_SLOT",E_INVENTORY_SLOT);
- tolua_constant(tolua_S,"E_INVENTORY_WHOLE",E_INVENTORY_WHOLE);
- tolua_constant(tolua_S,"E_INVENTORY_PROGRESS",E_INVENTORY_PROGRESS);
- tolua_constant(tolua_S,"E_CREATIVE_INVENTORY_ACTION",E_CREATIVE_INVENTORY_ACTION);
- tolua_constant(tolua_S,"E_UPDATE_SIGN",E_UPDATE_SIGN);
- tolua_constant(tolua_S,"E_PLAYER_LIST_ITEM",E_PLAYER_LIST_ITEM);
- tolua_constant(tolua_S,"E_PLAYER_ABILITIES",E_PLAYER_ABILITIES);
- tolua_constant(tolua_S,"E_PING",E_PING);
- tolua_constant(tolua_S,"E_DISCONNECT",E_DISCONNECT);
- tolua_array(tolua_S,"g_BlockLightValue",tolua_get_AllToLua_g_BlockLightValue,tolua_set_AllToLua_g_BlockLightValue);
- tolua_array(tolua_S,"g_BlockSpreadLightFalloff",tolua_get_AllToLua_g_BlockSpreadLightFalloff,tolua_set_AllToLua_g_BlockSpreadLightFalloff);
- tolua_array(tolua_S,"g_BlockTransparent",tolua_get_AllToLua_g_BlockTransparent,tolua_set_AllToLua_g_BlockTransparent);
- tolua_array(tolua_S,"g_BlockOneHitDig",tolua_get_AllToLua_g_BlockOneHitDig,tolua_set_AllToLua_g_BlockOneHitDig);
- tolua_function(tolua_S,"IsValidBlock",tolua_AllToLua_IsValidBlock00);
- tolua_function(tolua_S,"IsValidItem",tolua_AllToLua_IsValidItem00);
- tolua_function(tolua_S,"AddDirection",tolua_AllToLua_AddDirection00);
- tolua_module(tolua_S,"ItemCategory",0);
- tolua_beginmodule(tolua_S,"ItemCategory");
- tolua_function(tolua_S,"IsPickaxe",tolua_AllToLua_ItemCategory_IsPickaxe00);
- tolua_function(tolua_S,"IsAxe",tolua_AllToLua_ItemCategory_IsAxe00);
- tolua_function(tolua_S,"IsSword",tolua_AllToLua_ItemCategory_IsSword00);
- tolua_function(tolua_S,"IsHoe",tolua_AllToLua_ItemCategory_IsHoe00);
- tolua_function(tolua_S,"IsShovel",tolua_AllToLua_ItemCategory_IsShovel00);
- tolua_function(tolua_S,"IsTool",tolua_AllToLua_ItemCategory_IsTool00);
- tolua_endmodule(tolua_S);
- tolua_constant(tolua_S,"eGameMode_Survival",eGameMode_Survival);
- tolua_constant(tolua_S,"eGameMode_Creative",eGameMode_Creative);
- tolua_constant(tolua_S,"eWeather_Sunny",eWeather_Sunny);
- tolua_constant(tolua_S,"eWeather_Rain",eWeather_Rain);
- tolua_constant(tolua_S,"eWeather_ThunderStorm",eWeather_ThunderStorm);
- tolua_function(tolua_S,"GetTime",tolua_AllToLua_GetTime00);
- tolua_function(tolua_S,"GetChar",tolua_AllToLua_GetChar00);
- tolua_cclass(tolua_S,"cStringMap","cStringMap","",NULL);
- tolua_beginmodule(tolua_S,"cStringMap");
- tolua_function(tolua_S,"clear",tolua_AllToLua_cStringMap_clear00);
- tolua_function(tolua_S,"size",tolua_AllToLua_cStringMap_size00);
- tolua_function(tolua_S,"get",tolua_AllToLua_cStringMap_get00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cChatColor","cChatColor","",NULL);
- tolua_beginmodule(tolua_S,"cChatColor");
- tolua_variable(tolua_S,"Color",tolua_get_cChatColor_Color,NULL);
- tolua_variable(tolua_S,"Delimiter",tolua_get_cChatColor_Delimiter,NULL);
- tolua_variable(tolua_S,"Black",tolua_get_cChatColor_Black,NULL);
- tolua_variable(tolua_S,"Navy",tolua_get_cChatColor_Navy,NULL);
- tolua_variable(tolua_S,"Green",tolua_get_cChatColor_Green,NULL);
- tolua_variable(tolua_S,"Blue",tolua_get_cChatColor_Blue,NULL);
- tolua_variable(tolua_S,"Red",tolua_get_cChatColor_Red,NULL);
- tolua_variable(tolua_S,"Purple",tolua_get_cChatColor_Purple,NULL);
- tolua_variable(tolua_S,"Gold",tolua_get_cChatColor_Gold,NULL);
- tolua_variable(tolua_S,"LightGray",tolua_get_cChatColor_LightGray,NULL);
- tolua_variable(tolua_S,"Gray",tolua_get_cChatColor_Gray,NULL);
- tolua_variable(tolua_S,"DarkPurple",tolua_get_cChatColor_DarkPurple,NULL);
- tolua_variable(tolua_S,"LightGreen",tolua_get_cChatColor_LightGreen,NULL);
- tolua_variable(tolua_S,"LightBlue",tolua_get_cChatColor_LightBlue,NULL);
- tolua_variable(tolua_S,"Rose",tolua_get_cChatColor_Rose,NULL);
- tolua_variable(tolua_S,"LightPurple",tolua_get_cChatColor_LightPurple,NULL);
- tolua_variable(tolua_S,"Yellow",tolua_get_cChatColor_Yellow,NULL);
- tolua_variable(tolua_S,"White",tolua_get_cChatColor_White,NULL);
- tolua_variable(tolua_S,"Random",tolua_get_cChatColor_Random,NULL);
- tolua_variable(tolua_S,"Bold",tolua_get_cChatColor_Bold,NULL);
- tolua_variable(tolua_S,"Strikethrough",tolua_get_cChatColor_Strikethrough,NULL);
- tolua_variable(tolua_S,"Underlined",tolua_get_cChatColor_Underlined,NULL);
- tolua_variable(tolua_S,"Italic",tolua_get_cChatColor_Italic,NULL);
- tolua_variable(tolua_S,"Plain",tolua_get_cChatColor_Plain,NULL);
- tolua_function(tolua_S,"MakeColor",tolua_AllToLua_cChatColor_MakeColor00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cClientHandle","cClientHandle","",NULL);
- tolua_beginmodule(tolua_S,"cClientHandle");
- tolua_function(tolua_S,"GetPlayer",tolua_AllToLua_cClientHandle_GetPlayer00);
- tolua_function(tolua_S,"Kick",tolua_AllToLua_cClientHandle_Kick00);
- tolua_function(tolua_S,"GetUsername",tolua_AllToLua_cClientHandle_GetUsername00);
- tolua_function(tolua_S,"GetPing",tolua_AllToLua_cClientHandle_GetPing00);
- tolua_function(tolua_S,"SetViewDistance",tolua_AllToLua_cClientHandle_SetViewDistance00);
- tolua_function(tolua_S,"GetViewDistance",tolua_AllToLua_cClientHandle_GetViewDistance00);
- tolua_function(tolua_S,"GetUniqueID",tolua_AllToLua_cClientHandle_GetUniqueID00);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"cEntity","cEntity","",tolua_collect_cEntity);
- #else
- tolua_cclass(tolua_S,"cEntity","cEntity","",NULL);
- #endif
- tolua_beginmodule(tolua_S,"cEntity");
- tolua_function(tolua_S,"delete",tolua_AllToLua_cEntity_delete00);
- tolua_function(tolua_S,"Initialize",tolua_AllToLua_cEntity_Initialize00);
- tolua_constant(tolua_S,"eEntityType_Entity",cEntity::eEntityType_Entity);
- tolua_constant(tolua_S,"eEntityType_Player",cEntity::eEntityType_Player);
- tolua_constant(tolua_S,"eEntityType_Pickup",cEntity::eEntityType_Pickup);
- tolua_function(tolua_S,"GetEntityType",tolua_AllToLua_cEntity_GetEntityType00);
- tolua_function(tolua_S,"IsA",tolua_AllToLua_cEntity_IsA00);
- tolua_function(tolua_S,"GetClass",tolua_AllToLua_cEntity_GetClass00);
- tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cEntity_GetWorld00);
- tolua_function(tolua_S,"GetPosition",tolua_AllToLua_cEntity_GetPosition00);
- tolua_function(tolua_S,"GetPosX",tolua_AllToLua_cEntity_GetPosX00);
- tolua_function(tolua_S,"GetPosY",tolua_AllToLua_cEntity_GetPosY00);
- tolua_function(tolua_S,"GetPosZ",tolua_AllToLua_cEntity_GetPosZ00);
- tolua_function(tolua_S,"GetRot",tolua_AllToLua_cEntity_GetRot00);
- tolua_function(tolua_S,"GetRotation",tolua_AllToLua_cEntity_GetRotation00);
- tolua_function(tolua_S,"GetPitch",tolua_AllToLua_cEntity_GetPitch00);
- tolua_function(tolua_S,"GetRoll",tolua_AllToLua_cEntity_GetRoll00);
- tolua_function(tolua_S,"GetLookVector",tolua_AllToLua_cEntity_GetLookVector00);
- tolua_function(tolua_S,"GetChunkX",tolua_AllToLua_cEntity_GetChunkX00);
- tolua_function(tolua_S,"GetChunkY",tolua_AllToLua_cEntity_GetChunkY00);
- tolua_function(tolua_S,"GetChunkZ",tolua_AllToLua_cEntity_GetChunkZ00);
- tolua_function(tolua_S,"SetPosX",tolua_AllToLua_cEntity_SetPosX00);
- tolua_function(tolua_S,"SetPosY",tolua_AllToLua_cEntity_SetPosY00);
- tolua_function(tolua_S,"SetPosZ",tolua_AllToLua_cEntity_SetPosZ00);
- tolua_function(tolua_S,"SetPosition",tolua_AllToLua_cEntity_SetPosition00);
- tolua_function(tolua_S,"SetPosition",tolua_AllToLua_cEntity_SetPosition01);
- tolua_function(tolua_S,"SetRot",tolua_AllToLua_cEntity_SetRot00);
- tolua_function(tolua_S,"SetRotation",tolua_AllToLua_cEntity_SetRotation00);
- tolua_function(tolua_S,"SetPitch",tolua_AllToLua_cEntity_SetPitch00);
- tolua_function(tolua_S,"SetRoll",tolua_AllToLua_cEntity_SetRoll00);
- tolua_function(tolua_S,"GetUniqueID",tolua_AllToLua_cEntity_GetUniqueID00);
- tolua_function(tolua_S,"IsDestroyed",tolua_AllToLua_cEntity_IsDestroyed00);
- tolua_function(tolua_S,"Destroy",tolua_AllToLua_cEntity_Destroy00);
- tolua_function(tolua_S,"Tick",tolua_AllToLua_cEntity_Tick00);
- tolua_function(tolua_S,"SpawnOn",tolua_AllToLua_cEntity_SpawnOn00);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"Lua__cEntity","Lua__cEntity","cEntity",tolua_collect_Lua__cEntity);
- #else
- tolua_cclass(tolua_S,"Lua__cEntity","Lua__cEntity","cEntity",NULL);
- #endif
- tolua_beginmodule(tolua_S,"Lua__cEntity");
- tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cEntity_tolua__set_instance00);
- tolua_function(tolua_S,"cEntity__Initialize",tolua_AllToLua_Lua__cEntity_cEntity__Initialize00);
- tolua_function(tolua_S,"cEntity__GetEntityType",tolua_AllToLua_Lua__cEntity_cEntity__GetEntityType00);
- tolua_function(tolua_S,"cEntity__IsA",tolua_AllToLua_Lua__cEntity_cEntity__IsA00);
- tolua_function(tolua_S,"cEntity__GetClass",tolua_AllToLua_Lua__cEntity_cEntity__GetClass00);
- tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cEntity_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cEntity_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cEntity_new00_local);
- tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cEntity_delete00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"TakeDamageInfo","TakeDamageInfo","",NULL);
- tolua_beginmodule(tolua_S,"TakeDamageInfo");
- tolua_variable(tolua_S,"Damage",tolua_get_TakeDamageInfo_Damage,tolua_set_TakeDamageInfo_Damage);
- tolua_variable(tolua_S,"Instigator",tolua_get_TakeDamageInfo_Instigator_ptr,tolua_set_TakeDamageInfo_Instigator_ptr);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cPawn","cPawn","cEntity",NULL);
- tolua_beginmodule(tolua_S,"cPawn");
- tolua_function(tolua_S,"TeleportToEntity",tolua_AllToLua_cPawn_TeleportToEntity00);
- tolua_function(tolua_S,"TeleportTo",tolua_AllToLua_cPawn_TeleportTo00);
- tolua_function(tolua_S,"Heal",tolua_AllToLua_cPawn_Heal00);
- tolua_function(tolua_S,"TakeDamage",tolua_AllToLua_cPawn_TakeDamage00);
- tolua_function(tolua_S,"KilledBy",tolua_AllToLua_cPawn_KilledBy00);
- tolua_function(tolua_S,"GetHealth",tolua_AllToLua_cPawn_GetHealth00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"Lua__cPawn","Lua__cPawn","cPawn",NULL);
- tolua_beginmodule(tolua_S,"Lua__cPawn");
- tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPawn_tolua__set_instance00);
- tolua_function(tolua_S,"cPawn__TeleportToEntity",tolua_AllToLua_Lua__cPawn_cPawn__TeleportToEntity00);
- tolua_function(tolua_S,"cPawn__TeleportTo",tolua_AllToLua_Lua__cPawn_cPawn__TeleportTo00);
- tolua_function(tolua_S,"cPawn__TakeDamage",tolua_AllToLua_Lua__cPawn_cPawn__TakeDamage00);
- tolua_function(tolua_S,"cPawn__KilledBy",tolua_AllToLua_Lua__cPawn_cPawn__KilledBy00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cPlayer","cPlayer","cPawn",NULL);
- tolua_beginmodule(tolua_S,"cPlayer");
- tolua_function(tolua_S,"Initialize",tolua_AllToLua_cPlayer_Initialize00);
- tolua_function(tolua_S,"GetEyeHeight",tolua_AllToLua_cPlayer_GetEyeHeight00);
- tolua_function(tolua_S,"GetEyePosition",tolua_AllToLua_cPlayer_GetEyePosition00);
- tolua_function(tolua_S,"GetFlying",tolua_AllToLua_cPlayer_GetFlying00);
- tolua_function(tolua_S,"GetStance",tolua_AllToLua_cPlayer_GetStance00);
- tolua_function(tolua_S,"GetInventory",tolua_AllToLua_cPlayer_GetInventory00);
- tolua_function(tolua_S,"TeleportTo",tolua_AllToLua_cPlayer_TeleportTo00);
- tolua_function(tolua_S,"GetGameMode",tolua_AllToLua_cPlayer_GetGameMode00);
- tolua_function(tolua_S,"GetIP",tolua_AllToLua_cPlayer_GetIP00);
- tolua_function(tolua_S,"GetLastBlockActionTime",tolua_AllToLua_cPlayer_GetLastBlockActionTime00);
- tolua_function(tolua_S,"GetLastBlockActionCnt",tolua_AllToLua_cPlayer_GetLastBlockActionCnt00);
- tolua_function(tolua_S,"SetLastBlockActionCnt",tolua_AllToLua_cPlayer_SetLastBlockActionCnt00);
- tolua_function(tolua_S,"SetLastBlockActionTime",tolua_AllToLua_cPlayer_SetLastBlockActionTime00);
- tolua_function(tolua_S,"SetGameMode",tolua_AllToLua_cPlayer_SetGameMode00);
- tolua_function(tolua_S,"MoveTo",tolua_AllToLua_cPlayer_MoveTo00);
- tolua_function(tolua_S,"GetClientHandle",tolua_AllToLua_cPlayer_GetClientHandle00);
- tolua_function(tolua_S,"SendMessage",tolua_AllToLua_cPlayer_SendMessage00);
- tolua_function(tolua_S,"GetName",tolua_AllToLua_cPlayer_GetName00);
- tolua_function(tolua_S,"SetName",tolua_AllToLua_cPlayer_SetName00);
- tolua_function(tolua_S,"AddToGroup",tolua_AllToLua_cPlayer_AddToGroup00);
- tolua_function(tolua_S,"CanUseCommand",tolua_AllToLua_cPlayer_CanUseCommand00);
- tolua_function(tolua_S,"HasPermission",tolua_AllToLua_cPlayer_HasPermission00);
- tolua_function(tolua_S,"IsInGroup",tolua_AllToLua_cPlayer_IsInGroup00);
- tolua_function(tolua_S,"GetColor",tolua_AllToLua_cPlayer_GetColor00);
- tolua_function(tolua_S,"TossItem",tolua_AllToLua_cPlayer_TossItem00);
- tolua_function(tolua_S,"Heal",tolua_AllToLua_cPlayer_Heal00);
- tolua_function(tolua_S,"TakeDamage",tolua_AllToLua_cPlayer_TakeDamage00);
- tolua_function(tolua_S,"KilledBy",tolua_AllToLua_cPlayer_KilledBy00);
- tolua_function(tolua_S,"Respawn",tolua_AllToLua_cPlayer_Respawn00);
- tolua_function(tolua_S,"SetVisible",tolua_AllToLua_cPlayer_SetVisible00);
- tolua_function(tolua_S,"IsVisible",tolua_AllToLua_cPlayer_IsVisible00);
- tolua_function(tolua_S,"MoveToWorld",tolua_AllToLua_cPlayer_MoveToWorld00);
- tolua_function(tolua_S,"LoadPermissionsFromDisk",tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"Lua__cPlayer","Lua__cPlayer","cPlayer",NULL);
- tolua_beginmodule(tolua_S,"Lua__cPlayer");
- tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPlayer_tolua__set_instance00);
- tolua_function(tolua_S,"cPlayer__Initialize",tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00);
- tolua_function(tolua_S,"cPlayer__TeleportTo",tolua_AllToLua_Lua__cPlayer_cPlayer__TeleportTo00);
- tolua_function(tolua_S,"cPlayer__MoveTo",tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cPluginManager","cPluginManager","",NULL);
- tolua_beginmodule(tolua_S,"cPluginManager");
- tolua_constant(tolua_S,"HOOK_TICK",cPluginManager::HOOK_TICK);
- tolua_constant(tolua_S,"HOOK_CHAT",cPluginManager::HOOK_CHAT);
- tolua_constant(tolua_S,"HOOK_COLLECT_ITEM",cPluginManager::HOOK_COLLECT_ITEM);
- tolua_constant(tolua_S,"HOOK_BLOCK_DIG",cPluginManager::HOOK_BLOCK_DIG);
- tolua_constant(tolua_S,"HOOK_BLOCK_PLACE",cPluginManager::HOOK_BLOCK_PLACE);
- tolua_constant(tolua_S,"HOOK_DISCONNECT",cPluginManager::HOOK_DISCONNECT);
- tolua_constant(tolua_S,"HOOK_HANDSHAKE",cPluginManager::HOOK_HANDSHAKE);
- tolua_constant(tolua_S,"HOOK_LOGIN",cPluginManager::HOOK_LOGIN);
- tolua_constant(tolua_S,"HOOK_PLAYER_SPAWN",cPluginManager::HOOK_PLAYER_SPAWN);
- tolua_constant(tolua_S,"HOOK_PLAYER_JOIN",cPluginManager::HOOK_PLAYER_JOIN);
- tolua_constant(tolua_S,"HOOK_PLAYER_MOVE",cPluginManager::HOOK_PLAYER_MOVE);
- tolua_constant(tolua_S,"HOOK_TAKE_DAMAGE",cPluginManager::HOOK_TAKE_DAMAGE);
- tolua_constant(tolua_S,"HOOK_KILLED",cPluginManager::HOOK_KILLED);
- tolua_constant(tolua_S,"HOOK_CHUNK_GENERATED",cPluginManager::HOOK_CHUNK_GENERATED);
- tolua_constant(tolua_S,"HOOK_CHUNK_GENERATING",cPluginManager::HOOK_CHUNK_GENERATING);
- tolua_constant(tolua_S,"HOOK_BLOCK_TO_DROPS",cPluginManager::HOOK_BLOCK_TO_DROPS);
- tolua_constant(tolua_S,"HOOK_PRE_CRAFTING",cPluginManager::HOOK_PRE_CRAFTING);
- tolua_constant(tolua_S,"HOOK_CRAFTING_NO_RECIPE",cPluginManager::HOOK_CRAFTING_NO_RECIPE);
- tolua_constant(tolua_S,"HOOK_POST_CRAFTING",cPluginManager::HOOK_POST_CRAFTING);
- tolua_constant(tolua_S,"HOOK_BLOCK_TO_PICKUP",cPluginManager::HOOK_BLOCK_TO_PICKUP);
- tolua_constant(tolua_S,"HOOK_WEATHER_CHANGE",cPluginManager::HOOK_WEATHER_CHANGE);
- tolua_constant(tolua_S,"E_PLUGIN_TICK",cPluginManager::E_PLUGIN_TICK);
- tolua_constant(tolua_S,"E_PLUGIN_CHAT",cPluginManager::E_PLUGIN_CHAT);
- tolua_constant(tolua_S,"E_PLUGIN_COLLECT_ITEM",cPluginManager::E_PLUGIN_COLLECT_ITEM);
- tolua_constant(tolua_S,"E_PLUGIN_BLOCK_DIG",cPluginManager::E_PLUGIN_BLOCK_DIG);
- tolua_constant(tolua_S,"E_PLUGIN_BLOCK_PLACE",cPluginManager::E_PLUGIN_BLOCK_PLACE);
- tolua_constant(tolua_S,"E_PLUGIN_DISCONNECT",cPluginManager::E_PLUGIN_DISCONNECT);
- tolua_constant(tolua_S,"E_PLUGIN_HANDSHAKE",cPluginManager::E_PLUGIN_HANDSHAKE);
- tolua_constant(tolua_S,"E_PLUGIN_LOGIN",cPluginManager::E_PLUGIN_LOGIN);
- tolua_constant(tolua_S,"E_PLUGIN_PLAYER_SPAWN",cPluginManager::E_PLUGIN_PLAYER_SPAWN);
- tolua_constant(tolua_S,"E_PLUGIN_PLAYER_JOIN",cPluginManager::E_PLUGIN_PLAYER_JOIN);
- tolua_constant(tolua_S,"E_PLUGIN_PLAYER_MOVE",cPluginManager::E_PLUGIN_PLAYER_MOVE);
- tolua_constant(tolua_S,"E_PLUGIN_TAKE_DAMAGE",cPluginManager::E_PLUGIN_TAKE_DAMAGE);
- tolua_constant(tolua_S,"E_PLUGIN_KILLED",cPluginManager::E_PLUGIN_KILLED);
- tolua_constant(tolua_S,"E_PLUGIN_CHUNK_GENERATED",cPluginManager::E_PLUGIN_CHUNK_GENERATED);
- tolua_constant(tolua_S,"E_PLUGIN_CHUNK_GENERATING",cPluginManager::E_PLUGIN_CHUNK_GENERATING);
- tolua_constant(tolua_S,"E_PLUGIN_BLOCK_TO_DROPS",cPluginManager::E_PLUGIN_BLOCK_TO_DROPS);
- tolua_function(tolua_S,"GetPluginManager",tolua_AllToLua_cPluginManager_GetPluginManager00);
- tolua_function(tolua_S,"GetPlugin",tolua_AllToLua_cPluginManager_GetPlugin00);
- tolua_function(tolua_S,"ReloadPlugins",tolua_AllToLua_cPluginManager_ReloadPlugins00);
- tolua_function(tolua_S,"AddPlugin",tolua_AllToLua_cPluginManager_AddPlugin00);
- tolua_function(tolua_S,"AddHook",tolua_AllToLua_cPluginManager_AddHook00);
- tolua_function(tolua_S,"GetNumPlugins",tolua_AllToLua_cPluginManager_GetNumPlugins00);
- tolua_function(tolua_S,"RemovePlugin",tolua_AllToLua_cPluginManager_RemovePlugin00);
- tolua_function(tolua_S,"RemoveLuaPlugin",tolua_AllToLua_cPluginManager_RemoveLuaPlugin00);
- tolua_function(tolua_S,"GetLuaPlugin",tolua_AllToLua_cPluginManager_GetLuaPlugin00);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"cPlugin","cPlugin","",tolua_collect_cPlugin);
- #else
- tolua_cclass(tolua_S,"cPlugin","cPlugin","",NULL);
- #endif
- tolua_beginmodule(tolua_S,"cPlugin");
- tolua_function(tolua_S,"delete",tolua_AllToLua_cPlugin_delete00);
- tolua_function(tolua_S,"OnDisable",tolua_AllToLua_cPlugin_OnDisable00);
- tolua_function(tolua_S,"Initialize",tolua_AllToLua_cPlugin_Initialize00);
- tolua_function(tolua_S,"Tick",tolua_AllToLua_cPlugin_Tick00);
- tolua_function(tolua_S,"OnCollectItem",tolua_AllToLua_cPlugin_OnCollectItem00);
- tolua_function(tolua_S,"OnDisconnect",tolua_AllToLua_cPlugin_OnDisconnect00);
- tolua_function(tolua_S,"OnBlockPlace",tolua_AllToLua_cPlugin_OnBlockPlace00);
- tolua_function(tolua_S,"OnBlockDig",tolua_AllToLua_cPlugin_OnBlockDig00);
- tolua_function(tolua_S,"OnChat",tolua_AllToLua_cPlugin_OnChat00);
- tolua_function(tolua_S,"OnLogin",tolua_AllToLua_cPlugin_OnLogin00);
- tolua_function(tolua_S,"OnPlayerSpawn",tolua_AllToLua_cPlugin_OnPlayerSpawn00);
- tolua_function(tolua_S,"OnPlayerJoin",tolua_AllToLua_cPlugin_OnPlayerJoin00);
- tolua_function(tolua_S,"OnPlayerMove",tolua_AllToLua_cPlugin_OnPlayerMove00);
- tolua_function(tolua_S,"OnTakeDamage",tolua_AllToLua_cPlugin_OnTakeDamage00);
- tolua_function(tolua_S,"OnKilled",tolua_AllToLua_cPlugin_OnKilled00);
- tolua_function(tolua_S,"OnChunkGenerated",tolua_AllToLua_cPlugin_OnChunkGenerated00);
- tolua_function(tolua_S,"OnChunkGenerating",tolua_AllToLua_cPlugin_OnChunkGenerating00);
- tolua_function(tolua_S,"OnPreCrafting",tolua_AllToLua_cPlugin_OnPreCrafting00);
- tolua_function(tolua_S,"OnCraftingNoRecipe",tolua_AllToLua_cPlugin_OnCraftingNoRecipe00);
- tolua_function(tolua_S,"OnPostCrafting",tolua_AllToLua_cPlugin_OnPostCrafting00);
- tolua_function(tolua_S,"OnBlockToPickup",tolua_AllToLua_cPlugin_OnBlockToPickup00);
- tolua_function(tolua_S,"GetName",tolua_AllToLua_cPlugin_GetName00);
- tolua_function(tolua_S,"SetName",tolua_AllToLua_cPlugin_SetName00);
- tolua_function(tolua_S,"GetVersion",tolua_AllToLua_cPlugin_GetVersion00);
- tolua_function(tolua_S,"SetVersion",tolua_AllToLua_cPlugin_SetVersion00);
- tolua_cclass(tolua_S,"CommandStruct","cPlugin::CommandStruct","",NULL);
- tolua_beginmodule(tolua_S,"CommandStruct");
- tolua_variable(tolua_S,"Command",tolua_get_cPlugin__CommandStruct_Command,tolua_set_cPlugin__CommandStruct_Command);
- tolua_variable(tolua_S,"Description",tolua_get_cPlugin__CommandStruct_Description,tolua_set_cPlugin__CommandStruct_Description);
- tolua_variable(tolua_S,"Permission",tolua_get_cPlugin__CommandStruct_Permission,tolua_set_cPlugin__CommandStruct_Permission);
- tolua_endmodule(tolua_S);
- tolua_function(tolua_S,"AddCommand",tolua_AllToLua_cPlugin_AddCommand00);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"Lua__cPlugin","Lua__cPlugin","cPlugin",tolua_collect_Lua__cPlugin);
- #else
- tolua_cclass(tolua_S,"Lua__cPlugin","Lua__cPlugin","cPlugin",NULL);
- #endif
- tolua_beginmodule(tolua_S,"Lua__cPlugin");
- tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPlugin_tolua__set_instance00);
- tolua_function(tolua_S,"cPlugin__OnDisable",tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisable00);
- tolua_function(tolua_S,"cPlugin__Tick",tolua_AllToLua_Lua__cPlugin_cPlugin__Tick00);
- tolua_function(tolua_S,"cPlugin__OnCollectItem",tolua_AllToLua_Lua__cPlugin_cPlugin__OnCollectItem00);
- tolua_function(tolua_S,"cPlugin__OnDisconnect",tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00);
- tolua_function(tolua_S,"cPlugin__OnBlockPlace",tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockPlace00);
- tolua_function(tolua_S,"cPlugin__OnBlockDig",tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockDig00);
- tolua_function(tolua_S,"cPlugin__OnChat",tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00);
- tolua_function(tolua_S,"cPlugin__OnLogin",tolua_AllToLua_Lua__cPlugin_cPlugin__OnLogin00);
- tolua_function(tolua_S,"cPlugin__OnPlayerSpawn",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerSpawn00);
- tolua_function(tolua_S,"cPlugin__OnPlayerJoin",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerJoin00);
- tolua_function(tolua_S,"cPlugin__OnPlayerMove",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerMove00);
- tolua_function(tolua_S,"cPlugin__OnTakeDamage",tolua_AllToLua_Lua__cPlugin_cPlugin__OnTakeDamage00);
- tolua_function(tolua_S,"cPlugin__OnKilled",tolua_AllToLua_Lua__cPlugin_cPlugin__OnKilled00);
- tolua_function(tolua_S,"cPlugin__OnChunkGenerated",tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerated00);
- tolua_function(tolua_S,"cPlugin__OnChunkGenerating",tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerating00);
- tolua_function(tolua_S,"cPlugin__OnPreCrafting",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPreCrafting00);
- tolua_function(tolua_S,"cPlugin__OnCraftingNoRecipe",tolua_AllToLua_Lua__cPlugin_cPlugin__OnCraftingNoRecipe00);
- tolua_function(tolua_S,"cPlugin__OnPostCrafting",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPostCrafting00);
- tolua_function(tolua_S,"cPlugin__OnBlockToPickup",tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockToPickup00);
- tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPlugin_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPlugin_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPlugin_new00_local);
- tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cPlugin_delete00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cPlugin_NewLua","cPlugin_NewLua","cPlugin",NULL);
- tolua_beginmodule(tolua_S,"cPlugin_NewLua");
- tolua_function(tolua_S,"OnDisable",tolua_AllToLua_cPlugin_NewLua_OnDisable00);
- tolua_function(tolua_S,"Initialize",tolua_AllToLua_cPlugin_NewLua_Initialize00);
- tolua_function(tolua_S,"Tick",tolua_AllToLua_cPlugin_NewLua_Tick00);
- tolua_function(tolua_S,"CreateWebPlugin",tolua_AllToLua_cPlugin_NewLua_CreateWebPlugin00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"Lua__cPlugin_NewLua","Lua__cPlugin_NewLua","cPlugin_NewLua",NULL);
- tolua_beginmodule(tolua_S,"Lua__cPlugin_NewLua");
- tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPlugin_NewLua_tolua__set_instance00);
- tolua_function(tolua_S,"cPlugin_NewLua__OnDisable",tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__OnDisable00);
- tolua_function(tolua_S,"cPlugin_NewLua__Initialize",tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Initialize00);
- tolua_function(tolua_S,"cPlugin_NewLua__Tick",tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Tick00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cPlugin_Lua","cPlugin_Lua","",NULL);
- tolua_beginmodule(tolua_S,"cPlugin_Lua");
- tolua_function(tolua_S,"GetFileName",tolua_AllToLua_cPlugin_Lua_GetFileName00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cServer","cServer","",NULL);
- tolua_beginmodule(tolua_S,"cServer");
- tolua_function(tolua_S,"GetServer",tolua_AllToLua_cServer_GetServer00);
- tolua_function(tolua_S,"ServerCommand",tolua_AllToLua_cServer_ServerCommand00);
- tolua_function(tolua_S,"SendMessage",tolua_AllToLua_cServer_SendMessage00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cWorld","cWorld","",NULL);
- tolua_beginmodule(tolua_S,"cWorld");
- tolua_function(tolua_S,"GetTime",tolua_AllToLua_cWorld_GetTime00);
- tolua_function(tolua_S,"GetGameMode",tolua_AllToLua_cWorld_GetGameMode00);
- tolua_function(tolua_S,"SetWorldTime",tolua_AllToLua_cWorld_SetWorldTime00);
- tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cWorld_GetHeight00);
- tolua_function(tolua_S,"UnloadUnusedChunks",tolua_AllToLua_cWorld_UnloadUnusedChunks00);
- tolua_function(tolua_S,"GetMaxPlayers",tolua_AllToLua_cWorld_GetMaxPlayers00);
- tolua_function(tolua_S,"SetMaxPlayers",tolua_AllToLua_cWorld_SetMaxPlayers00);
- tolua_function(tolua_S,"GetNumPlayers",tolua_AllToLua_cWorld_GetNumPlayers00);
- tolua_function(tolua_S,"GetPlayer",tolua_AllToLua_cWorld_GetPlayer00);
- tolua_function(tolua_S,"UpdateSign",tolua_AllToLua_cWorld_UpdateSign00);
- tolua_function(tolua_S,"RegenerateChunk",tolua_AllToLua_cWorld_RegenerateChunk00);
- tolua_function(tolua_S,"GenerateChunk",tolua_AllToLua_cWorld_GenerateChunk00);
- tolua_function(tolua_S,"SetBlock",tolua_AllToLua_cWorld_SetBlock00);
- tolua_function(tolua_S,"FastSetBlock",tolua_AllToLua_cWorld_FastSetBlock00);
- tolua_function(tolua_S,"GetBlock",tolua_AllToLua_cWorld_GetBlock00);
- tolua_function(tolua_S,"GetBlock",tolua_AllToLua_cWorld_GetBlock01);
- tolua_function(tolua_S,"GetBlockMeta",tolua_AllToLua_cWorld_GetBlockMeta00);
- tolua_function(tolua_S,"GetBlockMeta",tolua_AllToLua_cWorld_GetBlockMeta01);
- tolua_function(tolua_S,"SetBlockMeta",tolua_AllToLua_cWorld_SetBlockMeta00);
- tolua_function(tolua_S,"SetBlockMeta",tolua_AllToLua_cWorld_SetBlockMeta01);
- tolua_function(tolua_S,"GetBlockSkyLight",tolua_AllToLua_cWorld_GetBlockSkyLight00);
- tolua_function(tolua_S,"GetBlockTypeMeta",tolua_AllToLua_cWorld_GetBlockTypeMeta00);
- tolua_function(tolua_S,"DigBlock",tolua_AllToLua_cWorld_DigBlock00);
- tolua_function(tolua_S,"SendBlockTo",tolua_AllToLua_cWorld_SendBlockTo00);
- tolua_function(tolua_S,"GetSpawnX",tolua_AllToLua_cWorld_GetSpawnX00);
- tolua_function(tolua_S,"GetSpawnY",tolua_AllToLua_cWorld_GetSpawnY00);
- tolua_function(tolua_S,"GetSpawnZ",tolua_AllToLua_cWorld_GetSpawnZ00);
- tolua_function(tolua_S,"GetBlockEntity",tolua_AllToLua_cWorld_GetBlockEntity00);
- tolua_function(tolua_S,"GrowTree",tolua_AllToLua_cWorld_GrowTree00);
- tolua_function(tolua_S,"GrowTreeFromSapling",tolua_AllToLua_cWorld_GrowTreeFromSapling00);
- tolua_function(tolua_S,"GrowTreeByBiome",tolua_AllToLua_cWorld_GrowTreeByBiome00);
- tolua_function(tolua_S,"GrowPlant",tolua_AllToLua_cWorld_GrowPlant00);
- tolua_function(tolua_S,"GrowMelonPumpkin",tolua_AllToLua_cWorld_GrowMelonPumpkin00);
- tolua_function(tolua_S,"GetBiomeAt",tolua_AllToLua_cWorld_GetBiomeAt00);
- tolua_function(tolua_S,"GetName",tolua_AllToLua_cWorld_GetName00);
- tolua_function(tolua_S,"SaveAllChunks",tolua_AllToLua_cWorld_SaveAllChunks00);
- tolua_function(tolua_S,"GetNumChunks",tolua_AllToLua_cWorld_GetNumChunks00);
- tolua_function(tolua_S,"GetGeneratorQueueLength",tolua_AllToLua_cWorld_GetGeneratorQueueLength00);
- tolua_function(tolua_S,"GetLightingQueueLength",tolua_AllToLua_cWorld_GetLightingQueueLength00);
- tolua_function(tolua_S,"GetStorageLoadQueueLength",tolua_AllToLua_cWorld_GetStorageLoadQueueLength00);
- tolua_function(tolua_S,"GetStorageSaveQueueLength",tolua_AllToLua_cWorld_GetStorageSaveQueueLength00);
- tolua_function(tolua_S,"CastThunderbolt",tolua_AllToLua_cWorld_CastThunderbolt00);
- tolua_function(tolua_S,"SetWeather",tolua_AllToLua_cWorld_SetWeather00);
- tolua_function(tolua_S,"ChangeWeather",tolua_AllToLua_cWorld_ChangeWeather00);
- tolua_function(tolua_S,"GetWeather",tolua_AllToLua_cWorld_GetWeather00);
- tolua_function(tolua_S,"SetNextBlockTick",tolua_AllToLua_cWorld_SetNextBlockTick00);
- tolua_function(tolua_S,"GetMaxSugarcaneHeight",tolua_AllToLua_cWorld_GetMaxSugarcaneHeight00);
- tolua_function(tolua_S,"GetMaxCactusHeight",tolua_AllToLua_cWorld_GetMaxCactusHeight00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cInventory","cInventory","",NULL);
- tolua_beginmodule(tolua_S,"cInventory");
- tolua_function(tolua_S,"Clear",tolua_AllToLua_cInventory_Clear00);
- tolua_function(tolua_S,"AddItem",tolua_AllToLua_cInventory_AddItem00);
- tolua_function(tolua_S,"RemoveItem",tolua_AllToLua_cInventory_RemoveItem00);
- tolua_function(tolua_S,"GetSlot",tolua_AllToLua_cInventory_GetSlot00);
- tolua_function(tolua_S,"GetFromHotBar",tolua_AllToLua_cInventory_GetFromHotBar00);
- tolua_function(tolua_S,"GetEquippedItem",tolua_AllToLua_cInventory_GetEquippedItem00);
- tolua_function(tolua_S,"SetEquippedSlot",tolua_AllToLua_cInventory_SetEquippedSlot00);
- tolua_function(tolua_S,"GetEquippedSlot",tolua_AllToLua_cInventory_GetEquippedSlot00);
- tolua_function(tolua_S,"SendSlot",tolua_AllToLua_cInventory_SendSlot00);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"cItem","cItem","",tolua_collect_cItem);
- #else
- tolua_cclass(tolua_S,"cItem","cItem","",NULL);
- #endif
- tolua_beginmodule(tolua_S,"cItem");
- tolua_function(tolua_S,"new",tolua_AllToLua_cItem_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_cItem_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_cItem_new00_local);
- tolua_function(tolua_S,"Empty",tolua_AllToLua_cItem_Empty00);
- tolua_function(tolua_S,"Clear",tolua_AllToLua_cItem_Clear00);
- tolua_function(tolua_S,"IsEmpty",tolua_AllToLua_cItem_IsEmpty00);
- tolua_function(tolua_S,"Equals",tolua_AllToLua_cItem_Equals00);
- tolua_function(tolua_S,"GetMaxDuration",tolua_AllToLua_cItem_GetMaxDuration00);
- tolua_function(tolua_S,"DamageItem",tolua_AllToLua_cItem_DamageItem00);
- tolua_function(tolua_S,"HasDuration",tolua_AllToLua_cItem_HasDuration00);
- tolua_function(tolua_S,"GetJson",tolua_AllToLua_cItem_GetJson00);
- tolua_function(tolua_S,"FromJson",tolua_AllToLua_cItem_FromJson00);
- tolua_function(tolua_S,"IsEnchantable",tolua_AllToLua_cItem_IsEnchantable00);
- tolua_variable(tolua_S,"m_ItemID",tolua_get_cItem_m_ItemID,tolua_set_cItem_m_ItemID);
- tolua_variable(tolua_S,"m_ItemCount",tolua_get_cItem_m_ItemCount,tolua_set_cItem_m_ItemCount);
- tolua_variable(tolua_S,"m_ItemHealth",tolua_get_cItem_m_ItemHealth,tolua_set_cItem_m_ItemHealth);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"HTTPFormData","HTTPFormData","",NULL);
- tolua_beginmodule(tolua_S,"HTTPFormData");
- tolua_variable(tolua_S,"Name",tolua_get_HTTPFormData_Name,tolua_set_HTTPFormData_Name);
- tolua_variable(tolua_S,"Value",tolua_get_HTTPFormData_Value,tolua_set_HTTPFormData_Value);
- tolua_variable(tolua_S,"Type",tolua_get_HTTPFormData_Type,tolua_set_HTTPFormData_Type);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"HTTPRequest","HTTPRequest","",NULL);
- tolua_beginmodule(tolua_S,"HTTPRequest");
- tolua_variable(tolua_S,"Method",tolua_get_HTTPRequest_Method,tolua_set_HTTPRequest_Method);
- tolua_variable(tolua_S,"Path",tolua_get_HTTPRequest_Path,tolua_set_HTTPRequest_Path);
- tolua_variable(tolua_S,"Username",tolua_get_HTTPRequest_Username,tolua_set_HTTPRequest_Username);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"cWebPlugin","cWebPlugin","",tolua_collect_cWebPlugin);
- #else
- tolua_cclass(tolua_S,"cWebPlugin","cWebPlugin","",NULL);
- #endif
- tolua_beginmodule(tolua_S,"cWebPlugin");
- tolua_function(tolua_S,"delete",tolua_AllToLua_cWebPlugin_delete00);
- tolua_function(tolua_S,"SetName",tolua_AllToLua_cWebPlugin_SetName00);
- tolua_function(tolua_S,"GetName",tolua_AllToLua_cWebPlugin_GetName00);
- tolua_function(tolua_S,"HandleRequest",tolua_AllToLua_cWebPlugin_HandleRequest00);
- tolua_function(tolua_S,"Initialize",tolua_AllToLua_cWebPlugin_Initialize00);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"Lua__cWebPlugin","Lua__cWebPlugin","cWebPlugin",tolua_collect_Lua__cWebPlugin);
- #else
- tolua_cclass(tolua_S,"Lua__cWebPlugin","Lua__cWebPlugin","cWebPlugin",NULL);
- #endif
- tolua_beginmodule(tolua_S,"Lua__cWebPlugin");
- tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cWebPlugin_tolua__set_instance00);
- tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cWebPlugin_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cWebPlugin_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cWebPlugin_new00_local);
- tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cWebPlugin_delete00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cWebPlugin_Lua","cWebPlugin_Lua","cWebPlugin",NULL);
- tolua_beginmodule(tolua_S,"cWebPlugin_Lua");
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"cPickup","cPickup","cEntity",tolua_collect_cPickup);
- #else
- tolua_cclass(tolua_S,"cPickup","cPickup","cEntity",NULL);
- #endif
- tolua_beginmodule(tolua_S,"cPickup");
- tolua_function(tolua_S,"new",tolua_AllToLua_cPickup_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_cPickup_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_cPickup_new00_local);
- tolua_function(tolua_S,"new",tolua_AllToLua_cPickup_new01);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_cPickup_new01_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_cPickup_new01_local);
- tolua_function(tolua_S,"delete",tolua_AllToLua_cPickup_delete00);
- tolua_function(tolua_S,"GetItem",tolua_AllToLua_cPickup_GetItem00);
- tolua_function(tolua_S,"CollectedBy",tolua_AllToLua_cPickup_CollectedBy00);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"Lua__cPickup","Lua__cPickup","cPickup",tolua_collect_Lua__cPickup);
- #else
- tolua_cclass(tolua_S,"Lua__cPickup","Lua__cPickup","cPickup",NULL);
- #endif
- tolua_beginmodule(tolua_S,"Lua__cPickup");
- tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPickup_tolua__set_instance00);
- tolua_function(tolua_S,"cPickup__CollectedBy",tolua_AllToLua_Lua__cPickup_cPickup__CollectedBy00);
- tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPickup_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPickup_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPickup_new00_local);
- tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPickup_new01);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPickup_new01_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPickup_new01_local);
- tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cPickup_delete00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cRoot","cRoot","",NULL);
- tolua_beginmodule(tolua_S,"cRoot");
- tolua_function(tolua_S,"Get",tolua_AllToLua_cRoot_Get00);
- tolua_function(tolua_S,"GetServer",tolua_AllToLua_cRoot_GetServer00);
- tolua_function(tolua_S,"GetDefaultWorld",tolua_AllToLua_cRoot_GetDefaultWorld00);
- tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cRoot_GetWorld00);
- tolua_function(tolua_S,"GetGroupManager",tolua_AllToLua_cRoot_GetGroupManager00);
- tolua_function(tolua_S,"GetCraftingRecipes",tolua_AllToLua_cRoot_GetCraftingRecipes00);
- tolua_function(tolua_S,"GetFurnaceRecipe",tolua_AllToLua_cRoot_GetFurnaceRecipe00);
- tolua_function(tolua_S,"GetWebAdmin",tolua_AllToLua_cRoot_GetWebAdmin00);
- tolua_function(tolua_S,"GetPluginManager",tolua_AllToLua_cRoot_GetPluginManager00);
- tolua_function(tolua_S,"ServerCommand",tolua_AllToLua_cRoot_ServerCommand00);
- tolua_function(tolua_S,"GetTotalChunkCount",tolua_AllToLua_cRoot_GetTotalChunkCount00);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"cTCPLink","cTCPLink","",tolua_collect_cTCPLink);
- #else
- tolua_cclass(tolua_S,"cTCPLink","cTCPLink","",NULL);
- #endif
- tolua_beginmodule(tolua_S,"cTCPLink");
- tolua_function(tolua_S,"delete",tolua_AllToLua_cTCPLink_delete00);
- tolua_function(tolua_S,"Connect",tolua_AllToLua_cTCPLink_Connect00);
- tolua_function(tolua_S,"Send",tolua_AllToLua_cTCPLink_Send00);
- tolua_function(tolua_S,"SendMessage",tolua_AllToLua_cTCPLink_SendMessage00);
- tolua_function(tolua_S,"CloseSocket",tolua_AllToLua_cTCPLink_CloseSocket00);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"Lua__cTCPLink","Lua__cTCPLink","cTCPLink",tolua_collect_Lua__cTCPLink);
- #else
- tolua_cclass(tolua_S,"Lua__cTCPLink","Lua__cTCPLink","cTCPLink",NULL);
- #endif
- tolua_beginmodule(tolua_S,"Lua__cTCPLink");
- tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cTCPLink_tolua__set_instance00);
- tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cTCPLink_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cTCPLink_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cTCPLink_new00_local);
- tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cTCPLink_delete00);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"Vector3f","Vector3f","",tolua_collect_Vector3f);
- #else
- tolua_cclass(tolua_S,"Vector3f","Vector3f","",NULL);
- #endif
- tolua_beginmodule(tolua_S,"Vector3f");
- tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new00_local);
- tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new01);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new01_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new01_local);
- tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new02);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new02_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new02_local);
- tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new03);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new03_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new03_local);
- tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new04);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new04_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new04_local);
- tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new05);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new05_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new05_local);
- tolua_function(tolua_S,"Set",tolua_AllToLua_Vector3f_Set00);
- tolua_function(tolua_S,"Normalize",tolua_AllToLua_Vector3f_Normalize00);
- tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3f_NormalizeCopy00);
- tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3f_NormalizeCopy01);
- tolua_function(tolua_S,"Length",tolua_AllToLua_Vector3f_Length00);
- tolua_function(tolua_S,"SqrLength",tolua_AllToLua_Vector3f_SqrLength00);
- tolua_function(tolua_S,"Dot",tolua_AllToLua_Vector3f_Dot00);
- tolua_function(tolua_S,"Cross",tolua_AllToLua_Vector3f_Cross00);
- tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3f_Equals00);
- tolua_function(tolua_S,".add",tolua_AllToLua_Vector3f__add00);
- tolua_function(tolua_S,".add",tolua_AllToLua_Vector3f__add01);
- tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3f__sub00);
- tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3f__sub01);
- tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3f__mul00);
- tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3f__mul01);
- tolua_variable(tolua_S,"x",tolua_get_Vector3f_x,tolua_set_Vector3f_x);
- tolua_variable(tolua_S,"y",tolua_get_Vector3f_y,tolua_set_Vector3f_y);
- tolua_variable(tolua_S,"z",tolua_get_Vector3f_z,tolua_set_Vector3f_z);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"Vector3d","Vector3d","",tolua_collect_Vector3d);
- #else
- tolua_cclass(tolua_S,"Vector3d","Vector3d","",NULL);
- #endif
- tolua_beginmodule(tolua_S,"Vector3d");
- tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new00_local);
- tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new01);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new01_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new01_local);
- tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new02);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new02_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new02_local);
- tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new03);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new03_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new03_local);
- tolua_function(tolua_S,"Set",tolua_AllToLua_Vector3d_Set00);
- tolua_function(tolua_S,"Normalize",tolua_AllToLua_Vector3d_Normalize00);
- tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3d_NormalizeCopy00);
- tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3d_NormalizeCopy01);
- tolua_function(tolua_S,"Length",tolua_AllToLua_Vector3d_Length00);
- tolua_function(tolua_S,"SqrLength",tolua_AllToLua_Vector3d_SqrLength00);
- tolua_function(tolua_S,"Dot",tolua_AllToLua_Vector3d_Dot00);
- tolua_function(tolua_S,"Cross",tolua_AllToLua_Vector3d_Cross00);
- tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3d_Equals00);
- tolua_function(tolua_S,".add",tolua_AllToLua_Vector3d__add00);
- tolua_function(tolua_S,".add",tolua_AllToLua_Vector3d__add01);
- tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3d__sub00);
- tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3d__sub01);
- tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3d__mul00);
- tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3d__mul01);
- tolua_variable(tolua_S,"x",tolua_get_Vector3d_x,tolua_set_Vector3d_x);
- tolua_variable(tolua_S,"y",tolua_get_Vector3d_y,tolua_set_Vector3d_y);
- tolua_variable(tolua_S,"z",tolua_get_Vector3d_z,tolua_set_Vector3d_z);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"Vector3i","Vector3i","",tolua_collect_Vector3i);
- #else
- tolua_cclass(tolua_S,"Vector3i","Vector3i","",NULL);
- #endif
- tolua_beginmodule(tolua_S,"Vector3i");
- tolua_function(tolua_S,"new",tolua_AllToLua_Vector3i_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3i_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Vector3i_new00_local);
- tolua_function(tolua_S,"new",tolua_AllToLua_Vector3i_new01);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3i_new01_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Vector3i_new01_local);
- tolua_function(tolua_S,"new",tolua_AllToLua_Vector3i_new02);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3i_new02_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Vector3i_new02_local);
- tolua_function(tolua_S,"Set",tolua_AllToLua_Vector3i_Set00);
- tolua_function(tolua_S,"Length",tolua_AllToLua_Vector3i_Length00);
- tolua_function(tolua_S,"SqrLength",tolua_AllToLua_Vector3i_SqrLength00);
- tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3i_Equals00);
- tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3i_Equals01);
- tolua_variable(tolua_S,"x",tolua_get_Vector3i_x,tolua_set_Vector3i_x);
- tolua_variable(tolua_S,"y",tolua_get_Vector3i_y,tolua_set_Vector3i_y);
- tolua_variable(tolua_S,"z",tolua_get_Vector3i_z,tolua_set_Vector3i_z);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"cCuboid","cCuboid","",tolua_collect_cCuboid);
- #else
- tolua_cclass(tolua_S,"cCuboid","cCuboid","",NULL);
- #endif
- tolua_beginmodule(tolua_S,"cCuboid");
- tolua_function(tolua_S,"new",tolua_AllToLua_cCuboid_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_cCuboid_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_cCuboid_new00_local);
- tolua_function(tolua_S,"new",tolua_AllToLua_cCuboid_new01);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_cCuboid_new01_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_cCuboid_new01_local);
- tolua_function(tolua_S,"new",tolua_AllToLua_cCuboid_new02);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_cCuboid_new02_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_cCuboid_new02_local);
- tolua_variable(tolua_S,"p1",tolua_get_cCuboid_p1,tolua_set_cCuboid_p1);
- tolua_variable(tolua_S,"p2",tolua_get_cCuboid_p2,tolua_set_cCuboid_p2);
- tolua_function(tolua_S,"Sort",tolua_AllToLua_cCuboid_Sort00);
- tolua_function(tolua_S,"IsInside",tolua_AllToLua_cCuboid_IsInside00);
- tolua_function(tolua_S,"IsInside",tolua_AllToLua_cCuboid_IsInside01);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"cMCLogger","cMCLogger","",tolua_collect_cMCLogger);
- #else
- tolua_cclass(tolua_S,"cMCLogger","cMCLogger","",NULL);
- #endif
- tolua_beginmodule(tolua_S,"cMCLogger");
- tolua_function(tolua_S,"new",tolua_AllToLua_cMCLogger_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_cMCLogger_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_cMCLogger_new00_local);
- tolua_function(tolua_S,"delete",tolua_AllToLua_cMCLogger_delete00);
- tolua_function(tolua_S,"LogSimple",tolua_AllToLua_cMCLogger_LogSimple00);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"cTracer","cTracer","",tolua_collect_cTracer);
- #else
- tolua_cclass(tolua_S,"cTracer","cTracer","",NULL);
- #endif
- tolua_beginmodule(tolua_S,"cTracer");
- tolua_function(tolua_S,"new",tolua_AllToLua_cTracer_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_cTracer_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_cTracer_new00_local);
- tolua_function(tolua_S,"delete",tolua_AllToLua_cTracer_delete00);
- tolua_function(tolua_S,"Trace",tolua_AllToLua_cTracer_Trace00);
- tolua_function(tolua_S,"SetValues",tolua_AllToLua_cTracer_SetValues00);
- tolua_variable(tolua_S,"BlockHitPosition",tolua_get_cTracer_BlockHitPosition,tolua_set_cTracer_BlockHitPosition);
- tolua_variable(tolua_S,"HitNormal",tolua_get_cTracer_HitNormal,tolua_set_cTracer_HitNormal);
- tolua_variable(tolua_S,"RealHit",tolua_get_cTracer_RealHit,tolua_set_cTracer_RealHit);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cGroup","cGroup","",NULL);
- tolua_beginmodule(tolua_S,"cGroup");
- tolua_function(tolua_S,"SetName",tolua_AllToLua_cGroup_SetName00);
- tolua_function(tolua_S,"GetName",tolua_AllToLua_cGroup_GetName00);
- tolua_function(tolua_S,"SetColor",tolua_AllToLua_cGroup_SetColor00);
- tolua_function(tolua_S,"AddCommand",tolua_AllToLua_cGroup_AddCommand00);
- tolua_function(tolua_S,"AddPermission",tolua_AllToLua_cGroup_AddPermission00);
- tolua_function(tolua_S,"InheritFrom",tolua_AllToLua_cGroup_InheritFrom00);
- tolua_function(tolua_S,"HasCommand",tolua_AllToLua_cGroup_HasCommand00);
- tolua_function(tolua_S,"GetColor",tolua_AllToLua_cGroup_GetColor00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cPacket_Login","cPacket_Login","cPacket",NULL);
- tolua_beginmodule(tolua_S,"cPacket_Login");
- tolua_variable(tolua_S,"m_ProtocolVersion",tolua_get_cPacket_Login_m_ProtocolVersion,tolua_set_cPacket_Login_m_ProtocolVersion);
- tolua_variable(tolua_S,"m_Username",tolua_get_cPacket_Login_m_Username,tolua_set_cPacket_Login_m_Username);
- tolua_variable(tolua_S,"m_LevelType",tolua_get_cPacket_Login_m_LevelType,tolua_set_cPacket_Login_m_LevelType);
- tolua_variable(tolua_S,"m_ServerMode",tolua_get_cPacket_Login_m_ServerMode,tolua_set_cPacket_Login_m_ServerMode);
- tolua_variable(tolua_S,"m_Difficulty",tolua_get_cPacket_Login_m_Difficulty,tolua_set_cPacket_Login_m_Difficulty);
- tolua_variable(tolua_S,"m_WorldHeight",tolua_get_cPacket_Login_unsigned_m_WorldHeight,tolua_set_cPacket_Login_unsigned_m_WorldHeight);
- tolua_variable(tolua_S,"m_MaxPlayers",tolua_get_cPacket_Login_unsigned_m_MaxPlayers,tolua_set_cPacket_Login_unsigned_m_MaxPlayers);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"cPacket_BlockDig","cPacket_BlockDig","cPacket",tolua_collect_cPacket_BlockDig);
- #else
- tolua_cclass(tolua_S,"cPacket_BlockDig","cPacket_BlockDig","cPacket",NULL);
- #endif
- tolua_beginmodule(tolua_S,"cPacket_BlockDig");
- tolua_function(tolua_S,"new",tolua_AllToLua_cPacket_BlockDig_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_cPacket_BlockDig_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_cPacket_BlockDig_new00_local);
- tolua_function(tolua_S,"Clone",tolua_AllToLua_cPacket_BlockDig_Clone00);
- tolua_variable(tolua_S,"m_Status",tolua_get_cPacket_BlockDig_m_Status,tolua_set_cPacket_BlockDig_m_Status);
- tolua_variable(tolua_S,"m_PosX",tolua_get_cPacket_BlockDig_m_PosX,tolua_set_cPacket_BlockDig_m_PosX);
- tolua_variable(tolua_S,"m_PosY",tolua_get_cPacket_BlockDig_m_PosY,tolua_set_cPacket_BlockDig_m_PosY);
- tolua_variable(tolua_S,"m_PosZ",tolua_get_cPacket_BlockDig_m_PosZ,tolua_set_cPacket_BlockDig_m_PosZ);
- tolua_variable(tolua_S,"m_Direction",tolua_get_cPacket_BlockDig_m_Direction,tolua_set_cPacket_BlockDig_m_Direction);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"Lua__cPacket_BlockDig","Lua__cPacket_BlockDig","cPacket_BlockDig",tolua_collect_Lua__cPacket_BlockDig);
- #else
- tolua_cclass(tolua_S,"Lua__cPacket_BlockDig","Lua__cPacket_BlockDig","cPacket_BlockDig",NULL);
- #endif
- tolua_beginmodule(tolua_S,"Lua__cPacket_BlockDig");
- tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPacket_BlockDig_tolua__set_instance00);
- tolua_function(tolua_S,"cPacket_BlockDig__Clone",tolua_AllToLua_Lua__cPacket_BlockDig_cPacket_BlockDig__Clone00);
- tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPacket_BlockDig_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPacket_BlockDig_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPacket_BlockDig_new00_local);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cPacket_BlockPlace","cPacket_BlockPlace","cPacket",NULL);
- tolua_beginmodule(tolua_S,"cPacket_BlockPlace");
- tolua_variable(tolua_S,"m_PosX",tolua_get_cPacket_BlockPlace_m_PosX,tolua_set_cPacket_BlockPlace_m_PosX);
- tolua_variable(tolua_S,"m_PosY",tolua_get_cPacket_BlockPlace_unsigned_m_PosY,tolua_set_cPacket_BlockPlace_unsigned_m_PosY);
- tolua_variable(tolua_S,"m_PosZ",tolua_get_cPacket_BlockPlace_m_PosZ,tolua_set_cPacket_BlockPlace_m_PosZ);
- tolua_variable(tolua_S,"m_Direction",tolua_get_cPacket_BlockPlace_m_Direction,tolua_set_cPacket_BlockPlace_m_Direction);
- tolua_variable(tolua_S,"m_ItemType",tolua_get_cPacket_BlockPlace_m_ItemType,tolua_set_cPacket_BlockPlace_m_ItemType);
- tolua_variable(tolua_S,"m_Count",tolua_get_cPacket_BlockPlace_m_Count,tolua_set_cPacket_BlockPlace_m_Count);
- tolua_variable(tolua_S,"m_Uses",tolua_get_cPacket_BlockPlace_m_Uses,tolua_set_cPacket_BlockPlace_m_Uses);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cLuaChunk","cLuaChunk","",NULL);
- tolua_beginmodule(tolua_S,"cLuaChunk");
- tolua_function(tolua_S,"FillBlocks",tolua_AllToLua_cLuaChunk_FillBlocks00);
- tolua_function(tolua_S,"SetBlock",tolua_AllToLua_cLuaChunk_SetBlock00);
- tolua_function(tolua_S,"GetBlock",tolua_AllToLua_cLuaChunk_GetBlock00);
- tolua_function(tolua_S,"GetBlockMeta",tolua_AllToLua_cLuaChunk_GetBlockMeta00);
- tolua_function(tolua_S,"SetBiome",tolua_AllToLua_cLuaChunk_SetBiome00);
- tolua_function(tolua_S,"GetBiome",tolua_AllToLua_cLuaChunk_GetBiome00);
- tolua_function(tolua_S,"SetHeight",tolua_AllToLua_cLuaChunk_SetHeight00);
- tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cLuaChunk_GetHeight00);
- tolua_function(tolua_S,"SetUseDefaultBiomes",tolua_AllToLua_cLuaChunk_SetUseDefaultBiomes00);
- tolua_function(tolua_S,"IsUsingDefaultBiomes",tolua_AllToLua_cLuaChunk_IsUsingDefaultBiomes00);
- tolua_function(tolua_S,"SetUseDefaultComposition",tolua_AllToLua_cLuaChunk_SetUseDefaultComposition00);
- tolua_function(tolua_S,"IsUsingDefaultComposition",tolua_AllToLua_cLuaChunk_IsUsingDefaultComposition00);
- tolua_function(tolua_S,"SetUseDefaultStructures",tolua_AllToLua_cLuaChunk_SetUseDefaultStructures00);
- tolua_function(tolua_S,"IsUsingDefaultStructures",tolua_AllToLua_cLuaChunk_IsUsingDefaultStructures00);
- tolua_function(tolua_S,"SetUseDefaultFinish",tolua_AllToLua_cLuaChunk_SetUseDefaultFinish00);
- tolua_function(tolua_S,"IsUsingDefaultFinish",tolua_AllToLua_cLuaChunk_IsUsingDefaultFinish00);
- tolua_endmodule(tolua_S);
- #ifdef __cplusplus
- tolua_cclass(tolua_S,"cCraftingGrid","cCraftingGrid","",tolua_collect_cCraftingGrid);
- #else
- tolua_cclass(tolua_S,"cCraftingGrid","cCraftingGrid","",NULL);
- #endif
- tolua_beginmodule(tolua_S,"cCraftingGrid");
- tolua_function(tolua_S,"new",tolua_AllToLua_cCraftingGrid_new00);
- tolua_function(tolua_S,"new_local",tolua_AllToLua_cCraftingGrid_new00_local);
- tolua_function(tolua_S,".call",tolua_AllToLua_cCraftingGrid_new00_local);
- tolua_function(tolua_S,"GetWidth",tolua_AllToLua_cCraftingGrid_GetWidth00);
- tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cCraftingGrid_GetHeight00);
- tolua_function(tolua_S,"GetItem",tolua_AllToLua_cCraftingGrid_GetItem00);
- tolua_function(tolua_S,"SetItem",tolua_AllToLua_cCraftingGrid_SetItem00);
- tolua_function(tolua_S,"SetItem",tolua_AllToLua_cCraftingGrid_SetItem01);
- tolua_function(tolua_S,"Clear",tolua_AllToLua_cCraftingGrid_Clear00);
- tolua_function(tolua_S,"ConsumeGrid",tolua_AllToLua_cCraftingGrid_ConsumeGrid00);
- tolua_function(tolua_S,"Dump",tolua_AllToLua_cCraftingGrid_Dump00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cCraftingRecipe","cCraftingRecipe","",NULL);
- tolua_beginmodule(tolua_S,"cCraftingRecipe");
- tolua_function(tolua_S,"Clear",tolua_AllToLua_cCraftingRecipe_Clear00);
- tolua_function(tolua_S,"GetIngredientsWidth",tolua_AllToLua_cCraftingRecipe_GetIngredientsWidth00);
- tolua_function(tolua_S,"GetIngredientsHeight",tolua_AllToLua_cCraftingRecipe_GetIngredientsHeight00);
- tolua_function(tolua_S,"GetIngredient",tolua_AllToLua_cCraftingRecipe_GetIngredient00);
- tolua_function(tolua_S,"GetResult",tolua_AllToLua_cCraftingRecipe_GetResult00);
- tolua_function(tolua_S,"SetResult",tolua_AllToLua_cCraftingRecipe_SetResult00);
- tolua_function(tolua_S,"SetResult",tolua_AllToLua_cCraftingRecipe_SetResult01);
- tolua_function(tolua_S,"SetIngredient",tolua_AllToLua_cCraftingRecipe_SetIngredient00);
- tolua_function(tolua_S,"SetIngredient",tolua_AllToLua_cCraftingRecipe_SetIngredient01);
- tolua_function(tolua_S,"ConsumeIngredients",tolua_AllToLua_cCraftingRecipe_ConsumeIngredients00);
- tolua_function(tolua_S,"Dump",tolua_AllToLua_cCraftingRecipe_Dump00);
- tolua_endmodule(tolua_S);
- tolua_cclass(tolua_S,"cLuaItems","cLuaItems","",NULL);
- tolua_beginmodule(tolua_S,"cLuaItems");
- tolua_function(tolua_S,"Get",tolua_AllToLua_cLuaItems_Get00);
- tolua_function(tolua_S,"Set",tolua_AllToLua_cLuaItems_Set00);
- tolua_function(tolua_S,"Add",tolua_AllToLua_cLuaItems_Add00);
- tolua_function(tolua_S,"Delete",tolua_AllToLua_cLuaItems_Delete00);
- tolua_function(tolua_S,"Clear",tolua_AllToLua_cLuaItems_Clear00);
- tolua_function(tolua_S,"Size",tolua_AllToLua_cLuaItems_Size00);
- tolua_function(tolua_S,"Add",tolua_AllToLua_cLuaItems_Add01);
- tolua_function(tolua_S,"Set",tolua_AllToLua_cLuaItems_Set01);
- tolua_endmodule(tolua_S);
- tolua_endmodule(tolua_S);
- return 1;
-}
-
-
-#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
- TOLUA_API int luaopen_AllToLua (lua_State* tolua_S) {
- return tolua_AllToLua_open(tolua_S);
-};
-#endif
-
+/* +** Lua binding: AllToLua +** Generated automatically by tolua++-1.0.92 on Thu Jun 14 14:20:17 2012. +*/ + +#ifndef __cplusplus +#include "stdlib.h" +#endif +#include "string.h" + +#include "tolua++.h" + +/* Exported function */ +TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules +#include "tolua_base.h" +#include "cTorch.h" +#include "cStairs.h" +#include "cStep.h" +#include "cLadder.h" +#include "../iniFile/iniFile.h" +#include "BlockID.h" +#include "PacketID.h" +#include "Defines.h" +#include "LuaFunctions.h" +#include "cStringMap.h" +#include "cChatColor.h" +#include "cClientHandle.h" +#include "cEntity.h" +#include "cPawn.h" +#include "cPlayer.h" +#include "cPluginManager.h" +#include "cPlugin.h" +#include "cPlugin_NewLua.h" +#include "cPlugin_Lua.h" +#include "cServer.h" +#include "cWorld.h" +#include "cInventory.h" +#include "cItem.h" +#include "cWebAdmin.h" +#include "cWebPlugin.h" +#include "cWebPlugin_Lua.h" +#include "cPickup.h" +#include "cRoot.h" +#include "cTCPLink.h" +#include "Vector3f.h" +#include "Vector3d.h" +#include "Vector3i.h" +#include "Matrix4f.h" +#include "cCuboid.h" +#include "cMCLogger.h" +#include "cTracer.h" +#include "cGroup.h" +#include "packets/cPacket_Login.h" +#include "packets/cPacket_BlockDig.h" +#include "packets/cPacket_BlockPlace.h" +#include "cLuaChunk.h" +#include "CraftingRecipes.h" +#include "LuaItems.h" + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_cMCLogger (lua_State* tolua_S) +{ + cMCLogger* self = (cMCLogger*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cItem (lua_State* tolua_S) +{ + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_Vector3f (lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cIniFile (lua_State* tolua_S) +{ + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cPickup (lua_State* tolua_S) +{ + cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cPacket_BlockDig (lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cTracer (lua_State* tolua_S) +{ + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cPlugin (lua_State* tolua_S) +{ + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cCraftingGrid (lua_State* tolua_S) +{ + cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cCuboid (lua_State* tolua_S) +{ + cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cWebPlugin (lua_State* tolua_S) +{ + cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_Vector3i (lua_State* tolua_S) +{ + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cEntity (lua_State* tolua_S) +{ + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cTCPLink (lua_State* tolua_S) +{ + cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_Vector3d (lua_State* tolua_S) +{ + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} +#endif + + +/* function to register type */ +static void tolua_reg_types (lua_State* tolua_S) +{ + tolua_usertype(tolua_S,"BLOCKTYPE"); + tolua_usertype(tolua_S,"TakeDamageInfo"); + tolua_usertype(tolua_S,"cLuaItems"); + tolua_usertype(tolua_S,"cLuaChunk"); + tolua_usertype(tolua_S,"cCraftingGrid"); + tolua_usertype(tolua_S,"cCraftingRecipe"); + tolua_usertype(tolua_S,"cPlugin"); + tolua_usertype(tolua_S,"cEntity"); + tolua_usertype(tolua_S,"NIBBLETYPE"); + tolua_usertype(tolua_S,"Lua__cPacket_BlockDig"); + tolua_usertype(tolua_S,"cTCPLink"); + tolua_usertype(tolua_S,"Lua__cTCPLink"); + tolua_usertype(tolua_S,"Json::Value"); + tolua_usertype(tolua_S,"cServer"); + tolua_usertype(tolua_S,"cRoot"); + tolua_usertype(tolua_S,"cMCLogger"); + tolua_usertype(tolua_S,"cGroup"); + tolua_usertype(tolua_S,"cTracer"); + tolua_usertype(tolua_S,"cPlugin::CommandStruct"); + tolua_usertype(tolua_S,"cPickup"); + tolua_usertype(tolua_S,"cItems"); + tolua_usertype(tolua_S,"cPacket_Login"); + tolua_usertype(tolua_S,"cClientHandle"); + tolua_usertype(tolua_S,"cStep"); + tolua_usertype(tolua_S,"cFurnaceRecipe"); + tolua_usertype(tolua_S,"cCuboid"); + tolua_usertype(tolua_S,"cChatColor"); + tolua_usertype(tolua_S,"Vector3i"); + tolua_usertype(tolua_S,"cPacket_PickupSpawn"); + tolua_usertype(tolua_S,"Lua__cWebPlugin"); + tolua_usertype(tolua_S,"Lua__cPawn"); + tolua_usertype(tolua_S,"cStairs"); + tolua_usertype(tolua_S,"cItem"); + tolua_usertype(tolua_S,"Vector3f"); + tolua_usertype(tolua_S,"cPlugin_Lua"); + tolua_usertype(tolua_S,"cWebPlugin_Lua"); + tolua_usertype(tolua_S,"Lua__cPlugin_NewLua"); + tolua_usertype(tolua_S,"cPacket"); + tolua_usertype(tolua_S,"cPacket_BlockDig"); + tolua_usertype(tolua_S,"cWebAdmin"); + tolua_usertype(tolua_S,"cCraftingRecipes"); + tolua_usertype(tolua_S,"cBlockEntity"); + tolua_usertype(tolua_S,"cGroupManager"); + tolua_usertype(tolua_S,"Lua__cPickup"); + tolua_usertype(tolua_S,"Lua__cPlugin"); + tolua_usertype(tolua_S,"cWebPlugin"); + tolua_usertype(tolua_S,"cPacket_BlockPlace"); + tolua_usertype(tolua_S,"cLadder"); + tolua_usertype(tolua_S,"cPluginManager"); + tolua_usertype(tolua_S,"HTTPFormData"); + tolua_usertype(tolua_S,"cIniFile"); + tolua_usertype(tolua_S,"Lua__cPlayer"); + tolua_usertype(tolua_S,"HTTPRequest"); + tolua_usertype(tolua_S,"cPawn"); + tolua_usertype(tolua_S,"cPlayer"); + tolua_usertype(tolua_S,"cTorch"); + tolua_usertype(tolua_S,"cStringMap"); + tolua_usertype(tolua_S,"cInventory"); + tolua_usertype(tolua_S,"cWorld"); + tolua_usertype(tolua_S,"cPlugin_NewLua"); + tolua_usertype(tolua_S,"Lua__cEntity"); + tolua_usertype(tolua_S,"Vector3d"); +} + +/* method: DirectionToMetaData of class cTorch */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTorch_DirectionToMetaData00 +static int tolua_AllToLua_cTorch_DirectionToMetaData00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cTorch",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + char a_Direction = ((char) tolua_tonumber(tolua_S,2,0)); + { + char tolua_ret = (char) cTorch::DirectionToMetaData(a_Direction); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DirectionToMetaData'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: MetaDataToDirection of class cTorch */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTorch_MetaDataToDirection00 +static int tolua_AllToLua_cTorch_MetaDataToDirection00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cTorch",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + char a_MetaData = ((char) tolua_tonumber(tolua_S,2,0)); + { + char tolua_ret = (char) cTorch::MetaDataToDirection(a_MetaData); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'MetaDataToDirection'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: RotationToMetaData of class cStairs */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cStairs_RotationToMetaData00 +static int tolua_AllToLua_cStairs_RotationToMetaData00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cStairs",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + float a_Rotation = ((float) tolua_tonumber(tolua_S,2,0)); + int a_Direction = ((int) tolua_tonumber(tolua_S,3,0)); + { + char tolua_ret = (char) cStairs::RotationToMetaData(a_Rotation,a_Direction); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'RotationToMetaData'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DirectionToMetaData of class cStep */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cStep_DirectionToMetaData00 +static int tolua_AllToLua_cStep_DirectionToMetaData00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cStep",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_Direction = ((int) tolua_tonumber(tolua_S,2,0)); + { + char tolua_ret = (char) cStep::DirectionToMetaData(a_Direction); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DirectionToMetaData'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DirectionToMetaData of class cLadder */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLadder_DirectionToMetaData00 +static int tolua_AllToLua_cLadder_DirectionToMetaData00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cLadder",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + char a_Direction = ((char) tolua_tonumber(tolua_S,2,0)); + { + char tolua_ret = (char) cLadder::DirectionToMetaData(a_Direction); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DirectionToMetaData'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: MetaDataToDirection of class cLadder */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLadder_MetaDataToDirection00 +static int tolua_AllToLua_cLadder_MetaDataToDirection00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cLadder",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + char a_MetaData = ((char) tolua_tonumber(tolua_S,2,0)); + { + char tolua_ret = (char) cLadder::MetaDataToDirection(a_MetaData); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'MetaDataToDirection'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_new00 +static int tolua_AllToLua_cIniFile_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,1,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const std::string iniPath = ((const std::string) tolua_tocppstring(tolua_S,2,"")); + { + cIniFile* tolua_ret = (cIniFile*) Mtolua_new((cIniFile)(iniPath)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cIniFile"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_new00_local +static int tolua_AllToLua_cIniFile_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,1,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const std::string iniPath = ((const std::string) tolua_tocppstring(tolua_S,2,"")); + { + cIniFile* tolua_ret = (cIniFile*) Mtolua_new((cIniFile)(iniPath)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cIniFile"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CaseSensitive of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_CaseSensitive00 +static int tolua_AllToLua_cIniFile_CaseSensitive00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CaseSensitive'", NULL); +#endif + { + self->CaseSensitive(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CaseSensitive'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CaseInsensitive of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_CaseInsensitive00 +static int tolua_AllToLua_cIniFile_CaseInsensitive00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CaseInsensitive'", NULL); +#endif + { + self->CaseInsensitive(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CaseInsensitive'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Path of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Path00 +static int tolua_AllToLua_cIniFile_Path00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string newPath = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Path'", NULL); +#endif + { + self->Path(newPath); + tolua_pushcppstring(tolua_S,(const char*)newPath); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Path'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Path of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Path01 +static int tolua_AllToLua_cIniFile_Path01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Path'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->Path(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_Path00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPath of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetPath00 +static int tolua_AllToLua_cIniFile_SetPath00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string newPath = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPath'", NULL); +#endif + { + self->SetPath(newPath); + tolua_pushcppstring(tolua_S,(const char*)newPath); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetPath'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ReadFile of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_ReadFile00 +static int tolua_AllToLua_cIniFile_ReadFile00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ReadFile'", NULL); +#endif + { + bool tolua_ret = (bool) self->ReadFile(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ReadFile'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: WriteFile of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_WriteFile00 +static int tolua_AllToLua_cIniFile_WriteFile00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'WriteFile'", NULL); +#endif + { + bool tolua_ret = (bool) self->WriteFile(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'WriteFile'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Erase of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Erase00 +static int tolua_AllToLua_cIniFile_Erase00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Erase'", NULL); +#endif + { + self->Erase(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Erase'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Clear of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Clear00 +static int tolua_AllToLua_cIniFile_Clear00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); +#endif + { + self->Clear(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Reset of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Reset00 +static int tolua_AllToLua_cIniFile_Reset00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Reset'", NULL); +#endif + { + self->Reset(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Reset'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: FindKey of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_FindKey00 +static int tolua_AllToLua_cIniFile_FindKey00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FindKey'", NULL); +#endif + { + long tolua_ret = (long) self->FindKey(keyname); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'FindKey'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: FindValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_FindValue00 +static int tolua_AllToLua_cIniFile_FindValue00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FindValue'", NULL); +#endif + { + long tolua_ret = (long) self->FindValue(keyID,valuename); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'FindValue'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NumKeys of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumKeys00 +static int tolua_AllToLua_cIniFile_NumKeys00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumKeys'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->NumKeys(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'NumKeys'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetNumKeys of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetNumKeys00 +static int tolua_AllToLua_cIniFile_GetNumKeys00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumKeys'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->GetNumKeys(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetNumKeys'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddKeyName of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_AddKeyName00 +static int tolua_AllToLua_cIniFile_AddKeyName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddKeyName'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->AddKeyName(keyname); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddKeyName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: KeyName of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyName00 +static int tolua_AllToLua_cIniFile_KeyName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->KeyName(keyID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'KeyName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetKeyName of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetKeyName00 +static int tolua_AllToLua_cIniFile_GetKeyName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetKeyName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->GetKeyName(keyID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetKeyName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NumValues of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumValues00 +static int tolua_AllToLua_cIniFile_NumValues00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumValues'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->NumValues(keyname); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'NumValues'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetNumValues of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetNumValues00 +static int tolua_AllToLua_cIniFile_GetNumValues00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumValues'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->GetNumValues(keyname); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetNumValues'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NumValues of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumValues01 +static int tolua_AllToLua_cIniFile_NumValues01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumValues'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->NumValues(keyID); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_NumValues00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetNumValues of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetNumValues01 +static int tolua_AllToLua_cIniFile_GetNumValues01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumValues'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->GetNumValues(keyID); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_GetNumValues00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ValueName of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_ValueName00 +static int tolua_AllToLua_cIniFile_ValueName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ValueName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->ValueName(keyname,valueID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ValueName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueName of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueName00 +static int tolua_AllToLua_cIniFile_GetValueName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->GetValueName(keyname,valueID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ValueName of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_ValueName01 +static int tolua_AllToLua_cIniFile_ValueName01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ValueName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->ValueName(keyID,valueID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_ValueName00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueName of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueName01 +static int tolua_AllToLua_cIniFile_GetValueName01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->GetValueName(keyID,valueID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_GetValueName00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue00 +static int tolua_AllToLua_cIniFile_GetValue00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetValue(keyname,valuename); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValue'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue01 +static int tolua_AllToLua_cIniFile_GetValue01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_iscppstring(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const AString defValue = ((const AString) tolua_tocppstring(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetValue(keyname,valuename,defValue); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + tolua_pushcppstring(tolua_S,(const char*)defValue); + } + } + return 4; +tolua_lerror: + return tolua_AllToLua_cIniFile_GetValue00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue02 +static int tolua_AllToLua_cIniFile_GetValue02(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetValue(keyID,valueID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_GetValue01(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValue03 +static int tolua_AllToLua_cIniFile_GetValue03(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_iscppstring(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); + const AString defValue = ((const AString) tolua_tocppstring(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValue'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetValue(keyID,valueID,defValue); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)defValue); + } + } + return 2; +tolua_lerror: + return tolua_AllToLua_cIniFile_GetValue02(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueF of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueF00 +static int tolua_AllToLua_cIniFile_GetValueF00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const double defValue = ((const double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueF'", NULL); +#endif + { + double tolua_ret = (double) self->GetValueF(keyname,valuename,defValue); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueF'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueI of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueI00 +static int tolua_AllToLua_cIniFile_GetValueI00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const int defValue = ((const int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueI'", NULL); +#endif + { + int tolua_ret = (int) self->GetValueI(keyname,valuename,defValue); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueI'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueB of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueB00 +static int tolua_AllToLua_cIniFile_GetValueB00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isboolean(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const bool defValue = ((const bool) tolua_toboolean(tolua_S,4,false)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueB'", NULL); +#endif + { + bool tolua_ret = (bool) self->GetValueB(keyname,valuename,defValue); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueB'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueSet of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSet00 +static int tolua_AllToLua_cIniFile_GetValueSet00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSet'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetValueSet(keyname,valuename); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueSet'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueSet of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSet01 +static int tolua_AllToLua_cIniFile_GetValueSet01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_iscppstring(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const AString defValue = ((const AString) tolua_tocppstring(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSet'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetValueSet(keyname,valuename,defValue); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + tolua_pushcppstring(tolua_S,(const char*)defValue); + } + } + return 4; +tolua_lerror: + return tolua_AllToLua_cIniFile_GetValueSet00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueSetF of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSetF00 +static int tolua_AllToLua_cIniFile_GetValueSetF00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const double defValue = ((const double) tolua_tonumber(tolua_S,4,0.0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSetF'", NULL); +#endif + { + double tolua_ret = (double) self->GetValueSetF(keyname,valuename,defValue); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueSetF'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueSetI of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSetI00 +static int tolua_AllToLua_cIniFile_GetValueSetI00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const int defValue = ((const int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSetI'", NULL); +#endif + { + int tolua_ret = (int) self->GetValueSetI(keyname,valuename,defValue); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueSetI'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetValueSetB of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_GetValueSetB00 +static int tolua_AllToLua_cIniFile_GetValueSetB00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isboolean(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const AString keyname = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const AString valuename = ((const AString) tolua_tocppstring(tolua_S,3,0)); + const bool defValue = ((const bool) tolua_toboolean(tolua_S,4,false)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetValueSetB'", NULL); +#endif + { + bool tolua_ret = (bool) self->GetValueSetB(keyname,valuename,defValue); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetValueSetB'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValue00 +static int tolua_AllToLua_cIniFile_SetValue00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_iscppstring(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); + const std::string value = ((const std::string) tolua_tocppstring(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValue'", NULL); +#endif + { + bool tolua_ret = (bool) self->SetValue(keyID,valueID,value); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)value); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetValue'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValue01 +static int tolua_AllToLua_cIniFile_SetValue01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_iscppstring(tolua_S,4,0,&tolua_err) || + !tolua_isboolean(tolua_S,5,1,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); + const std::string value = ((const std::string) tolua_tocppstring(tolua_S,4,0)); + const bool create = ((const bool) tolua_toboolean(tolua_S,5,true)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValue'", NULL); +#endif + { + bool tolua_ret = (bool) self->SetValue(keyname,valuename,value,create); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + tolua_pushcppstring(tolua_S,(const char*)value); + } + } + return 4; +tolua_lerror: + return tolua_AllToLua_cIniFile_SetValue00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetValueI of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValueI00 +static int tolua_AllToLua_cIniFile_SetValueI00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isboolean(tolua_S,5,1,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); + const int value = ((const int) tolua_tonumber(tolua_S,4,0)); + const bool create = ((const bool) tolua_toboolean(tolua_S,5,true)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValueI'", NULL); +#endif + { + bool tolua_ret = (bool) self->SetValueI(keyname,valuename,value,create); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetValueI'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetValueB of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValueB00 +static int tolua_AllToLua_cIniFile_SetValueB00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isboolean(tolua_S,4,0,&tolua_err) || + !tolua_isboolean(tolua_S,5,1,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); + const bool value = ((const bool) tolua_toboolean(tolua_S,4,0)); + const bool create = ((const bool) tolua_toboolean(tolua_S,5,true)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValueB'", NULL); +#endif + { + bool tolua_ret = (bool) self->SetValueB(keyname,valuename,value,create); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetValueB'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetValueF of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_SetValueF00 +static int tolua_AllToLua_cIniFile_SetValueF00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isboolean(tolua_S,5,1,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); + const double value = ((const double) tolua_tonumber(tolua_S,4,0)); + const bool create = ((const bool) tolua_toboolean(tolua_S,5,true)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValueF'", NULL); +#endif + { + bool tolua_ret = (bool) self->SetValueF(keyname,valuename,value,create); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetValueF'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteValueByID of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteValueByID00 +static int tolua_AllToLua_cIniFile_DeleteValueByID00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned valueID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteValueByID'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteValueByID(keyID,valueID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DeleteValueByID'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteValue of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteValue00 +static int tolua_AllToLua_cIniFile_DeleteValue00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const std::string valuename = ((const std::string) tolua_tocppstring(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteValue'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteValue(keyname,valuename); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)valuename); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DeleteValue'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteKey of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKey00 +static int tolua_AllToLua_cIniFile_DeleteKey00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKey'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteKey(keyname); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DeleteKey'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NumHeaderComments of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumHeaderComments00 +static int tolua_AllToLua_cIniFile_NumHeaderComments00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumHeaderComments'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->NumHeaderComments(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'NumHeaderComments'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HeaderComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_HeaderComment00 +static int tolua_AllToLua_cIniFile_HeaderComment00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string comment = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HeaderComment'", NULL); +#endif + { + self->HeaderComment(comment); + tolua_pushcppstring(tolua_S,(const char*)comment); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'HeaderComment'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HeaderComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_HeaderComment01 +static int tolua_AllToLua_cIniFile_HeaderComment01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HeaderComment'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->HeaderComment(commentID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_HeaderComment00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteHeaderComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteHeaderComment00 +static int tolua_AllToLua_cIniFile_DeleteHeaderComment00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + unsigned commentID = ((unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteHeaderComment'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteHeaderComment(commentID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DeleteHeaderComment'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteHeaderComments of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteHeaderComments00 +static int tolua_AllToLua_cIniFile_DeleteHeaderComments00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteHeaderComments'", NULL); +#endif + { + self->DeleteHeaderComments(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DeleteHeaderComments'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NumKeyComments of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumKeyComments00 +static int tolua_AllToLua_cIniFile_NumKeyComments00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumKeyComments'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->NumKeyComments(keyID); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'NumKeyComments'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NumKeyComments of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_NumKeyComments01 +static int tolua_AllToLua_cIniFile_NumKeyComments01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NumKeyComments'", NULL); +#endif + { + unsigned tolua_ret = (unsigned) self->NumKeyComments(keyname); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +tolua_lerror: + return tolua_AllToLua_cIniFile_NumKeyComments00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: KeyComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment00 +static int tolua_AllToLua_cIniFile_KeyComment00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const std::string comment = ((const std::string) tolua_tocppstring(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL); +#endif + { + bool tolua_ret = (bool) self->KeyComment(keyID,comment); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)comment); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'KeyComment'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: KeyComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment01 +static int tolua_AllToLua_cIniFile_KeyComment01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const std::string comment = ((const std::string) tolua_tocppstring(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL); +#endif + { + bool tolua_ret = (bool) self->KeyComment(keyname,comment); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + tolua_pushcppstring(tolua_S,(const char*)comment); + } + } + return 3; +tolua_lerror: + return tolua_AllToLua_cIniFile_KeyComment00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: KeyComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment02 +static int tolua_AllToLua_cIniFile_KeyComment02(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->KeyComment(keyID,commentID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cIniFile_KeyComment01(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: KeyComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_KeyComment03 +static int tolua_AllToLua_cIniFile_KeyComment03(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KeyComment'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->KeyComment(keyname,commentID); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +tolua_lerror: + return tolua_AllToLua_cIniFile_KeyComment02(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteKeyComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComment00 +static int tolua_AllToLua_cIniFile_DeleteKeyComment00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); + const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComment'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteKeyComment(keyID,commentID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DeleteKeyComment'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteKeyComment of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComment01 +static int tolua_AllToLua_cIniFile_DeleteKeyComment01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + const unsigned commentID = ((const unsigned) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComment'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteKeyComment(keyname,commentID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +tolua_lerror: + return tolua_AllToLua_cIniFile_DeleteKeyComment00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteKeyComments of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComments00 +static int tolua_AllToLua_cIniFile_DeleteKeyComments00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const unsigned keyID = ((const unsigned) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComments'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteKeyComments(keyID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DeleteKeyComments'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DeleteKeyComments of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_DeleteKeyComments01 +static int tolua_AllToLua_cIniFile_DeleteKeyComments01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const std::string keyname = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DeleteKeyComments'", NULL); +#endif + { + bool tolua_ret = (bool) self->DeleteKeyComments(keyname); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)keyname); + } + } + return 2; +tolua_lerror: + return tolua_AllToLua_cIniFile_DeleteKeyComments00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* function: BlockStringToType */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_BlockStringToType00 +static int tolua_AllToLua_BlockStringToType00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_iscppstring(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const AString a_BlockTypeString = ((const AString) tolua_tocppstring(tolua_S,1,0)); + { + int tolua_ret = (int) BlockStringToType(a_BlockTypeString); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)a_BlockTypeString); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'BlockStringToType'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: StringToItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_StringToItem00 +static int tolua_AllToLua_StringToItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_iscppstring(tolua_S,1,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const AString a_ItemTypeString = ((const AString) tolua_tocppstring(tolua_S,1,0)); + cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); + { + bool tolua_ret = (bool) StringToItem(a_ItemTypeString,*a_Item); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)a_ItemTypeString); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'StringToItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockLightValue */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockLightValue +static int tolua_get_AllToLua_g_BlockLightValue(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)g_BlockLightValue[tolua_index]); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockLightValue */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockLightValue +static int tolua_set_AllToLua_g_BlockLightValue(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + g_BlockLightValue[tolua_index] = ((unsigned char) tolua_tonumber(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockSpreadLightFalloff */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockSpreadLightFalloff +static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)g_BlockSpreadLightFalloff[tolua_index]); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockSpreadLightFalloff */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockSpreadLightFalloff +static int tolua_set_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + g_BlockSpreadLightFalloff[tolua_index] = ((unsigned char) tolua_tonumber(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockTransparent */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockTransparent +static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + tolua_pushboolean(tolua_S,(bool)g_BlockTransparent[tolua_index]); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockTransparent */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockTransparent +static int tolua_set_AllToLua_g_BlockTransparent(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + g_BlockTransparent[tolua_index] = ((bool) tolua_toboolean(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockOneHitDig */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockOneHitDig +static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + tolua_pushboolean(tolua_S,(bool)g_BlockOneHitDig[tolua_index]); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockOneHitDig */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockOneHitDig +static int tolua_set_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) +{ + int tolua_index; +#ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } +#endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); +#ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); +#endif + g_BlockOneHitDig[tolua_index] = ((bool) tolua_toboolean(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* function: IsValidBlock */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_IsValidBlock00 +static int tolua_AllToLua_IsValidBlock00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_BlockID = ((int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) IsValidBlock(a_BlockID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsValidBlock'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: IsValidItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_IsValidItem00 +static int tolua_AllToLua_IsValidItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_ItemID = ((int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) IsValidItem(a_ItemID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsValidItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: AddDirection */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_AddDirection00 +static int tolua_AllToLua_AddDirection00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isboolean(tolua_S,5,1,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_X = ((int) tolua_tonumber(tolua_S,1,0)); + unsigned char a_Y = ((unsigned char) tolua_tonumber(tolua_S,2,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); + char a_Direction = ((char) tolua_tonumber(tolua_S,4,0)); + bool a_bInverse = ((bool) tolua_toboolean(tolua_S,5,false)); + { + AddDirection(a_X,a_Y,a_Z,a_Direction,a_bInverse); + tolua_pushnumber(tolua_S,(lua_Number)a_X); + tolua_pushnumber(tolua_S,(lua_Number)a_Y); + tolua_pushnumber(tolua_S,(lua_Number)a_Z); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddDirection'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: ItemCategory::IsPickaxe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsPickaxe00 +static int tolua_AllToLua_ItemCategory_IsPickaxe00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) ItemCategory::IsPickaxe(a_ItemID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsPickaxe'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: ItemCategory::IsAxe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsAxe00 +static int tolua_AllToLua_ItemCategory_IsAxe00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) ItemCategory::IsAxe(a_ItemID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsAxe'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: ItemCategory::IsSword */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsSword00 +static int tolua_AllToLua_ItemCategory_IsSword00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) ItemCategory::IsSword(a_ItemID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsSword'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: ItemCategory::IsHoe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsHoe00 +static int tolua_AllToLua_ItemCategory_IsHoe00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) ItemCategory::IsHoe(a_ItemID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsHoe'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: ItemCategory::IsShovel */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsShovel00 +static int tolua_AllToLua_ItemCategory_IsShovel00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) ItemCategory::IsShovel(a_ItemID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsShovel'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: ItemCategory::IsTool */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsTool00 +static int tolua_AllToLua_ItemCategory_IsTool00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) ItemCategory::IsTool(a_ItemID); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsTool'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: GetTime */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_GetTime00 +static int tolua_AllToLua_GetTime00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnoobj(tolua_S,1,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + unsigned int tolua_ret = (unsigned int) GetTime(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetTime'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* function: GetChar */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_GetChar00 +static int tolua_AllToLua_GetChar00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_iscppstring(tolua_S,1,0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + std::string a_Str = ((std::string) tolua_tocppstring(tolua_S,1,0)); + unsigned int a_Idx = ((unsigned int) tolua_tonumber(tolua_S,2,0)); + { + std::string tolua_ret = (std::string) GetChar(a_Str,a_Idx); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)a_Str); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetChar'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: clear of class cStringMap */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cStringMap_clear00 +static int tolua_AllToLua_cStringMap_clear00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cStringMap",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cStringMap* self = (cStringMap*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'clear'", NULL); +#endif + { + self->clear(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'clear'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: size of class cStringMap */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cStringMap_size00 +static int tolua_AllToLua_cStringMap_size00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cStringMap",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cStringMap* self = (const cStringMap*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'size'", NULL); +#endif + { + unsigned int tolua_ret = (unsigned int) self->size(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'size'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: get of class cStringMap */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cStringMap_get00 +static int tolua_AllToLua_cStringMap_get00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cStringMap",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cStringMap* self = (cStringMap*) tolua_tousertype(tolua_S,1,0); + const std::string index = ((const std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'get'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->get(index); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)index); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'get'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Color of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Color +static int tolua_get_cChatColor_Color(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Color); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Delimiter of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Delimiter +static int tolua_get_cChatColor_Delimiter(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Delimiter); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Black of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Black +static int tolua_get_cChatColor_Black(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Black); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Navy of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Navy +static int tolua_get_cChatColor_Navy(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Navy); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Green of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Green +static int tolua_get_cChatColor_Green(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Green); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Blue of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Blue +static int tolua_get_cChatColor_Blue(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Blue); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Red of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Red +static int tolua_get_cChatColor_Red(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Red); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Purple of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Purple +static int tolua_get_cChatColor_Purple(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Purple); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Gold of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Gold +static int tolua_get_cChatColor_Gold(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Gold); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: LightGray of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightGray +static int tolua_get_cChatColor_LightGray(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightGray); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Gray of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Gray +static int tolua_get_cChatColor_Gray(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Gray); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: DarkPurple of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_DarkPurple +static int tolua_get_cChatColor_DarkPurple(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::DarkPurple); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: LightGreen of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightGreen +static int tolua_get_cChatColor_LightGreen(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightGreen); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: LightBlue of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightBlue +static int tolua_get_cChatColor_LightBlue(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightBlue); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Rose of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Rose +static int tolua_get_cChatColor_Rose(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Rose); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: LightPurple of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_LightPurple +static int tolua_get_cChatColor_LightPurple(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::LightPurple); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Yellow of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Yellow +static int tolua_get_cChatColor_Yellow(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Yellow); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: White of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_White +static int tolua_get_cChatColor_White(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::White); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Random of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Random +static int tolua_get_cChatColor_Random(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Random); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Bold of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Bold +static int tolua_get_cChatColor_Bold(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Bold); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Strikethrough of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Strikethrough +static int tolua_get_cChatColor_Strikethrough(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Strikethrough); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Underlined of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Underlined +static int tolua_get_cChatColor_Underlined(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Underlined); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Italic of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Italic +static int tolua_get_cChatColor_Italic(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Italic); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Plain of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_get_cChatColor_Plain +static int tolua_get_cChatColor_Plain(lua_State* tolua_S) +{ + tolua_pushcppstring(tolua_S,(const char*)cChatColor::Plain); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: MakeColor of class cChatColor */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cChatColor_MakeColor00 +static int tolua_AllToLua_cChatColor_MakeColor00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cChatColor",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + char a_Color = ((char) tolua_tonumber(tolua_S,2,0)); + { + const std::string tolua_ret = (const std::string) cChatColor::MakeColor(a_Color); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'MakeColor'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPlayer of class cClientHandle */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetPlayer00 +static int tolua_AllToLua_cClientHandle_GetPlayer00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPlayer'", NULL); +#endif + { + cPlayer* tolua_ret = (cPlayer*) self->GetPlayer(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlayer"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPlayer'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Kick of class cClientHandle */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_Kick00 +static int tolua_AllToLua_cClientHandle_Kick00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0); + const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Kick'", NULL); +#endif + { + self->Kick(a_Reason); + tolua_pushcppstring(tolua_S,(const char*)a_Reason); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Kick'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetUsername of class cClientHandle */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetUsername00 +static int tolua_AllToLua_cClientHandle_GetUsername00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cClientHandle",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cClientHandle* self = (const cClientHandle*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetUsername'", NULL); +#endif + { + const AString tolua_ret = (const AString) self->GetUsername(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetUsername'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPing of class cClientHandle */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetPing00 +static int tolua_AllToLua_cClientHandle_GetPing00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cClientHandle",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cClientHandle* self = (const cClientHandle*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPing'", NULL); +#endif + { + short tolua_ret = (short) self->GetPing(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPing'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetViewDistance of class cClientHandle */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_SetViewDistance00 +static int tolua_AllToLua_cClientHandle_SetViewDistance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0); + int a_ViewDistance = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetViewDistance'", NULL); +#endif + { + self->SetViewDistance(a_ViewDistance); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetViewDistance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetViewDistance of class cClientHandle */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetViewDistance00 +static int tolua_AllToLua_cClientHandle_GetViewDistance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cClientHandle",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cClientHandle* self = (cClientHandle*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetViewDistance'", NULL); +#endif + { + int tolua_ret = (int) self->GetViewDistance(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetViewDistance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetUniqueID of class cClientHandle */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cClientHandle_GetUniqueID00 +static int tolua_AllToLua_cClientHandle_GetUniqueID00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cClientHandle",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cClientHandle* self = (const cClientHandle*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetUniqueID'", NULL); +#endif + { + int tolua_ret = (int) self->GetUniqueID(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetUniqueID'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_delete00 +static int tolua_AllToLua_cEntity_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Initialize of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_Initialize00 +static int tolua_AllToLua_cEntity_Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); +#endif + { + self->Initialize(a_World); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetEntityType of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetEntityType00 +static int tolua_AllToLua_cEntity_GetEntityType00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEntityType'", NULL); +#endif + { + unsigned int tolua_ret = (unsigned int) self->GetEntityType(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetEntityType'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsA of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_IsA00 +static int tolua_AllToLua_cEntity_IsA00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + const char* a_EntityType = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsA'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsA(a_EntityType); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsA'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetClass of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetClass00 +static int tolua_AllToLua_cEntity_GetClass00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetClass'", NULL); +#endif + { + const char* tolua_ret = (const char*) self->GetClass(); + tolua_pushstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetClass'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetWorld of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetWorld00 +static int tolua_AllToLua_cEntity_GetWorld00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWorld'", NULL); +#endif + { + cWorld* tolua_ret = (cWorld*) self->GetWorld(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWorld'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPosition of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosition00 +static int tolua_AllToLua_cEntity_GetPosition00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosition'", NULL); +#endif + { + const Vector3d& tolua_ret = (const Vector3d&) self->GetPosition(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const Vector3d"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPosition'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPosX of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosX00 +static int tolua_AllToLua_cEntity_GetPosX00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosX'", NULL); +#endif + { + const double tolua_ret = (const double) self->GetPosX(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPosX'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPosY of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosY00 +static int tolua_AllToLua_cEntity_GetPosY00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosY'", NULL); +#endif + { + const double tolua_ret = (const double) self->GetPosY(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPosY'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPosZ of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosZ00 +static int tolua_AllToLua_cEntity_GetPosZ00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPosZ'", NULL); +#endif + { + const double tolua_ret = (const double) self->GetPosZ(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPosZ'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetRot of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetRot00 +static int tolua_AllToLua_cEntity_GetRot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetRot'", NULL); +#endif + { + const Vector3f& tolua_ret = (const Vector3f&) self->GetRot(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const Vector3f"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetRot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetRotation of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetRotation00 +static int tolua_AllToLua_cEntity_GetRotation00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetRotation'", NULL); +#endif + { + float tolua_ret = (float) self->GetRotation(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetRotation'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPitch of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPitch00 +static int tolua_AllToLua_cEntity_GetPitch00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPitch'", NULL); +#endif + { + float tolua_ret = (float) self->GetPitch(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPitch'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetRoll of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetRoll00 +static int tolua_AllToLua_cEntity_GetRoll00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetRoll'", NULL); +#endif + { + float tolua_ret = (float) self->GetRoll(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetRoll'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetLookVector of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetLookVector00 +static int tolua_AllToLua_cEntity_GetLookVector00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLookVector'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->GetLookVector(); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetLookVector'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetChunkX of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkX00 +static int tolua_AllToLua_cEntity_GetChunkX00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetChunkX'", NULL); +#endif + { + int tolua_ret = (int) self->GetChunkX(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetChunkX'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetChunkY of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkY00 +static int tolua_AllToLua_cEntity_GetChunkY00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetChunkY'", NULL); +#endif + { + int tolua_ret = (int) self->GetChunkY(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetChunkY'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetChunkZ of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkZ00 +static int tolua_AllToLua_cEntity_GetChunkZ00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetChunkZ'", NULL); +#endif + { + int tolua_ret = (int) self->GetChunkZ(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetChunkZ'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPosX of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosX00 +static int tolua_AllToLua_cEntity_SetPosX00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosX'", NULL); +#endif + { + self->SetPosX(a_PosX); + tolua_pushnumber(tolua_S,(lua_Number)a_PosX); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetPosX'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPosY of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosY00 +static int tolua_AllToLua_cEntity_SetPosY00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + const double a_PosY = ((const double) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosY'", NULL); +#endif + { + self->SetPosY(a_PosY); + tolua_pushnumber(tolua_S,(lua_Number)a_PosY); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetPosY'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPosZ of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosZ00 +static int tolua_AllToLua_cEntity_SetPosZ00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + const double a_PosZ = ((const double) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosZ'", NULL); +#endif + { + self->SetPosZ(a_PosZ); + tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetPosZ'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPosition of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosition00 +static int tolua_AllToLua_cEntity_SetPosition00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); + const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); + const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosition'", NULL); +#endif + { + self->SetPosition(a_PosX,a_PosY,a_PosZ); + tolua_pushnumber(tolua_S,(lua_Number)a_PosX); + tolua_pushnumber(tolua_S,(lua_Number)a_PosY); + tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetPosition'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPosition of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosition01 +static int tolua_AllToLua_cEntity_SetPosition01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_Pos = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPosition'", NULL); +#endif + { + self->SetPosition(*a_Pos); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cEntity_SetPosition00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetRot of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetRot00 +static int tolua_AllToLua_cEntity_SetRot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + const Vector3f* a_Rot = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRot'", NULL); +#endif + { + self->SetRot(*a_Rot); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetRot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetRotation of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetRotation00 +static int tolua_AllToLua_cEntity_SetRotation00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + float a_Rotation = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRotation'", NULL); +#endif + { + self->SetRotation(a_Rotation); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetRotation'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPitch of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPitch00 +static int tolua_AllToLua_cEntity_SetPitch00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + float a_Pitch = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPitch'", NULL); +#endif + { + self->SetPitch(a_Pitch); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetPitch'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetRoll of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetRoll00 +static int tolua_AllToLua_cEntity_SetRoll00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + float a_Roll = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRoll'", NULL); +#endif + { + self->SetRoll(a_Roll); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetRoll'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetUniqueID of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetUniqueID00 +static int tolua_AllToLua_cEntity_GetUniqueID00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetUniqueID'", NULL); +#endif + { + int tolua_ret = (int) self->GetUniqueID(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetUniqueID'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsDestroyed of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_IsDestroyed00 +static int tolua_AllToLua_cEntity_IsDestroyed00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsDestroyed'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsDestroyed(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsDestroyed'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Destroy of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_Destroy00 +static int tolua_AllToLua_cEntity_Destroy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Destroy'", NULL); +#endif + { + self->Destroy(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Destroy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Tick of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_Tick00 +static int tolua_AllToLua_cEntity_Tick00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Tick'", NULL); +#endif + { + self->Tick(a_Dt); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Tick'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SpawnOn of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SpawnOn00 +static int tolua_AllToLua_cEntity_SpawnOn00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cClientHandle",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + cClientHandle* a_Client = ((cClientHandle*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SpawnOn'", NULL); +#endif + { + self->SpawnOn(a_Client); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SpawnOn'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cEntity : public cEntity, public ToluaBase { +public: + void Initialize( cWorld* a_World) { + if (push_method("Initialize", tolua_AllToLua_cEntity_Initialize00)) { + tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cEntity:: Initialize(a_World); + }; + }; + unsigned int GetEntityType( void ) { + if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) { + ToluaBase::dbcall(lua_state, 1, 1); + unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return (unsigned int ) cEntity:: GetEntityType(); + }; + }; + bool IsA( const char* a_EntityType) { + if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) { + tolua_pushstring(lua_state, (const char*)a_EntityType); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cEntity:: IsA(a_EntityType); + }; + }; + const char* GetClass( void ) { + if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) { + ToluaBase::dbcall(lua_state, 1, 1); + const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( const char* ) cEntity:: GetClass(); + }; + }; + void Tick( float a_Dt) { + if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Dt); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + if (lua_state) + LOG("pure-virtual method cEntity::Tick not implemented."); + else { + LOG("pure-virtual method cEntity::Tick called with no lua_state. Aborting"); + ::abort(); + }; + return ( void )0; + }; + }; + + void cEntity__Initialize( cWorld* a_World) { + return ( void )cEntity::Initialize(a_World); + }; + unsigned int cEntity__GetEntityType( void ) { + return (unsigned int )cEntity::GetEntityType(); + }; + bool cEntity__IsA( const char* a_EntityType) { + return ( bool )cEntity::IsA(a_EntityType); + }; + const char* cEntity__GetClass( void ) { + return ( const char* )cEntity::GetClass(); + }; + Lua__cEntity( const double& a_X, const double& a_Y, const double& a_Z): cEntity(a_X,a_Y,a_Z){}; +}; + +/* method: tolua__set_instance of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_tolua__set_instance00 +static int tolua_AllToLua_Lua__cEntity_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cEntity__Initialize of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__Initialize00 +static int tolua_AllToLua_Lua__cEntity_cEntity__Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__Initialize'", NULL); +#endif + { + self->cEntity__Initialize(a_World); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cEntity__Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cEntity__GetEntityType of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__GetEntityType00 +static int tolua_AllToLua_Lua__cEntity_cEntity__GetEntityType00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__GetEntityType'", NULL); +#endif + { + unsigned int tolua_ret = (unsigned int) self->cEntity__GetEntityType(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cEntity__GetEntityType'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cEntity__IsA of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__IsA00 +static int tolua_AllToLua_Lua__cEntity_cEntity__IsA00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); + const char* a_EntityType = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__IsA'", NULL); +#endif + { + bool tolua_ret = (bool) self->cEntity__IsA(a_EntityType); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cEntity__IsA'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cEntity__GetClass of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_cEntity__GetClass00 +static int tolua_AllToLua_Lua__cEntity_cEntity__GetClass00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cEntity__GetClass'", NULL); +#endif + { + const char* tolua_ret = (const char*) self->cEntity__GetClass(); + tolua_pushstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cEntity__GetClass'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_new00 +static int tolua_AllToLua_Lua__cEntity_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const double a_X = ((const double) tolua_tonumber(tolua_S,2,0)); + const double a_Y = ((const double) tolua_tonumber(tolua_S,3,0)); + const double a_Z = ((const double) tolua_tonumber(tolua_S,4,0)); + { + Lua__cEntity* tolua_ret = (Lua__cEntity*) Mtolua_new((Lua__cEntity)(a_X,a_Y,a_Z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cEntity"); + tolua_pushnumber(tolua_S,(lua_Number)a_X); + tolua_pushnumber(tolua_S,(lua_Number)a_Y); + tolua_pushnumber(tolua_S,(lua_Number)a_Z); + } + } + return 4; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_new00_local +static int tolua_AllToLua_Lua__cEntity_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const double a_X = ((const double) tolua_tonumber(tolua_S,2,0)); + const double a_Y = ((const double) tolua_tonumber(tolua_S,3,0)); + const double a_Z = ((const double) tolua_tonumber(tolua_S,4,0)); + { + Lua__cEntity* tolua_ret = (Lua__cEntity*) Mtolua_new((Lua__cEntity)(a_X,a_Y,a_Z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cEntity"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + tolua_pushnumber(tolua_S,(lua_Number)a_X); + tolua_pushnumber(tolua_S,(lua_Number)a_Y); + tolua_pushnumber(tolua_S,(lua_Number)a_Z); + } + } + return 4; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class Lua__cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cEntity_delete00 +static int tolua_AllToLua_Lua__cEntity_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_Lua__cEntity (lua_State* tolua_S) +{ + Lua__cEntity* self = (Lua__cEntity*) tolua_tousertype(tolua_S,1,0); + delete self; + return 0; +} +#endif + +/* get function: Damage of class TakeDamageInfo */ +#ifndef TOLUA_DISABLE_tolua_get_TakeDamageInfo_Damage +static int tolua_get_TakeDamageInfo_Damage(lua_State* tolua_S) +{ + TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Damage'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->Damage); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Damage of class TakeDamageInfo */ +#ifndef TOLUA_DISABLE_tolua_set_TakeDamageInfo_Damage +static int tolua_set_TakeDamageInfo_Damage(lua_State* tolua_S) +{ + TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Damage'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Damage = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Instigator of class TakeDamageInfo */ +#ifndef TOLUA_DISABLE_tolua_get_TakeDamageInfo_Instigator_ptr +static int tolua_get_TakeDamageInfo_Instigator_ptr(lua_State* tolua_S) +{ + TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Instigator'",NULL); +#endif + tolua_pushusertype(tolua_S,(void*)self->Instigator,"cEntity"); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Instigator of class TakeDamageInfo */ +#ifndef TOLUA_DISABLE_tolua_set_TakeDamageInfo_Instigator_ptr +static int tolua_set_TakeDamageInfo_Instigator_ptr(lua_State* tolua_S) +{ + TakeDamageInfo* self = (TakeDamageInfo*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Instigator'",NULL); + if (!tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Instigator = ((cEntity*) tolua_tousertype(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: TeleportToEntity of class cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_TeleportToEntity00 +static int tolua_AllToLua_cPawn_TeleportToEntity00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); + cEntity* a_Entity = ((cEntity*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TeleportToEntity'", NULL); +#endif + { + self->TeleportToEntity(a_Entity); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'TeleportToEntity'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: TeleportTo of class cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_TeleportTo00 +static int tolua_AllToLua_cPawn_TeleportTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); + const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); + const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); + const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TeleportTo'", NULL); +#endif + { + self->TeleportTo(a_PosX,a_PosY,a_PosZ); + tolua_pushnumber(tolua_S,(lua_Number)a_PosX); + tolua_pushnumber(tolua_S,(lua_Number)a_PosY); + tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'TeleportTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Heal of class cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_Heal00 +static int tolua_AllToLua_cPawn_Heal00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); + int a_Health = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Heal'", NULL); +#endif + { + self->Heal(a_Health); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Heal'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: TakeDamage of class cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_TakeDamage00 +static int tolua_AllToLua_cPawn_TakeDamage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); + int a_Damage = ((int) tolua_tonumber(tolua_S,2,0)); + cEntity* a_Instigator = ((cEntity*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TakeDamage'", NULL); +#endif + { + self->TakeDamage(a_Damage,a_Instigator); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'TakeDamage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: KilledBy of class cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_KilledBy00 +static int tolua_AllToLua_cPawn_KilledBy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); + cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KilledBy'", NULL); +#endif + { + self->KilledBy(a_Killer); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'KilledBy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetHealth of class cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPawn_GetHealth00 +static int tolua_AllToLua_cPawn_GetHealth00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPawn",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPawn* self = (cPawn*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHealth'", NULL); +#endif + { + int tolua_ret = (int) self->GetHealth(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetHealth'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cPawn : public cPawn, public ToluaBase { +public: + void TeleportToEntity( cEntity* a_Entity) { + if (push_method("TeleportToEntity", tolua_AllToLua_cPawn_TeleportToEntity00)) { + tolua_pushusertype(lua_state, (void*)a_Entity, "cEntity"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPawn:: TeleportToEntity(a_Entity); + }; + }; + void TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) { + if (push_method("TeleportTo", tolua_AllToLua_cPawn_TeleportTo00)) { + tolua_pushnumber(lua_state, (lua_Number)a_PosX); + tolua_pushnumber(lua_state, (lua_Number)a_PosY); + tolua_pushnumber(lua_state, (lua_Number)a_PosZ); + ToluaBase::dbcall(lua_state, 4, 0); + } else { + return ( void ) cPawn:: TeleportTo(a_PosX,a_PosY,a_PosZ); + }; + }; + void TakeDamage( int a_Damage, cEntity* a_Instigator) { + if (push_method("TakeDamage", tolua_AllToLua_cPawn_TakeDamage00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Damage); + tolua_pushusertype(lua_state, (void*)a_Instigator, "cEntity"); + ToluaBase::dbcall(lua_state, 3, 0); + } else { + return ( void ) cPawn:: TakeDamage(a_Damage,a_Instigator); + }; + }; + void KilledBy( cEntity* a_Killer) { + if (push_method("KilledBy", tolua_AllToLua_cPawn_KilledBy00)) { + tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPawn:: KilledBy(a_Killer); + }; + }; + void Initialize( cWorld* a_World) { + if (push_method("Initialize", tolua_AllToLua_cEntity_Initialize00)) { + tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPawn:: Initialize(a_World); + }; + }; + unsigned int GetEntityType( void ) { + if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) { + ToluaBase::dbcall(lua_state, 1, 1); + unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return (unsigned int ) cPawn:: GetEntityType(); + }; + }; + bool IsA( const char* a_EntityType) { + if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) { + tolua_pushstring(lua_state, (const char*)a_EntityType); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPawn:: IsA(a_EntityType); + }; + }; + const char* GetClass( void ) { + if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) { + ToluaBase::dbcall(lua_state, 1, 1); + const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( const char* ) cPawn:: GetClass(); + }; + }; + void Tick( float a_Dt) { + if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Dt); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + if (lua_state) + LOG("pure-virtual method cPawn::Tick not implemented."); + else { + LOG("pure-virtual method cPawn::Tick called with no lua_state. Aborting"); + ::abort(); + }; + return ( void )0; + }; + }; + + void cPawn__TeleportToEntity( cEntity* a_Entity) { + return ( void )cPawn::TeleportToEntity(a_Entity); + }; + void cPawn__TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) { + return ( void )cPawn::TeleportTo(a_PosX,a_PosY,a_PosZ); + }; + void cPawn__TakeDamage( int a_Damage, cEntity* a_Instigator) { + return ( void )cPawn::TakeDamage(a_Damage,a_Instigator); + }; + void cPawn__KilledBy( cEntity* a_Killer) { + return ( void )cPawn::KilledBy(a_Killer); + }; + void cPawn__Initialize( cWorld* a_World) { + return ( void )cPawn::Initialize(a_World); + }; + unsigned int cPawn__GetEntityType( void ) { + return (unsigned int )cPawn::GetEntityType(); + }; + bool cPawn__IsA( const char* a_EntityType) { + return ( bool )cPawn::IsA(a_EntityType); + }; + const char* cPawn__GetClass( void ) { + return ( const char* )cPawn::GetClass(); + }; +}; + +/* method: tolua__set_instance of class Lua__cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_tolua__set_instance00 +static int tolua_AllToLua_Lua__cPawn_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPawn__TeleportToEntity of class Lua__cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__TeleportToEntity00 +static int tolua_AllToLua_Lua__cPawn_cPawn__TeleportToEntity00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); + cEntity* a_Entity = ((cEntity*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__TeleportToEntity'", NULL); +#endif + { + self->cPawn__TeleportToEntity(a_Entity); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPawn__TeleportToEntity'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPawn__TeleportTo of class Lua__cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__TeleportTo00 +static int tolua_AllToLua_Lua__cPawn_cPawn__TeleportTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); + const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); + const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); + const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__TeleportTo'", NULL); +#endif + { + self->cPawn__TeleportTo(a_PosX,a_PosY,a_PosZ); + tolua_pushnumber(tolua_S,(lua_Number)a_PosX); + tolua_pushnumber(tolua_S,(lua_Number)a_PosY); + tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPawn__TeleportTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPawn__TakeDamage of class Lua__cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__TakeDamage00 +static int tolua_AllToLua_Lua__cPawn_cPawn__TakeDamage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); + int a_Damage = ((int) tolua_tonumber(tolua_S,2,0)); + cEntity* a_Instigator = ((cEntity*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__TakeDamage'", NULL); +#endif + { + self->cPawn__TakeDamage(a_Damage,a_Instigator); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPawn__TakeDamage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPawn__KilledBy of class Lua__cPawn */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPawn_cPawn__KilledBy00 +static int tolua_AllToLua_Lua__cPawn_cPawn__KilledBy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPawn* self = (Lua__cPawn*) tolua_tousertype(tolua_S,1,0); + cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPawn__KilledBy'", NULL); +#endif + { + self->cPawn__KilledBy(a_Killer); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPawn__KilledBy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Initialize of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Initialize00 +static int tolua_AllToLua_cPlayer_Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); +#endif + { + self->Initialize(a_World); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetEyeHeight of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetEyeHeight00 +static int tolua_AllToLua_cPlayer_GetEyeHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEyeHeight'", NULL); +#endif + { + double tolua_ret = (double) self->GetEyeHeight(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetEyeHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetEyePosition of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetEyePosition00 +static int tolua_AllToLua_cPlayer_GetEyePosition00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEyePosition'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->GetEyePosition(); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetEyePosition'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetFlying of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetFlying00 +static int tolua_AllToLua_cPlayer_GetFlying00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFlying'", NULL); +#endif + { + bool tolua_ret = (bool) self->GetFlying(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetFlying'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetStance of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetStance00 +static int tolua_AllToLua_cPlayer_GetStance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStance'", NULL); +#endif + { + const double tolua_ret = (const double) self->GetStance(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetStance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetInventory of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetInventory00 +static int tolua_AllToLua_cPlayer_GetInventory00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetInventory'", NULL); +#endif + { + cInventory& tolua_ret = (cInventory&) self->GetInventory(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cInventory"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetInventory'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: TeleportTo of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_TeleportTo00 +static int tolua_AllToLua_cPlayer_TeleportTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); + const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); + const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TeleportTo'", NULL); +#endif + { + self->TeleportTo(a_PosX,a_PosY,a_PosZ); + tolua_pushnumber(tolua_S,(lua_Number)a_PosX); + tolua_pushnumber(tolua_S,(lua_Number)a_PosY); + tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'TeleportTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetGameMode of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetGameMode00 +static int tolua_AllToLua_cPlayer_GetGameMode00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGameMode'", NULL); +#endif + { + eGameMode tolua_ret = (eGameMode) self->GetGameMode(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetGameMode'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetIP of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetIP00 +static int tolua_AllToLua_cPlayer_GetIP00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIP'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->GetIP(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetIP'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetLastBlockActionTime of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetLastBlockActionTime00 +static int tolua_AllToLua_cPlayer_GetLastBlockActionTime00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLastBlockActionTime'", NULL); +#endif + { + float tolua_ret = (float) self->GetLastBlockActionTime(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetLastBlockActionTime'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetLastBlockActionCnt of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetLastBlockActionCnt00 +static int tolua_AllToLua_cPlayer_GetLastBlockActionCnt00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLastBlockActionCnt'", NULL); +#endif + { + int tolua_ret = (int) self->GetLastBlockActionCnt(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetLastBlockActionCnt'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetLastBlockActionCnt of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetLastBlockActionCnt00 +static int tolua_AllToLua_cPlayer_SetLastBlockActionCnt00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + int tolua_var_1 = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetLastBlockActionCnt'", NULL); +#endif + { + self->SetLastBlockActionCnt(tolua_var_1); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetLastBlockActionCnt'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetLastBlockActionTime of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetLastBlockActionTime00 +static int tolua_AllToLua_cPlayer_SetLastBlockActionTime00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetLastBlockActionTime'", NULL); +#endif + { + self->SetLastBlockActionTime(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetLastBlockActionTime'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetGameMode of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetGameMode00 +static int tolua_AllToLua_cPlayer_SetGameMode00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + eGameMode a_GameMode = ((eGameMode) (int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetGameMode'", NULL); +#endif + { + self->SetGameMode(a_GameMode); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetGameMode'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: MoveTo of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_MoveTo00 +static int tolua_AllToLua_cPlayer_MoveTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_NewPos = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'MoveTo'", NULL); +#endif + { + self->MoveTo(*a_NewPos); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'MoveTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetClientHandle of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetClientHandle00 +static int tolua_AllToLua_cPlayer_GetClientHandle00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetClientHandle'", NULL); +#endif + { + cClientHandle* tolua_ret = (cClientHandle*) self->GetClientHandle(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cClientHandle"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetClientHandle'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SendMessage of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SendMessage00 +static int tolua_AllToLua_cPlayer_SendMessage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const char* a_Message = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL); +#endif + { + self->SendMessage(a_Message); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetName of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetName00 +static int tolua_AllToLua_cPlayer_GetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); +#endif + { + const AString tolua_ret = (const AString) self->GetName(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetName of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetName00 +static int tolua_AllToLua_cPlayer_SetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const AString a_Name = ((const AString) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL); +#endif + { + self->SetName(a_Name); + tolua_pushcppstring(tolua_S,(const char*)a_Name); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddToGroup of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_AddToGroup00 +static int tolua_AllToLua_cPlayer_AddToGroup00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const char* a_GroupName = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddToGroup'", NULL); +#endif + { + self->AddToGroup(a_GroupName); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddToGroup'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CanUseCommand of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_CanUseCommand00 +static int tolua_AllToLua_cPlayer_CanUseCommand00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const char* a_Command = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CanUseCommand'", NULL); +#endif + { + bool tolua_ret = (bool) self->CanUseCommand(a_Command); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CanUseCommand'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HasPermission of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_HasPermission00 +static int tolua_AllToLua_cPlayer_HasPermission00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const char* a_Permission = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasPermission'", NULL); +#endif + { + bool tolua_ret = (bool) self->HasPermission(a_Permission); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'HasPermission'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsInGroup of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsInGroup00 +static int tolua_AllToLua_cPlayer_IsInGroup00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const char* a_Group = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInGroup'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsInGroup(a_Group); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsInGroup'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetColor of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetColor00 +static int tolua_AllToLua_cPlayer_GetColor00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetColor'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetColor(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetColor'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: TossItem of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_TossItem00 +static int tolua_AllToLua_cPlayer_TossItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,1,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + bool a_bDraggingItem = ((bool) tolua_toboolean(tolua_S,2,0)); + int a_Amount = ((int) tolua_tonumber(tolua_S,3,1)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TossItem'", NULL); +#endif + { + self->TossItem(a_bDraggingItem,a_Amount); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'TossItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Heal of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Heal00 +static int tolua_AllToLua_cPlayer_Heal00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + int a_Health = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Heal'", NULL); +#endif + { + self->Heal(a_Health); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Heal'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: TakeDamage of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_TakeDamage00 +static int tolua_AllToLua_cPlayer_TakeDamage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + int a_Damage = ((int) tolua_tonumber(tolua_S,2,0)); + cEntity* a_Instigator = ((cEntity*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'TakeDamage'", NULL); +#endif + { + self->TakeDamage(a_Damage,a_Instigator); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'TakeDamage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: KilledBy of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_KilledBy00 +static int tolua_AllToLua_cPlayer_KilledBy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'KilledBy'", NULL); +#endif + { + self->KilledBy(a_Killer); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'KilledBy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Respawn of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Respawn00 +static int tolua_AllToLua_cPlayer_Respawn00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Respawn'", NULL); +#endif + { + self->Respawn(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Respawn'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetVisible of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetVisible00 +static int tolua_AllToLua_cPlayer_SetVisible00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + bool a_bVisible = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetVisible'", NULL); +#endif + { + self->SetVisible(a_bVisible); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetVisible'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsVisible of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsVisible00 +static int tolua_AllToLua_cPlayer_IsVisible00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsVisible'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsVisible(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsVisible'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: MoveToWorld of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_MoveToWorld00 +static int tolua_AllToLua_cPlayer_MoveToWorld00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const char* a_WorldName = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'MoveToWorld'", NULL); +#endif + { + bool tolua_ret = (bool) self->MoveToWorld(a_WorldName); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'MoveToWorld'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: LoadPermissionsFromDisk of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00 +static int tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'LoadPermissionsFromDisk'", NULL); +#endif + { + self->LoadPermissionsFromDisk(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'LoadPermissionsFromDisk'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cPlayer : public cPlayer, public ToluaBase { +public: + void Initialize( cWorld* a_World) { + if (push_method("Initialize", tolua_AllToLua_cPlayer_Initialize00)) { + tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlayer:: Initialize(a_World); + }; + }; + void TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) { + if (push_method("TeleportTo", tolua_AllToLua_cPlayer_TeleportTo00)) { + tolua_pushnumber(lua_state, (lua_Number)a_PosX); + tolua_pushnumber(lua_state, (lua_Number)a_PosY); + tolua_pushnumber(lua_state, (lua_Number)a_PosZ); + ToluaBase::dbcall(lua_state, 4, 0); + } else { + return ( void ) cPlayer:: TeleportTo(a_PosX,a_PosY,a_PosZ); + }; + }; + void MoveTo( const Vector3d& a_NewPos) { + if (push_method("MoveTo", tolua_AllToLua_cPlayer_MoveTo00)) { + tolua_pushusertype(lua_state, (void*)&a_NewPos, "const Vector3d"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlayer:: MoveTo(a_NewPos); + }; + }; + void TeleportToEntity( cEntity* a_Entity) { + if (push_method("TeleportToEntity", tolua_AllToLua_cPawn_TeleportToEntity00)) { + tolua_pushusertype(lua_state, (void*)a_Entity, "cEntity"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlayer:: TeleportToEntity(a_Entity); + }; + }; + void TakeDamage( int a_Damage, cEntity* a_Instigator) { + if (push_method("TakeDamage", tolua_AllToLua_cPawn_TakeDamage00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Damage); + tolua_pushusertype(lua_state, (void*)a_Instigator, "cEntity"); + ToluaBase::dbcall(lua_state, 3, 0); + } else { + return ( void ) cPlayer:: TakeDamage(a_Damage,a_Instigator); + }; + }; + void KilledBy( cEntity* a_Killer) { + if (push_method("KilledBy", tolua_AllToLua_cPawn_KilledBy00)) { + tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlayer:: KilledBy(a_Killer); + }; + }; + unsigned int GetEntityType( void ) { + if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) { + ToluaBase::dbcall(lua_state, 1, 1); + unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return (unsigned int ) cPlayer:: GetEntityType(); + }; + }; + bool IsA( const char* a_EntityType) { + if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) { + tolua_pushstring(lua_state, (const char*)a_EntityType); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlayer:: IsA(a_EntityType); + }; + }; + const char* GetClass( void ) { + if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) { + ToluaBase::dbcall(lua_state, 1, 1); + const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( const char* ) cPlayer:: GetClass(); + }; + }; + void Tick( float a_Dt) { + if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Dt); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + if (lua_state) + LOG("pure-virtual method cPlayer::Tick not implemented."); + else { + LOG("pure-virtual method cPlayer::Tick called with no lua_state. Aborting"); + ::abort(); + }; + return ( void )0; + }; + }; + + void cPlayer__Initialize( cWorld* a_World) { + return ( void )cPlayer::Initialize(a_World); + }; + void cPlayer__TeleportTo( const double& a_PosX, const double& a_PosY, const double& a_PosZ) { + return ( void )cPlayer::TeleportTo(a_PosX,a_PosY,a_PosZ); + }; + void cPlayer__MoveTo( const Vector3d& a_NewPos) { + return ( void )cPlayer::MoveTo(a_NewPos); + }; + void cPlayer__TeleportToEntity( cEntity* a_Entity) { + return ( void )cPlayer::TeleportToEntity(a_Entity); + }; + void cPlayer__TakeDamage( int a_Damage, cEntity* a_Instigator) { + return ( void )cPlayer::TakeDamage(a_Damage,a_Instigator); + }; + void cPlayer__KilledBy( cEntity* a_Killer) { + return ( void )cPlayer::KilledBy(a_Killer); + }; + unsigned int cPlayer__GetEntityType( void ) { + return (unsigned int )cPlayer::GetEntityType(); + }; + bool cPlayer__IsA( const char* a_EntityType) { + return ( bool )cPlayer::IsA(a_EntityType); + }; + const char* cPlayer__GetClass( void ) { + return ( const char* )cPlayer::GetClass(); + }; +}; + +/* method: tolua__set_instance of class Lua__cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_tolua__set_instance00 +static int tolua_AllToLua_Lua__cPlayer_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlayer__Initialize of class Lua__cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00 +static int tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0); + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlayer__Initialize'", NULL); +#endif + { + self->cPlayer__Initialize(a_World); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlayer__Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlayer__TeleportTo of class Lua__cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_cPlayer__TeleportTo00 +static int tolua_AllToLua_Lua__cPlayer_cPlayer__TeleportTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0); + const double a_PosX = ((const double) tolua_tonumber(tolua_S,2,0)); + const double a_PosY = ((const double) tolua_tonumber(tolua_S,3,0)); + const double a_PosZ = ((const double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlayer__TeleportTo'", NULL); +#endif + { + self->cPlayer__TeleportTo(a_PosX,a_PosY,a_PosZ); + tolua_pushnumber(tolua_S,(lua_Number)a_PosX); + tolua_pushnumber(tolua_S,(lua_Number)a_PosY); + tolua_pushnumber(tolua_S,(lua_Number)a_PosZ); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlayer__TeleportTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlayer__MoveTo of class Lua__cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00 +static int tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_NewPos = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlayer__MoveTo'", NULL); +#endif + { + self->cPlayer__MoveTo(*a_NewPos); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlayer__MoveTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPluginManager of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetPluginManager00 +static int tolua_AllToLua_cPluginManager_GetPluginManager00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cPluginManager",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + cPluginManager* tolua_ret = (cPluginManager*) cPluginManager::GetPluginManager(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPluginManager"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPluginManager'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPlugin of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetPlugin00 +static int tolua_AllToLua_cPluginManager_GetPlugin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPluginManager",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPluginManager* self = (const cPluginManager*) tolua_tousertype(tolua_S,1,0); + const char* a_Plugin = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPlugin'", NULL); +#endif + { + cPlugin* tolua_ret = (cPlugin*) self->GetPlugin(a_Plugin); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlugin"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPlugin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ReloadPlugins of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_ReloadPlugins00 +static int tolua_AllToLua_cPluginManager_ReloadPlugins00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ReloadPlugins'", NULL); +#endif + { + self->ReloadPlugins(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ReloadPlugins'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddPlugin of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_AddPlugin00 +static int tolua_AllToLua_cPluginManager_AddPlugin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); + lua_State* a_LuaState = tolua_S; + cPlugin* a_Plugin = ((cPlugin*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddPlugin'", NULL); +#endif + { + bool tolua_ret = (bool) self->AddPlugin(a_LuaState,a_Plugin); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddPlugin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddHook of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_AddHook00 +static int tolua_AllToLua_cPluginManager_AddHook00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlugin",0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); + cPlugin* a_Plugin = ((cPlugin*) tolua_tousertype(tolua_S,2,0)); + cPluginManager::PluginHook a_Hook = ((cPluginManager::PluginHook) (int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddHook'", NULL); +#endif + { + self->AddHook(a_Plugin,a_Hook); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddHook'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetNumPlugins of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetNumPlugins00 +static int tolua_AllToLua_cPluginManager_GetNumPlugins00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPluginManager",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPluginManager* self = (const cPluginManager*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumPlugins'", NULL); +#endif + { + unsigned int tolua_ret = (unsigned int) self->GetNumPlugins(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetNumPlugins'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: RemovePlugin of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_RemovePlugin00 +static int tolua_AllToLua_cPluginManager_RemovePlugin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlugin",0,&tolua_err) || + !tolua_isboolean(tolua_S,3,1,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); + cPlugin* a_Plugin = ((cPlugin*) tolua_tousertype(tolua_S,2,0)); + bool a_bDelete = ((bool) tolua_toboolean(tolua_S,3,false)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RemovePlugin'", NULL); +#endif + { + self->RemovePlugin(a_Plugin,a_bDelete); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'RemovePlugin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: RemoveLuaPlugin of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_RemoveLuaPlugin00 +static int tolua_AllToLua_cPluginManager_RemoveLuaPlugin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); + std::string a_FileName = ((std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RemoveLuaPlugin'", NULL); +#endif + { + self->RemoveLuaPlugin(a_FileName); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'RemoveLuaPlugin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetLuaPlugin of class cPluginManager */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetLuaPlugin00 +static int tolua_AllToLua_cPluginManager_GetLuaPlugin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); + lua_State* a_State = tolua_S; +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLuaPlugin'", NULL); +#endif + { + cPlugin_Lua* tolua_ret = (cPlugin_Lua*) self->GetLuaPlugin(a_State); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlugin_Lua"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetLuaPlugin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_delete00 +static int tolua_AllToLua_cPlugin_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnDisable of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnDisable00 +static int tolua_AllToLua_cPlugin_OnDisable00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisable'", NULL); +#endif + { + self->OnDisable(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnDisable'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Initialize of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_Initialize00 +static int tolua_AllToLua_cPlugin_Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); +#endif + { + bool tolua_ret = (bool) self->Initialize(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Tick of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_Tick00 +static int tolua_AllToLua_cPlugin_Tick00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Tick'", NULL); +#endif + { + self->Tick(a_Dt); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Tick'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnCollectItem of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnCollectItem00 +static int tolua_AllToLua_cPlugin_OnCollectItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPickup* a_Pickup = ((cPickup*) tolua_tousertype(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnCollectItem'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnCollectItem(a_Pickup,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnCollectItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnDisconnect of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnDisconnect00 +static int tolua_AllToLua_cPlugin_OnDisconnect00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisconnect'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnDisconnect(a_Reason,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)a_Reason); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnDisconnect'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnBlockPlace of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnBlockPlace00 +static int tolua_AllToLua_cPlugin_OnBlockPlace00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_BlockPlace",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPacket_BlockPlace* a_PacketData = ((cPacket_BlockPlace*) tolua_tousertype(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnBlockPlace'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnBlockPlace(a_PacketData,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnBlockPlace'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnBlockDig of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnBlockDig00 +static int tolua_AllToLua_cPlugin_OnBlockDig00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_BlockDig",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPacket_BlockDig* a_PacketData = ((cPacket_BlockDig*) tolua_tousertype(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); + cItem* a_PickupItem = ((cItem*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnBlockDig'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnBlockDig(a_PacketData,a_Player,a_PickupItem); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnBlockDig'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnChat of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnChat00 +static int tolua_AllToLua_cPlugin_OnChat00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + const char* a_Chat = ((const char*) tolua_tostring(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnChat'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnChat(a_Chat,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnChat'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnLogin of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnLogin00 +static int tolua_AllToLua_cPlugin_OnLogin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_Login",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPacket_Login* a_PacketData = ((cPacket_Login*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnLogin'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnLogin(a_PacketData); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnLogin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnPlayerSpawn of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPlayerSpawn00 +static int tolua_AllToLua_cPlugin_OnPlayerSpawn00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPlayerSpawn'", NULL); +#endif + { + self->OnPlayerSpawn(a_Player); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnPlayerSpawn'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnPlayerJoin of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPlayerJoin00 +static int tolua_AllToLua_cPlugin_OnPlayerJoin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPlayerJoin'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnPlayerJoin(a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnPlayerJoin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnPlayerMove of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPlayerMove00 +static int tolua_AllToLua_cPlugin_OnPlayerMove00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPlayerMove'", NULL); +#endif + { + self->OnPlayerMove(a_Player); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnPlayerMove'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnTakeDamage of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnTakeDamage00 +static int tolua_AllToLua_cPlugin_OnTakeDamage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"TakeDamageInfo",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPawn* a_Pawn = ((cPawn*) tolua_tousertype(tolua_S,2,0)); + TakeDamageInfo* a_TakeDamageInfo = ((TakeDamageInfo*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnTakeDamage'", NULL); +#endif + { + self->OnTakeDamage(a_Pawn,a_TakeDamageInfo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnTakeDamage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnKilled of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnKilled00 +static int tolua_AllToLua_cPlugin_OnKilled00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPawn* a_Killed = ((cPawn*) tolua_tousertype(tolua_S,2,0)); + cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnKilled'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnKilled(a_Killed,a_Killer); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnKilled'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnChunkGenerated of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnChunkGenerated00 +static int tolua_AllToLua_cPlugin_OnChunkGenerated00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); + int a_ChunkX = ((int) tolua_tonumber(tolua_S,3,0)); + int a_ChunkZ = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnChunkGenerated'", NULL); +#endif + { + self->OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnChunkGenerated'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnChunkGenerating of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnChunkGenerating00 +static int tolua_AllToLua_cPlugin_OnChunkGenerating00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cLuaChunk",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0)); + cLuaChunk* a_pLuaChunk = ((cLuaChunk*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnChunkGenerating'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnChunkGenerating'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnPreCrafting of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPreCrafting00 +static int tolua_AllToLua_cPlugin_OnPreCrafting00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); + const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); + cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPreCrafting'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnPreCrafting(a_Player,a_Grid,a_Recipe); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnPreCrafting'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnCraftingNoRecipe of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnCraftingNoRecipe00 +static int tolua_AllToLua_cPlugin_OnCraftingNoRecipe00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); + const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); + cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnCraftingNoRecipe'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnCraftingNoRecipe'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnPostCrafting of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnPostCrafting00 +static int tolua_AllToLua_cPlugin_OnPostCrafting00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); + const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); + cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnPostCrafting'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnPostCrafting(a_Player,a_Grid,a_Recipe); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnPostCrafting'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: OnBlockToPickup of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_OnBlockToPickup00 +static int tolua_AllToLua_cPlugin_OnBlockToPickup00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"BLOCKTYPE",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"NIBBLETYPE",0,&tolua_err)) || + !tolua_isusertype(tolua_S,4,"const cPlayer",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,6,&tolua_err) || !tolua_isusertype(tolua_S,6,"cItems",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + BLOCKTYPE a_BlockType = *((BLOCKTYPE*) tolua_tousertype(tolua_S,2,0)); + NIBBLETYPE a_BlockMeta = *((NIBBLETYPE*) tolua_tousertype(tolua_S,3,0)); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,4,0)); + const cItem* a_EquippedItem = ((const cItem*) tolua_tousertype(tolua_S,5,0)); + cItems* a_Pickups = ((cItems*) tolua_tousertype(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnBlockToPickup'", NULL); +#endif + { + bool tolua_ret = (bool) self->OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,*a_EquippedItem,*a_Pickups); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnBlockToPickup'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetName of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_GetName00 +static int tolua_AllToLua_cPlugin_GetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPlugin* self = (const cPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); +#endif + { + const char* tolua_ret = (const char*) self->GetName(); + tolua_pushstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetName of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_SetName00 +static int tolua_AllToLua_cPlugin_SetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + const char* a_Name = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL); +#endif + { + self->SetName(a_Name); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetVersion of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_GetVersion00 +static int tolua_AllToLua_cPlugin_GetVersion00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPlugin* self = (const cPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetVersion'", NULL); +#endif + { + int tolua_ret = (int) self->GetVersion(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetVersion'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetVersion of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_SetVersion00 +static int tolua_AllToLua_cPlugin_SetVersion00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + int a_Version = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetVersion'", NULL); +#endif + { + self->SetVersion(a_Version); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetVersion'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Command of class CommandStruct */ +#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Command +static int tolua_get_cPlugin__CommandStruct_Command(lua_State* tolua_S) +{ + cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Command'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Command); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Command of class CommandStruct */ +#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Command +static int tolua_set_cPlugin__CommandStruct_Command(lua_State* tolua_S) +{ + cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Command'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Command = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Description of class CommandStruct */ +#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Description +static int tolua_get_cPlugin__CommandStruct_Description(lua_State* tolua_S) +{ + cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Description'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Description); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Description of class CommandStruct */ +#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Description +static int tolua_set_cPlugin__CommandStruct_Description(lua_State* tolua_S) +{ + cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Description'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Description = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Permission of class CommandStruct */ +#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Permission +static int tolua_get_cPlugin__CommandStruct_Permission(lua_State* tolua_S) +{ + cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Permission'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Permission); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Permission of class CommandStruct */ +#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Permission +static int tolua_set_cPlugin__CommandStruct_Permission(lua_State* tolua_S) +{ + cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Permission'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Permission = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddCommand of class cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_AddCommand00 +static int tolua_AllToLua_cPlugin_AddCommand00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || + !tolua_iscppstring(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + std::string a_Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); + std::string a_Description = ((std::string) tolua_tocppstring(tolua_S,3,0)); + std::string a_Permission = ((std::string) tolua_tocppstring(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddCommand'", NULL); +#endif + { + self->AddCommand(a_Command,a_Description,a_Permission); + tolua_pushcppstring(tolua_S,(const char*)a_Command); + tolua_pushcppstring(tolua_S,(const char*)a_Description); + tolua_pushcppstring(tolua_S,(const char*)a_Permission); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddCommand'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cPlugin : public cPlugin, public ToluaBase { +public: + void OnDisable( void ) { + if (push_method("OnDisable", tolua_AllToLua_cPlugin_OnDisable00)) { + ToluaBase::dbcall(lua_state, 1, 0); + } else { + return ( void ) cPlugin:: OnDisable(); + }; + }; + bool Initialize( void ) { + if (push_method("Initialize", tolua_AllToLua_cPlugin_Initialize00)) { + ToluaBase::dbcall(lua_state, 1, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + if (lua_state) + LOG("pure-virtual method cPlugin::Initialize not implemented."); + else { + LOG("pure-virtual method cPlugin::Initialize called with no lua_state. Aborting"); + ::abort(); + }; + return ( bool )0; + }; + }; + void Tick( float a_Dt) { + if (push_method("Tick", tolua_AllToLua_cPlugin_Tick00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Dt); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlugin:: Tick(a_Dt); + }; + }; + bool OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) { + if (push_method("OnCollectItem", tolua_AllToLua_cPlugin_OnCollectItem00)) { + tolua_pushusertype(lua_state, (void*)a_Pickup, "cPickup"); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnCollectItem(a_Pickup,a_Player); + }; + }; + bool OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { + if (push_method("OnDisconnect", tolua_AllToLua_cPlugin_OnDisconnect00)) { + tolua_pushcppstring(lua_state, (const char*)a_Reason); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnDisconnect(a_Reason,a_Player); + }; + }; + bool OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) { + if (push_method("OnBlockPlace", tolua_AllToLua_cPlugin_OnBlockPlace00)) { + tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockPlace"); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnBlockPlace(a_PacketData,a_Player); + }; + }; + bool OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) { + if (push_method("OnBlockDig", tolua_AllToLua_cPlugin_OnBlockDig00)) { + tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockDig"); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + tolua_pushusertype(lua_state, (void*)a_PickupItem, "cItem"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnBlockDig(a_PacketData,a_Player,a_PickupItem); + }; + }; + bool OnChat( const char* a_Chat, cPlayer* a_Player) { + if (push_method("OnChat", tolua_AllToLua_cPlugin_OnChat00)) { + tolua_pushstring(lua_state, (const char*)a_Chat); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnChat(a_Chat,a_Player); + }; + }; + bool OnLogin( cPacket_Login* a_PacketData) { + if (push_method("OnLogin", tolua_AllToLua_cPlugin_OnLogin00)) { + tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_Login"); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnLogin(a_PacketData); + }; + }; + void OnPlayerSpawn( cPlayer* a_Player) { + if (push_method("OnPlayerSpawn", tolua_AllToLua_cPlugin_OnPlayerSpawn00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlugin:: OnPlayerSpawn(a_Player); + }; + }; + bool OnPlayerJoin( cPlayer* a_Player) { + if (push_method("OnPlayerJoin", tolua_AllToLua_cPlugin_OnPlayerJoin00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnPlayerJoin(a_Player); + }; + }; + void OnPlayerMove( cPlayer* a_Player) { + if (push_method("OnPlayerMove", tolua_AllToLua_cPlugin_OnPlayerMove00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlugin:: OnPlayerMove(a_Player); + }; + }; + void OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) { + if (push_method("OnTakeDamage", tolua_AllToLua_cPlugin_OnTakeDamage00)) { + tolua_pushusertype(lua_state, (void*)a_Pawn, "cPawn"); + tolua_pushusertype(lua_state, (void*)a_TakeDamageInfo, "TakeDamageInfo"); + ToluaBase::dbcall(lua_state, 3, 0); + } else { + return ( void ) cPlugin:: OnTakeDamage(a_Pawn,a_TakeDamageInfo); + }; + }; + bool OnKilled( cPawn* a_Killed, cEntity* a_Killer) { + if (push_method("OnKilled", tolua_AllToLua_cPlugin_OnKilled00)) { + tolua_pushusertype(lua_state, (void*)a_Killed, "cPawn"); + tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnKilled(a_Killed,a_Killer); + }; + }; + void OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) { + if (push_method("OnChunkGenerated", tolua_AllToLua_cPlugin_OnChunkGenerated00)) { + tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); + tolua_pushnumber(lua_state, (lua_Number)a_ChunkX); + tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ); + ToluaBase::dbcall(lua_state, 4, 0); + } else { + return ( void ) cPlugin:: OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); + }; + }; + bool OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) { + if (push_method("OnChunkGenerating", tolua_AllToLua_cPlugin_OnChunkGenerating00)) { + tolua_pushnumber(lua_state, (lua_Number)a_ChunkX); + tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ); + tolua_pushusertype(lua_state, (void*)a_pLuaChunk, "cLuaChunk"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); + }; + }; + bool OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + if (push_method("OnPreCrafting", tolua_AllToLua_cPlugin_OnPreCrafting00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); + tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnPreCrafting(a_Player,a_Grid,a_Recipe); + }; + }; + bool OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + if (push_method("OnCraftingNoRecipe", tolua_AllToLua_cPlugin_OnCraftingNoRecipe00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); + tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); + }; + }; + bool OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + if (push_method("OnPostCrafting", tolua_AllToLua_cPlugin_OnPostCrafting00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); + tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnPostCrafting(a_Player,a_Grid,a_Recipe); + }; + }; + bool OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) { + if (push_method("OnBlockToPickup", tolua_AllToLua_cPlugin_OnBlockToPickup00)) { + void* tolua_obj0 = (void*)new BLOCKTYPE(a_BlockType); + tolua_pushusertype_and_takeownership(lua_state, tolua_obj0, "BLOCKTYPE"); + void* tolua_obj1 = (void*)new NIBBLETYPE(a_BlockMeta); + tolua_pushusertype_and_takeownership(lua_state, tolua_obj1, "NIBBLETYPE"); + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)&a_EquippedItem, "const cItem"); + tolua_pushusertype(lua_state, (void*)&a_Pickups, "cItems"); + ToluaBase::dbcall(lua_state, 6, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin:: OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups); + }; + }; + + void cPlugin__OnDisable( void ) { + return ( void )cPlugin::OnDisable(); + }; + void cPlugin__Tick( float a_Dt) { + return ( void )cPlugin::Tick(a_Dt); + }; + bool cPlugin__OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) { + return ( bool )cPlugin::OnCollectItem(a_Pickup,a_Player); + }; + bool cPlugin__OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { + return ( bool )cPlugin::OnDisconnect(a_Reason,a_Player); + }; + bool cPlugin__OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) { + return ( bool )cPlugin::OnBlockPlace(a_PacketData,a_Player); + }; + bool cPlugin__OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) { + return ( bool )cPlugin::OnBlockDig(a_PacketData,a_Player,a_PickupItem); + }; + bool cPlugin__OnChat( const char* a_Chat, cPlayer* a_Player) { + return ( bool )cPlugin::OnChat(a_Chat,a_Player); + }; + bool cPlugin__OnLogin( cPacket_Login* a_PacketData) { + return ( bool )cPlugin::OnLogin(a_PacketData); + }; + void cPlugin__OnPlayerSpawn( cPlayer* a_Player) { + return ( void )cPlugin::OnPlayerSpawn(a_Player); + }; + bool cPlugin__OnPlayerJoin( cPlayer* a_Player) { + return ( bool )cPlugin::OnPlayerJoin(a_Player); + }; + void cPlugin__OnPlayerMove( cPlayer* a_Player) { + return ( void )cPlugin::OnPlayerMove(a_Player); + }; + void cPlugin__OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) { + return ( void )cPlugin::OnTakeDamage(a_Pawn,a_TakeDamageInfo); + }; + bool cPlugin__OnKilled( cPawn* a_Killed, cEntity* a_Killer) { + return ( bool )cPlugin::OnKilled(a_Killed,a_Killer); + }; + void cPlugin__OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) { + return ( void )cPlugin::OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); + }; + bool cPlugin__OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) { + return ( bool )cPlugin::OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); + }; + bool cPlugin__OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + return ( bool )cPlugin::OnPreCrafting(a_Player,a_Grid,a_Recipe); + }; + bool cPlugin__OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + return ( bool )cPlugin::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); + }; + bool cPlugin__OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + return ( bool )cPlugin::OnPostCrafting(a_Player,a_Grid,a_Recipe); + }; + bool cPlugin__OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) { + return ( bool )cPlugin::OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups); + }; + Lua__cPlugin( void ): cPlugin(){}; +}; + +/* method: tolua__set_instance of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_tolua__set_instance00 +static int tolua_AllToLua_Lua__cPlugin_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnDisable of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisable00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisable00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnDisable'", NULL); +#endif + { + self->cPlugin__OnDisable(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnDisable'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__Tick of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__Tick00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__Tick00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__Tick'", NULL); +#endif + { + self->cPlugin__Tick(a_Dt); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__Tick'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnCollectItem of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnCollectItem00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnCollectItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPickup* a_Pickup = ((cPickup*) tolua_tousertype(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnCollectItem'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnCollectItem(a_Pickup,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnCollectItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnDisconnect of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnDisconnect'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnDisconnect(a_Reason,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)a_Reason); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnDisconnect'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnBlockPlace of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockPlace00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockPlace00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_BlockPlace",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPacket_BlockPlace* a_PacketData = ((cPacket_BlockPlace*) tolua_tousertype(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnBlockPlace'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnBlockPlace(a_PacketData,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnBlockPlace'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnBlockDig of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockDig00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockDig00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_BlockDig",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPacket_BlockDig* a_PacketData = ((cPacket_BlockDig*) tolua_tousertype(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); + cItem* a_PickupItem = ((cItem*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnBlockDig'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnBlockDig(a_PacketData,a_Player,a_PickupItem); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnBlockDig'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnChat of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + const char* a_Chat = ((const char*) tolua_tostring(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnChat'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnChat(a_Chat,a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnChat'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnLogin of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnLogin00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnLogin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_Login",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPacket_Login* a_PacketData = ((cPacket_Login*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnLogin'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnLogin(a_PacketData); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnLogin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnPlayerSpawn of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerSpawn00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerSpawn00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPlayerSpawn'", NULL); +#endif + { + self->cPlugin__OnPlayerSpawn(a_Player); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPlayerSpawn'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnPlayerJoin of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerJoin00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerJoin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPlayerJoin'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnPlayerJoin(a_Player); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPlayerJoin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnPlayerMove of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerMove00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerMove00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPlayerMove'", NULL); +#endif + { + self->cPlugin__OnPlayerMove(a_Player); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPlayerMove'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnTakeDamage of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnTakeDamage00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnTakeDamage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"TakeDamageInfo",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPawn* a_Pawn = ((cPawn*) tolua_tousertype(tolua_S,2,0)); + TakeDamageInfo* a_TakeDamageInfo = ((TakeDamageInfo*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnTakeDamage'", NULL); +#endif + { + self->cPlugin__OnTakeDamage(a_Pawn,a_TakeDamageInfo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnTakeDamage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnKilled of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnKilled00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnKilled00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPawn",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cPawn* a_Killed = ((cPawn*) tolua_tousertype(tolua_S,2,0)); + cEntity* a_Killer = ((cEntity*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnKilled'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnKilled(a_Killed,a_Killer); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnKilled'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnChunkGenerated of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerated00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerated00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); + int a_ChunkX = ((int) tolua_tonumber(tolua_S,3,0)); + int a_ChunkZ = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnChunkGenerated'", NULL); +#endif + { + self->cPlugin__OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnChunkGenerated'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnChunkGenerating of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerating00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerating00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cLuaChunk",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0)); + cLuaChunk* a_pLuaChunk = ((cLuaChunk*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnChunkGenerating'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnChunkGenerating'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnPreCrafting of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPreCrafting00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPreCrafting00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); + const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); + cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPreCrafting'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnPreCrafting(a_Player,a_Grid,a_Recipe); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPreCrafting'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnCraftingNoRecipe of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnCraftingNoRecipe00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnCraftingNoRecipe00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); + const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); + cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnCraftingNoRecipe'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnCraftingNoRecipe'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnPostCrafting of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnPostCrafting00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnPostCrafting00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"const cCraftingGrid",0,&tolua_err) || + !tolua_isusertype(tolua_S,4,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,2,0)); + const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,3,0)); + cCraftingRecipe* a_Recipe = ((cCraftingRecipe*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnPostCrafting'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnPostCrafting(a_Player,a_Grid,a_Recipe); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnPostCrafting'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin__OnBlockToPickup of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockToPickup00 +static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockToPickup00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"BLOCKTYPE",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"NIBBLETYPE",0,&tolua_err)) || + !tolua_isusertype(tolua_S,4,"const cPlayer",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,6,&tolua_err) || !tolua_isusertype(tolua_S,6,"cItems",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + BLOCKTYPE a_BlockType = *((BLOCKTYPE*) tolua_tousertype(tolua_S,2,0)); + NIBBLETYPE a_BlockMeta = *((NIBBLETYPE*) tolua_tousertype(tolua_S,3,0)); + const cPlayer* a_Player = ((const cPlayer*) tolua_tousertype(tolua_S,4,0)); + const cItem* a_EquippedItem = ((const cItem*) tolua_tousertype(tolua_S,5,0)); + cItems* a_Pickups = ((cItems*) tolua_tousertype(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnBlockToPickup'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin__OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,*a_EquippedItem,*a_Pickups); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin__OnBlockToPickup'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_new00 +static int tolua_AllToLua_Lua__cPlugin_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + Lua__cPlugin* tolua_ret = (Lua__cPlugin*) Mtolua_new((Lua__cPlugin)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPlugin"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_new00_local +static int tolua_AllToLua_Lua__cPlugin_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + Lua__cPlugin* tolua_ret = (Lua__cPlugin*) Mtolua_new((Lua__cPlugin)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPlugin"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class Lua__cPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_delete00 +static int tolua_AllToLua_Lua__cPlugin_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_Lua__cPlugin (lua_State* tolua_S) +{ + Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); + delete self; + return 0; +} +#endif + +/* method: OnDisable of class cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_OnDisable00 +static int tolua_AllToLua_cPlugin_NewLua_OnDisable00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisable'", NULL); +#endif + { + self->OnDisable(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'OnDisable'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Initialize of class cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_Initialize00 +static int tolua_AllToLua_cPlugin_NewLua_Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); +#endif + { + bool tolua_ret = (bool) self->Initialize(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Tick of class cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_Tick00 +static int tolua_AllToLua_cPlugin_NewLua_Tick00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); + float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Tick'", NULL); +#endif + { + self->Tick(a_Dt); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Tick'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CreateWebPlugin of class cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_NewLua_CreateWebPlugin00 +static int tolua_AllToLua_cPlugin_NewLua_CreateWebPlugin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin_NewLua",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin_NewLua* self = (cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); + lua_State* a_LuaState = tolua_S; +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CreateWebPlugin'", NULL); +#endif + { + cWebPlugin_Lua* tolua_ret = (cWebPlugin_Lua*) self->CreateWebPlugin(a_LuaState); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWebPlugin_Lua"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CreateWebPlugin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cPlugin_NewLua : public cPlugin_NewLua, public ToluaBase { +public: + void OnDisable( void ) { + if (push_method("OnDisable", tolua_AllToLua_cPlugin_NewLua_OnDisable00)) { + ToluaBase::dbcall(lua_state, 1, 0); + } else { + return ( void ) cPlugin_NewLua:: OnDisable(); + }; + }; + bool Initialize( void ) { + if (push_method("Initialize", tolua_AllToLua_cPlugin_NewLua_Initialize00)) { + ToluaBase::dbcall(lua_state, 1, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: Initialize(); + }; + }; + void Tick( float a_Dt) { + if (push_method("Tick", tolua_AllToLua_cPlugin_NewLua_Tick00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Dt); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlugin_NewLua:: Tick(a_Dt); + }; + }; + bool OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) { + if (push_method("OnCollectItem", tolua_AllToLua_cPlugin_OnCollectItem00)) { + tolua_pushusertype(lua_state, (void*)a_Pickup, "cPickup"); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnCollectItem(a_Pickup,a_Player); + }; + }; + bool OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { + if (push_method("OnDisconnect", tolua_AllToLua_cPlugin_OnDisconnect00)) { + tolua_pushcppstring(lua_state, (const char*)a_Reason); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnDisconnect(a_Reason,a_Player); + }; + }; + bool OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) { + if (push_method("OnBlockPlace", tolua_AllToLua_cPlugin_OnBlockPlace00)) { + tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockPlace"); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnBlockPlace(a_PacketData,a_Player); + }; + }; + bool OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) { + if (push_method("OnBlockDig", tolua_AllToLua_cPlugin_OnBlockDig00)) { + tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_BlockDig"); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + tolua_pushusertype(lua_state, (void*)a_PickupItem, "cItem"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnBlockDig(a_PacketData,a_Player,a_PickupItem); + }; + }; + bool OnChat( const char* a_Chat, cPlayer* a_Player) { + if (push_method("OnChat", tolua_AllToLua_cPlugin_OnChat00)) { + tolua_pushstring(lua_state, (const char*)a_Chat); + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnChat(a_Chat,a_Player); + }; + }; + bool OnLogin( cPacket_Login* a_PacketData) { + if (push_method("OnLogin", tolua_AllToLua_cPlugin_OnLogin00)) { + tolua_pushusertype(lua_state, (void*)a_PacketData, "cPacket_Login"); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnLogin(a_PacketData); + }; + }; + void OnPlayerSpawn( cPlayer* a_Player) { + if (push_method("OnPlayerSpawn", tolua_AllToLua_cPlugin_OnPlayerSpawn00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlugin_NewLua:: OnPlayerSpawn(a_Player); + }; + }; + bool OnPlayerJoin( cPlayer* a_Player) { + if (push_method("OnPlayerJoin", tolua_AllToLua_cPlugin_OnPlayerJoin00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnPlayerJoin(a_Player); + }; + }; + void OnPlayerMove( cPlayer* a_Player) { + if (push_method("OnPlayerMove", tolua_AllToLua_cPlugin_OnPlayerMove00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPlugin_NewLua:: OnPlayerMove(a_Player); + }; + }; + void OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) { + if (push_method("OnTakeDamage", tolua_AllToLua_cPlugin_OnTakeDamage00)) { + tolua_pushusertype(lua_state, (void*)a_Pawn, "cPawn"); + tolua_pushusertype(lua_state, (void*)a_TakeDamageInfo, "TakeDamageInfo"); + ToluaBase::dbcall(lua_state, 3, 0); + } else { + return ( void ) cPlugin_NewLua:: OnTakeDamage(a_Pawn,a_TakeDamageInfo); + }; + }; + bool OnKilled( cPawn* a_Killed, cEntity* a_Killer) { + if (push_method("OnKilled", tolua_AllToLua_cPlugin_OnKilled00)) { + tolua_pushusertype(lua_state, (void*)a_Killed, "cPawn"); + tolua_pushusertype(lua_state, (void*)a_Killer, "cEntity"); + ToluaBase::dbcall(lua_state, 3, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnKilled(a_Killed,a_Killer); + }; + }; + void OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) { + if (push_method("OnChunkGenerated", tolua_AllToLua_cPlugin_OnChunkGenerated00)) { + tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); + tolua_pushnumber(lua_state, (lua_Number)a_ChunkX); + tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ); + ToluaBase::dbcall(lua_state, 4, 0); + } else { + return ( void ) cPlugin_NewLua:: OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); + }; + }; + bool OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) { + if (push_method("OnChunkGenerating", tolua_AllToLua_cPlugin_OnChunkGenerating00)) { + tolua_pushnumber(lua_state, (lua_Number)a_ChunkX); + tolua_pushnumber(lua_state, (lua_Number)a_ChunkZ); + tolua_pushusertype(lua_state, (void*)a_pLuaChunk, "cLuaChunk"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); + }; + }; + bool OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + if (push_method("OnPreCrafting", tolua_AllToLua_cPlugin_OnPreCrafting00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); + tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnPreCrafting(a_Player,a_Grid,a_Recipe); + }; + }; + bool OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + if (push_method("OnCraftingNoRecipe", tolua_AllToLua_cPlugin_OnCraftingNoRecipe00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); + tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); + }; + }; + bool OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + if (push_method("OnPostCrafting", tolua_AllToLua_cPlugin_OnPostCrafting00)) { + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)a_Grid, "const cCraftingGrid"); + tolua_pushusertype(lua_state, (void*)a_Recipe, "cCraftingRecipe"); + ToluaBase::dbcall(lua_state, 4, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnPostCrafting(a_Player,a_Grid,a_Recipe); + }; + }; + bool OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) { + if (push_method("OnBlockToPickup", tolua_AllToLua_cPlugin_OnBlockToPickup00)) { + void* tolua_obj0 = (void*)new BLOCKTYPE(a_BlockType); + tolua_pushusertype_and_takeownership(lua_state, tolua_obj0, "BLOCKTYPE"); + void* tolua_obj1 = (void*)new NIBBLETYPE(a_BlockMeta); + tolua_pushusertype_and_takeownership(lua_state, tolua_obj1, "NIBBLETYPE"); + tolua_pushusertype(lua_state, (void*)a_Player, "const cPlayer"); + tolua_pushusertype(lua_state, (void*)&a_EquippedItem, "const cItem"); + tolua_pushusertype(lua_state, (void*)&a_Pickups, "cItems"); + ToluaBase::dbcall(lua_state, 6, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPlugin_NewLua:: OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups); + }; + }; + + void cPlugin_NewLua__OnDisable( void ) { + return ( void )cPlugin_NewLua::OnDisable(); + }; + bool cPlugin_NewLua__Initialize( void ) { + return ( bool )cPlugin_NewLua::Initialize(); + }; + void cPlugin_NewLua__Tick( float a_Dt) { + return ( void )cPlugin_NewLua::Tick(a_Dt); + }; + bool cPlugin_NewLua__OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player) { + return ( bool )cPlugin_NewLua::OnCollectItem(a_Pickup,a_Player); + }; + bool cPlugin_NewLua__OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { + return ( bool )cPlugin_NewLua::OnDisconnect(a_Reason,a_Player); + }; + bool cPlugin_NewLua__OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player) { + return ( bool )cPlugin_NewLua::OnBlockPlace(a_PacketData,a_Player); + }; + bool cPlugin_NewLua__OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) { + return ( bool )cPlugin_NewLua::OnBlockDig(a_PacketData,a_Player,a_PickupItem); + }; + bool cPlugin_NewLua__OnChat( const char* a_Chat, cPlayer* a_Player) { + return ( bool )cPlugin_NewLua::OnChat(a_Chat,a_Player); + }; + bool cPlugin_NewLua__OnLogin( cPacket_Login* a_PacketData) { + return ( bool )cPlugin_NewLua::OnLogin(a_PacketData); + }; + void cPlugin_NewLua__OnPlayerSpawn( cPlayer* a_Player) { + return ( void )cPlugin_NewLua::OnPlayerSpawn(a_Player); + }; + bool cPlugin_NewLua__OnPlayerJoin( cPlayer* a_Player) { + return ( bool )cPlugin_NewLua::OnPlayerJoin(a_Player); + }; + void cPlugin_NewLua__OnPlayerMove( cPlayer* a_Player) { + return ( void )cPlugin_NewLua::OnPlayerMove(a_Player); + }; + void cPlugin_NewLua__OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo) { + return ( void )cPlugin_NewLua::OnTakeDamage(a_Pawn,a_TakeDamageInfo); + }; + bool cPlugin_NewLua__OnKilled( cPawn* a_Killed, cEntity* a_Killer) { + return ( bool )cPlugin_NewLua::OnKilled(a_Killed,a_Killer); + }; + void cPlugin_NewLua__OnChunkGenerated( cWorld* a_World, int a_ChunkX, int a_ChunkZ) { + return ( void )cPlugin_NewLua::OnChunkGenerated(a_World,a_ChunkX,a_ChunkZ); + }; + bool cPlugin_NewLua__OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk* a_pLuaChunk) { + return ( bool )cPlugin_NewLua::OnChunkGenerating(a_ChunkX,a_ChunkZ,a_pLuaChunk); + }; + bool cPlugin_NewLua__OnPreCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + return ( bool )cPlugin_NewLua::OnPreCrafting(a_Player,a_Grid,a_Recipe); + }; + bool cPlugin_NewLua__OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + return ( bool )cPlugin_NewLua::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); + }; + bool cPlugin_NewLua__OnPostCrafting( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { + return ( bool )cPlugin_NewLua::OnPostCrafting(a_Player,a_Grid,a_Recipe); + }; + bool cPlugin_NewLua__OnBlockToPickup( BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer* a_Player, const cItem& a_EquippedItem, cItems& a_Pickups) { + return ( bool )cPlugin_NewLua::OnBlockToPickup(a_BlockType,a_BlockMeta,a_Player,a_EquippedItem,a_Pickups); + }; +}; + +/* method: tolua__set_instance of class Lua__cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_tolua__set_instance00 +static int tolua_AllToLua_Lua__cPlugin_NewLua_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin_NewLua__OnDisable of class Lua__cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__OnDisable00 +static int tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__OnDisable00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin_NewLua__OnDisable'", NULL); +#endif + { + self->cPlugin_NewLua__OnDisable(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin_NewLua__OnDisable'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin_NewLua__Initialize of class Lua__cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Initialize00 +static int tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin_NewLua__Initialize'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPlugin_NewLua__Initialize(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin_NewLua__Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPlugin_NewLua__Tick of class Lua__cPlugin_NewLua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Tick00 +static int tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Tick00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPlugin_NewLua",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPlugin_NewLua* self = (Lua__cPlugin_NewLua*) tolua_tousertype(tolua_S,1,0); + float a_Dt = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin_NewLua__Tick'", NULL); +#endif + { + self->cPlugin_NewLua__Tick(a_Dt); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPlugin_NewLua__Tick'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetFileName of class cPlugin_Lua */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_Lua_GetFileName00 +static int tolua_AllToLua_cPlugin_Lua_GetFileName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlugin_Lua",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlugin_Lua* self = (cPlugin_Lua*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFileName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->GetFileName(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetFileName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetServer of class cServer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_GetServer00 +static int tolua_AllToLua_cServer_GetServer00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cServer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + cServer* tolua_ret = (cServer*) cServer::GetServer(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cServer"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetServer'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ServerCommand of class cServer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_ServerCommand00 +static int tolua_AllToLua_cServer_ServerCommand00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cServer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cServer* self = (cServer*) tolua_tousertype(tolua_S,1,0); + const char* a_Cmd = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ServerCommand'", NULL); +#endif + { + self->ServerCommand(a_Cmd); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ServerCommand'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SendMessage of class cServer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_SendMessage00 +static int tolua_AllToLua_cServer_SendMessage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cServer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"cPlayer",1,&tolua_err) || + !tolua_isboolean(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cServer* self = (cServer*) tolua_tousertype(tolua_S,1,0); + const char* a_Message = ((const char*) tolua_tostring(tolua_S,2,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); + bool a_bExclude = ((bool) tolua_toboolean(tolua_S,4,false)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL); +#endif + { + self->SendMessage(a_Message,a_Player,a_bExclude); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetTime of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetTime00 +static int tolua_AllToLua_cWorld_GetTime00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + float tolua_ret = (float) cWorld::GetTime(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetTime'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetGameMode of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetGameMode00 +static int tolua_AllToLua_cWorld_GetGameMode00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGameMode'", NULL); +#endif + { + eGameMode tolua_ret = (eGameMode) self->GetGameMode(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetGameMode'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetWorldTime of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetWorldTime00 +static int tolua_AllToLua_cWorld_SetWorldTime00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + long long a_WorldTime = ((long long) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetWorldTime'", NULL); +#endif + { + self->SetWorldTime(a_WorldTime); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetWorldTime'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetHeight of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetHeight00 +static int tolua_AllToLua_cWorld_GetHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHeight'", NULL); +#endif + { + int tolua_ret = (int) self->GetHeight(a_X,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: UnloadUnusedChunks of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_UnloadUnusedChunks00 +static int tolua_AllToLua_cWorld_UnloadUnusedChunks00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'UnloadUnusedChunks'", NULL); +#endif + { + self->UnloadUnusedChunks(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'UnloadUnusedChunks'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetMaxPlayers of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetMaxPlayers00 +static int tolua_AllToLua_cWorld_GetMaxPlayers00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxPlayers'", NULL); +#endif + { + unsigned int tolua_ret = (unsigned int) self->GetMaxPlayers(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetMaxPlayers'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetMaxPlayers of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetMaxPlayers00 +static int tolua_AllToLua_cWorld_SetMaxPlayers00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int iMax = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetMaxPlayers'", NULL); +#endif + { + self->SetMaxPlayers(iMax); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetMaxPlayers'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetNumPlayers of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetNumPlayers00 +static int tolua_AllToLua_cWorld_GetNumPlayers00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumPlayers'", NULL); +#endif + { + unsigned int tolua_ret = (unsigned int) self->GetNumPlayers(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetNumPlayers'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPlayer of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetPlayer00 +static int tolua_AllToLua_cWorld_GetPlayer00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + const char* a_PlayerName = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPlayer'", NULL); +#endif + { + cPlayer* tolua_ret = (cPlayer*) self->GetPlayer(a_PlayerName); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPlayer"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPlayer'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: UpdateSign of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_UpdateSign00 +static int tolua_AllToLua_cWorld_UpdateSign00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_iscppstring(tolua_S,5,0,&tolua_err) || + !tolua_iscppstring(tolua_S,6,0,&tolua_err) || + !tolua_iscppstring(tolua_S,7,0,&tolua_err) || + !tolua_iscppstring(tolua_S,8,0,&tolua_err) || + !tolua_isnoobj(tolua_S,9,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + const AString a_Line1 = ((const AString) tolua_tocppstring(tolua_S,5,0)); + const AString a_Line2 = ((const AString) tolua_tocppstring(tolua_S,6,0)); + const AString a_Line3 = ((const AString) tolua_tocppstring(tolua_S,7,0)); + const AString a_Line4 = ((const AString) tolua_tocppstring(tolua_S,8,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'UpdateSign'", NULL); +#endif + { + self->UpdateSign(a_X,a_Y,a_Z,a_Line1,a_Line2,a_Line3,a_Line4); + tolua_pushcppstring(tolua_S,(const char*)a_Line1); + tolua_pushcppstring(tolua_S,(const char*)a_Line2); + tolua_pushcppstring(tolua_S,(const char*)a_Line3); + tolua_pushcppstring(tolua_S,(const char*)a_Line4); + } + } + return 4; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'UpdateSign'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: RegenerateChunk of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_RegenerateChunk00 +static int tolua_AllToLua_cWorld_RegenerateChunk00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RegenerateChunk'", NULL); +#endif + { + self->RegenerateChunk(a_ChunkX,a_ChunkZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'RegenerateChunk'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GenerateChunk of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GenerateChunk00 +static int tolua_AllToLua_cWorld_GenerateChunk00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_ChunkX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_ChunkZ = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GenerateChunk'", NULL); +#endif + { + self->GenerateChunk(a_ChunkX,a_ChunkZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GenerateChunk'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetBlock of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetBlock00 +static int tolua_AllToLua_cWorld_SetBlock00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0)); + char a_BlockMeta = ((char) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlock'", NULL); +#endif + { + self->SetBlock(a_X,a_Y,a_Z,a_BlockType,a_BlockMeta); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetBlock'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: FastSetBlock of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_FastSetBlock00 +static int tolua_AllToLua_cWorld_FastSetBlock00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0)); + char a_BlockMeta = ((char) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FastSetBlock'", NULL); +#endif + { + self->FastSetBlock(a_X,a_Y,a_Z,a_BlockType,a_BlockMeta); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'FastSetBlock'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlock of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlock00 +static int tolua_AllToLua_cWorld_GetBlock00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlock'", NULL); +#endif + { + char tolua_ret = (char) self->GetBlock(a_X,a_Y,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlock'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlock of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlock01 +static int tolua_AllToLua_cWorld_GetBlock01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + const Vector3i* a_Pos = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlock'", NULL); +#endif + { + char tolua_ret = (char) self->GetBlock(*a_Pos); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cWorld_GetBlock00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlockMeta of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockMeta00 +static int tolua_AllToLua_cWorld_GetBlockMeta00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockMeta'", NULL); +#endif + { + char tolua_ret = (char) self->GetBlockMeta(a_X,a_Y,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlockMeta'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlockMeta of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockMeta01 +static int tolua_AllToLua_cWorld_GetBlockMeta01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + const Vector3i* a_Pos = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockMeta'", NULL); +#endif + { + char tolua_ret = (char) self->GetBlockMeta(*a_Pos); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cWorld_GetBlockMeta00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetBlockMeta of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetBlockMeta00 +static int tolua_AllToLua_cWorld_SetBlockMeta00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + char a_MetaData = ((char) tolua_tonumber(tolua_S,5,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlockMeta'", NULL); +#endif + { + self->SetBlockMeta(a_X,a_Y,a_Z,a_MetaData); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetBlockMeta'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetBlockMeta of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetBlockMeta01 +static int tolua_AllToLua_cWorld_SetBlockMeta01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + const Vector3i* a_Pos = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); + char a_MetaData = ((char) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlockMeta'", NULL); +#endif + { + self->SetBlockMeta(*a_Pos,a_MetaData); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cWorld_SetBlockMeta00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlockSkyLight of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockSkyLight00 +static int tolua_AllToLua_cWorld_GetBlockSkyLight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockSkyLight'", NULL); +#endif + { + char tolua_ret = (char) self->GetBlockSkyLight(a_X,a_Y,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlockSkyLight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlockTypeMeta of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockTypeMeta00 +static int tolua_AllToLua_cWorld_GetBlockTypeMeta00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); + char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0)); + unsigned char a_BlockMeta = ((unsigned char) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockTypeMeta'", NULL); +#endif + { + self->GetBlockTypeMeta(a_BlockX,a_BlockY,a_BlockZ,a_BlockType,a_BlockMeta); + tolua_pushnumber(tolua_S,(lua_Number)a_BlockType); + tolua_pushnumber(tolua_S,(lua_Number)a_BlockMeta); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlockTypeMeta'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DigBlock of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_DigBlock00 +static int tolua_AllToLua_cWorld_DigBlock00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DigBlock'", NULL); +#endif + { + bool tolua_ret = (bool) self->DigBlock(a_X,a_Y,a_Z); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DigBlock'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SendBlockTo of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SendBlockTo00 +static int tolua_AllToLua_cWorld_SendBlockTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isusertype(tolua_S,5,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,5,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendBlockTo'", NULL); +#endif + { + self->SendBlockTo(a_X,a_Y,a_Z,a_Player); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SendBlockTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetSpawnX of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSpawnX00 +static int tolua_AllToLua_cWorld_GetSpawnX00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSpawnX'", NULL); +#endif + { + const double tolua_ret = (const double) self->GetSpawnX(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetSpawnX'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetSpawnY of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSpawnY00 +static int tolua_AllToLua_cWorld_GetSpawnY00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSpawnY'", NULL); +#endif + { + const double tolua_ret = (const double) self->GetSpawnY(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetSpawnY'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetSpawnZ of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSpawnZ00 +static int tolua_AllToLua_cWorld_GetSpawnZ00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSpawnZ'", NULL); +#endif + { + const double tolua_ret = (const double) self->GetSpawnZ(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetSpawnZ'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlockEntity of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockEntity00 +static int tolua_AllToLua_cWorld_GetBlockEntity00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockEntity'", NULL); +#endif + { + OBSOLETE cBlockEntity* tolua_ret = (OBSOLETE cBlockEntity*) self->GetBlockEntity(a_X,a_Y,a_Z); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cBlockEntity"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlockEntity'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GrowTree of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowTree00 +static int tolua_AllToLua_cWorld_GrowTree00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowTree'", NULL); +#endif + { + self->GrowTree(a_BlockX,a_BlockY,a_BlockZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GrowTree'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GrowTreeFromSapling of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowTreeFromSapling00 +static int tolua_AllToLua_cWorld_GrowTreeFromSapling00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); + char a_SaplingMeta = ((char) tolua_tonumber(tolua_S,5,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowTreeFromSapling'", NULL); +#endif + { + self->GrowTreeFromSapling(a_BlockX,a_BlockY,a_BlockZ,a_SaplingMeta); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GrowTreeFromSapling'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GrowTreeByBiome of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowTreeByBiome00 +static int tolua_AllToLua_cWorld_GrowTreeByBiome00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowTreeByBiome'", NULL); +#endif + { + self->GrowTreeByBiome(a_BlockX,a_BlockY,a_BlockZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GrowTreeByBiome'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GrowPlant of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowPlant00 +static int tolua_AllToLua_cWorld_GrowPlant00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isboolean(tolua_S,5,1,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); + bool a_IsByBonemeal = ((bool) tolua_toboolean(tolua_S,5,false)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowPlant'", NULL); +#endif + { + bool tolua_ret = (bool) self->GrowPlant(a_BlockX,a_BlockY,a_BlockZ,a_IsByBonemeal); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GrowPlant'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GrowMelonPumpkin of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowMelonPumpkin00 +static int tolua_AllToLua_cWorld_GrowMelonPumpkin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); + char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowMelonPumpkin'", NULL); +#endif + { + self->GrowMelonPumpkin(a_BlockX,a_BlockY,a_BlockZ,a_BlockType); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GrowMelonPumpkin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBiomeAt of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBiomeAt00 +static int tolua_AllToLua_cWorld_GetBiomeAt00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBiomeAt'", NULL); +#endif + { + int tolua_ret = (int) self->GetBiomeAt(a_BlockX,a_BlockZ); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBiomeAt'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetName of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetName00 +static int tolua_AllToLua_cWorld_GetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); +#endif + { + const AString tolua_ret = (const AString) self->GetName(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SaveAllChunks of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SaveAllChunks00 +static int tolua_AllToLua_cWorld_SaveAllChunks00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SaveAllChunks'", NULL); +#endif + { + self->SaveAllChunks(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SaveAllChunks'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetNumChunks of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetNumChunks00 +static int tolua_AllToLua_cWorld_GetNumChunks00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumChunks'", NULL); +#endif + { + int tolua_ret = (int) self->GetNumChunks(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetNumChunks'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetGeneratorQueueLength of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetGeneratorQueueLength00 +static int tolua_AllToLua_cWorld_GetGeneratorQueueLength00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGeneratorQueueLength'", NULL); +#endif + { + int tolua_ret = (int) self->GetGeneratorQueueLength(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetGeneratorQueueLength'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetLightingQueueLength of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetLightingQueueLength00 +static int tolua_AllToLua_cWorld_GetLightingQueueLength00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLightingQueueLength'", NULL); +#endif + { + int tolua_ret = (int) self->GetLightingQueueLength(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetLightingQueueLength'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetStorageLoadQueueLength of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetStorageLoadQueueLength00 +static int tolua_AllToLua_cWorld_GetStorageLoadQueueLength00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStorageLoadQueueLength'", NULL); +#endif + { + int tolua_ret = (int) self->GetStorageLoadQueueLength(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetStorageLoadQueueLength'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetStorageSaveQueueLength of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetStorageSaveQueueLength00 +static int tolua_AllToLua_cWorld_GetStorageSaveQueueLength00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStorageSaveQueueLength'", NULL); +#endif + { + int tolua_ret = (int) self->GetStorageSaveQueueLength(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetStorageSaveQueueLength'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CastThunderbolt of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_CastThunderbolt00 +static int tolua_AllToLua_cWorld_CastThunderbolt00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CastThunderbolt'", NULL); +#endif + { + self->CastThunderbolt(a_X,a_Y,a_Z); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CastThunderbolt'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetWeather of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetWeather00 +static int tolua_AllToLua_cWorld_SetWeather00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + eWeather a_Weather = ((eWeather) (int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetWeather'", NULL); +#endif + { + self->SetWeather(a_Weather); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetWeather'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ChangeWeather of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_ChangeWeather00 +static int tolua_AllToLua_cWorld_ChangeWeather00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ChangeWeather'", NULL); +#endif + { + self->ChangeWeather(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ChangeWeather'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetWeather of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetWeather00 +static int tolua_AllToLua_cWorld_GetWeather00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWeather'", NULL); +#endif + { + eWeather tolua_ret = (eWeather) self->GetWeather(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWeather'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetNextBlockTick of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetNextBlockTick00 +static int tolua_AllToLua_cWorld_SetNextBlockTick00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetNextBlockTick'", NULL); +#endif + { + self->SetNextBlockTick(a_BlockX,a_BlockY,a_BlockZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetNextBlockTick'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetMaxSugarcaneHeight of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetMaxSugarcaneHeight00 +static int tolua_AllToLua_cWorld_GetMaxSugarcaneHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxSugarcaneHeight'", NULL); +#endif + { + int tolua_ret = (int) self->GetMaxSugarcaneHeight(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetMaxSugarcaneHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetMaxCactusHeight of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetMaxCactusHeight00 +static int tolua_AllToLua_cWorld_GetMaxCactusHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxCactusHeight'", NULL); +#endif + { + int tolua_ret = (int) self->GetMaxCactusHeight(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetMaxCactusHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Clear of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_Clear00 +static int tolua_AllToLua_cInventory_Clear00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); +#endif + { + self->Clear(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddItem of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_AddItem00 +static int tolua_AllToLua_cInventory_AddItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItem'", NULL); +#endif + { + bool tolua_ret = (bool) self->AddItem(*a_Item); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: RemoveItem of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_RemoveItem00 +static int tolua_AllToLua_cInventory_RemoveItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RemoveItem'", NULL); +#endif + { + bool tolua_ret = (bool) self->RemoveItem(*a_Item); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'RemoveItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetSlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetSlot00 +static int tolua_AllToLua_cInventory_GetSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSlot'", NULL); +#endif + { + cItem* tolua_ret = (cItem*) self->GetSlot(a_SlotNum); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetSlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetFromHotBar of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetFromHotBar00 +static int tolua_AllToLua_cInventory_GetFromHotBar00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFromHotBar'", NULL); +#endif + { + cItem* tolua_ret = (cItem*) self->GetFromHotBar(a_SlotNum); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetFromHotBar'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetEquippedItem of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetEquippedItem00 +static int tolua_AllToLua_cInventory_GetEquippedItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEquippedItem'", NULL); +#endif + { + cItem& tolua_ret = (cItem&) self->GetEquippedItem(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetEquippedItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetEquippedSlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_SetEquippedSlot00 +static int tolua_AllToLua_cInventory_SetEquippedSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetEquippedSlot'", NULL); +#endif + { + self->SetEquippedSlot(a_SlotNum); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetEquippedSlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetEquippedSlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetEquippedSlot00 +static int tolua_AllToLua_cInventory_GetEquippedSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEquippedSlot'", NULL); +#endif + { + short tolua_ret = (short) self->GetEquippedSlot(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetEquippedSlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SendSlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_SendSlot00 +static int tolua_AllToLua_cInventory_SendSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendSlot'", NULL); +#endif + { + self->SendSlot(a_SlotNum); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SendSlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_new00 +static int tolua_AllToLua_cItem_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,1,&tolua_err) || + !tolua_isnumber(tolua_S,3,1,&tolua_err) || + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,E_ITEM_EMPTY)); + char a_ItemCount = ((char) tolua_tonumber(tolua_S,3,0)); + short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0)); + { + cItem* tolua_ret = (cItem*) Mtolua_new((cItem)(a_ItemID,a_ItemCount,a_ItemHealth)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_new00_local +static int tolua_AllToLua_cItem_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,1,&tolua_err) || + !tolua_isnumber(tolua_S,3,1,&tolua_err) || + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID a_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,E_ITEM_EMPTY)); + char a_ItemCount = ((char) tolua_tonumber(tolua_S,3,0)); + short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0)); + { + cItem* tolua_ret = (cItem*) Mtolua_new((cItem)(a_ItemID,a_ItemCount,a_ItemHealth)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Empty of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_Empty00 +static int tolua_AllToLua_cItem_Empty00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Empty'", NULL); +#endif + { + self->Empty(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Empty'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Clear of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_Clear00 +static int tolua_AllToLua_cItem_Clear00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); +#endif + { + self->Clear(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsEmpty of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_IsEmpty00 +static int tolua_AllToLua_cItem_IsEmpty00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsEmpty'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsEmpty(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsEmpty'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Equals of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_Equals00 +static int tolua_AllToLua_cItem_Equals00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0); + cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); +#endif + { + bool tolua_ret = (bool) self->Equals(*a_Item); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetMaxDuration of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_GetMaxDuration00 +static int tolua_AllToLua_cItem_GetMaxDuration00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxDuration'", NULL); +#endif + { + int tolua_ret = (int) self->GetMaxDuration(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetMaxDuration'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DamageItem of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_DamageItem00 +static int tolua_AllToLua_cItem_DamageItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DamageItem'", NULL); +#endif + { + bool tolua_ret = (bool) self->DamageItem(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DamageItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HasDuration of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_HasDuration00 +static int tolua_AllToLua_cItem_HasDuration00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasDuration'", NULL); +#endif + { + bool tolua_ret = (bool) self->HasDuration(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'HasDuration'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetJson of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_GetJson00 +static int tolua_AllToLua_cItem_GetJson00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Json::Value",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0); + Json::Value* a_OutValue = ((Json::Value*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetJson'", NULL); +#endif + { + self->GetJson(*a_OutValue); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetJson'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: FromJson of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_FromJson00 +static int tolua_AllToLua_cItem_FromJson00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Json::Value",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); + const Json::Value* a_Value = ((const Json::Value*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FromJson'", NULL); +#endif + { + self->FromJson(*a_Value); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'FromJson'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsEnchantable of class cItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItem_IsEnchantable00 +static int tolua_AllToLua_cItem_IsEnchantable00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + ENUM_ITEM_ID item = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0)); + { + bool tolua_ret = (bool) cItem::IsEnchantable(item); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsEnchantable'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_ItemID of class cItem */ +#ifndef TOLUA_DISABLE_tolua_get_cItem_m_ItemID +static int tolua_get_cItem_m_ItemID(lua_State* tolua_S) +{ + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemID'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemID); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_ItemID of class cItem */ +#ifndef TOLUA_DISABLE_tolua_set_cItem_m_ItemID +static int tolua_set_cItem_m_ItemID(lua_State* tolua_S) +{ + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemID'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_ItemID = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_ItemCount of class cItem */ +#ifndef TOLUA_DISABLE_tolua_get_cItem_m_ItemCount +static int tolua_get_cItem_m_ItemCount(lua_State* tolua_S) +{ + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemCount'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemCount); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_ItemCount of class cItem */ +#ifndef TOLUA_DISABLE_tolua_set_cItem_m_ItemCount +static int tolua_set_cItem_m_ItemCount(lua_State* tolua_S) +{ + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemCount'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_ItemCount = ((char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_ItemHealth of class cItem */ +#ifndef TOLUA_DISABLE_tolua_get_cItem_m_ItemHealth +static int tolua_get_cItem_m_ItemHealth(lua_State* tolua_S) +{ + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemHealth'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemHealth); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_ItemHealth of class cItem */ +#ifndef TOLUA_DISABLE_tolua_set_cItem_m_ItemHealth +static int tolua_set_cItem_m_ItemHealth(lua_State* tolua_S) +{ + cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemHealth'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_ItemHealth = ((short) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Name of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Name +static int tolua_get_HTTPFormData_Name(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Name'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Name); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Name of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Name +static int tolua_set_HTTPFormData_Name(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Name'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Name = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Value of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Value +static int tolua_get_HTTPFormData_Value(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Value'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Value); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Value of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Value +static int tolua_set_HTTPFormData_Value(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Value'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Value = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Type of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Type +static int tolua_get_HTTPFormData_Type(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Type'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Type); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Type of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Type +static int tolua_set_HTTPFormData_Type(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Type'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Type = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Method of class HTTPRequest */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Method +static int tolua_get_HTTPRequest_Method(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Method'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Method); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Method of class HTTPRequest */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPRequest_Method +static int tolua_set_HTTPRequest_Method(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Method'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Method = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Path of class HTTPRequest */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Path +static int tolua_get_HTTPRequest_Path(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Path'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Path); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Path of class HTTPRequest */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPRequest_Path +static int tolua_set_HTTPRequest_Path(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Path'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Path = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Username of class HTTPRequest */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Username +static int tolua_get_HTTPRequest_Username(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Username'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Username); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Username of class HTTPRequest */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPRequest_Username +static int tolua_set_HTTPRequest_Username(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Username'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Username = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_delete00 +static int tolua_AllToLua_cWebPlugin_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetName of class cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_SetName00 +static int tolua_AllToLua_cWebPlugin_SetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); + std::string a_Name = ((std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL); +#endif + { + self->SetName(a_Name); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetName of class cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_GetName00 +static int tolua_AllToLua_cWebPlugin_GetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->GetName(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HandleRequest of class cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_HandleRequest00 +static int tolua_AllToLua_cWebPlugin_HandleRequest00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"HTTPRequest",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); + HTTPRequest* a_Request = ((HTTPRequest*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HandleRequest'", NULL); +#endif + { + std::string tolua_ret = (std::string) self->HandleRequest(a_Request); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'HandleRequest'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Initialize of class cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_Initialize00 +static int tolua_AllToLua_cWebPlugin_Initialize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); +#endif + { + self->Initialize(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cWebPlugin : public cWebPlugin, public ToluaBase { +public: + std::string HandleRequest( HTTPRequest* a_Request) { + if (push_method("HandleRequest", tolua_AllToLua_cWebPlugin_HandleRequest00)) { + tolua_pushusertype(lua_state, (void*)a_Request, "HTTPRequest"); + ToluaBase::dbcall(lua_state, 2, 1); + std::string tolua_ret = ( std::string )tolua_tocppstring(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + if (lua_state) + LOG("pure-virtual method cWebPlugin::HandleRequest not implemented."); + else { + LOG("pure-virtual method cWebPlugin::HandleRequest called with no lua_state. Aborting"); + ::abort(); + }; + return ""; + }; + }; + void Initialize( void ) { + if (push_method("Initialize", tolua_AllToLua_cWebPlugin_Initialize00)) { + ToluaBase::dbcall(lua_state, 1, 0); + } else { + if (lua_state) + LOG("pure-virtual method cWebPlugin::Initialize not implemented."); + else { + LOG("pure-virtual method cWebPlugin::Initialize called with no lua_state. Aborting"); + ::abort(); + }; + return ( void )0; + }; + }; + + Lua__cWebPlugin( lua_State* L): cWebPlugin(L){}; +}; + +/* method: tolua__set_instance of class Lua__cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_tolua__set_instance00 +static int tolua_AllToLua_Lua__cWebPlugin_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cWebPlugin* self = (Lua__cWebPlugin*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Lua__cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_new00 +static int tolua_AllToLua_Lua__cWebPlugin_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + lua_State* L = tolua_S; + { + Lua__cWebPlugin* tolua_ret = (Lua__cWebPlugin*) Mtolua_new((Lua__cWebPlugin)(L)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cWebPlugin"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Lua__cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_new00_local +static int tolua_AllToLua_Lua__cWebPlugin_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + lua_State* L = tolua_S; + { + Lua__cWebPlugin* tolua_ret = (Lua__cWebPlugin*) Mtolua_new((Lua__cWebPlugin)(L)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cWebPlugin"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class Lua__cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cWebPlugin_delete00 +static int tolua_AllToLua_Lua__cWebPlugin_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cWebPlugin* self = (Lua__cWebPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_Lua__cWebPlugin (lua_State* tolua_S) +{ + Lua__cWebPlugin* self = (Lua__cWebPlugin*) tolua_tousertype(tolua_S,1,0); + delete self; + return 0; +} +#endif + +/* method: new of class cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new00 +static int tolua_AllToLua_cPickup_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) || + !tolua_isnumber(tolua_S,6,1,&tolua_err) || + !tolua_isnumber(tolua_S,7,1,&tolua_err) || + !tolua_isnumber(tolua_S,8,1,&tolua_err) || + !tolua_isnoobj(tolua_S,9,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0)); + float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f)); + float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f)); + float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f)); + { + cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new00_local +static int tolua_AllToLua_cPickup_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const cItem",0,&tolua_err)) || + !tolua_isnumber(tolua_S,6,1,&tolua_err) || + !tolua_isnumber(tolua_S,7,1,&tolua_err) || + !tolua_isnumber(tolua_S,8,1,&tolua_err) || + !tolua_isnoobj(tolua_S,9,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0)); + float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f)); + float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f)); + float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f)); + { + cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new01 +static int tolua_AllToLua_cPickup_new01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0)); + { + cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_PickupSpawnPacket)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cPickup_new00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new01_local +static int tolua_AllToLua_cPickup_new01_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0)); + { + cPickup* tolua_ret = (cPickup*) Mtolua_new((cPickup)(a_PickupSpawnPacket)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPickup"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cPickup_new00_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_delete00 +static int tolua_AllToLua_cPickup_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPickup",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetItem of class cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_GetItem00 +static int tolua_AllToLua_cPickup_GetItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPickup",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetItem'", NULL); +#endif + { + cItem* tolua_ret = (cItem*) self->GetItem(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CollectedBy of class cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_CollectedBy00 +static int tolua_AllToLua_cPickup_CollectedBy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPickup* self = (cPickup*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Dest = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CollectedBy'", NULL); +#endif + { + bool tolua_ret = (bool) self->CollectedBy(a_Dest); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CollectedBy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cPickup : public cPickup, public ToluaBase { +public: + bool CollectedBy( cPlayer* a_Dest) { + if (push_method("CollectedBy", tolua_AllToLua_cPickup_CollectedBy00)) { + tolua_pushusertype(lua_state, (void*)a_Dest, "cPlayer"); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPickup:: CollectedBy(a_Dest); + }; + }; + void Initialize( cWorld* a_World) { + if (push_method("Initialize", tolua_AllToLua_cEntity_Initialize00)) { + tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + return ( void ) cPickup:: Initialize(a_World); + }; + }; + unsigned int GetEntityType( void ) { + if (push_method("GetEntityType", tolua_AllToLua_cEntity_GetEntityType00)) { + ToluaBase::dbcall(lua_state, 1, 1); + unsigned int tolua_ret = (unsigned int )tolua_tonumber(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return (unsigned int ) cPickup:: GetEntityType(); + }; + }; + bool IsA( const char* a_EntityType) { + if (push_method("IsA", tolua_AllToLua_cEntity_IsA00)) { + tolua_pushstring(lua_state, (const char*)a_EntityType); + ToluaBase::dbcall(lua_state, 2, 1); + bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( bool ) cPickup:: IsA(a_EntityType); + }; + }; + const char* GetClass( void ) { + if (push_method("GetClass", tolua_AllToLua_cEntity_GetClass00)) { + ToluaBase::dbcall(lua_state, 1, 1); + const char* tolua_ret = ( const char* )tolua_tostring(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( const char* ) cPickup:: GetClass(); + }; + }; + void Tick( float a_Dt) { + if (push_method("Tick", tolua_AllToLua_cEntity_Tick00)) { + tolua_pushnumber(lua_state, (lua_Number)a_Dt); + ToluaBase::dbcall(lua_state, 2, 0); + } else { + if (lua_state) + LOG("pure-virtual method cPickup::Tick not implemented."); + else { + LOG("pure-virtual method cPickup::Tick called with no lua_state. Aborting"); + ::abort(); + }; + return ( void )0; + }; + }; + + bool cPickup__CollectedBy( cPlayer* a_Dest) { + return ( bool )cPickup::CollectedBy(a_Dest); + }; + void cPickup__Initialize( cWorld* a_World) { + return ( void )cPickup::Initialize(a_World); + }; + unsigned int cPickup__GetEntityType( void ) { + return (unsigned int )cPickup::GetEntityType(); + }; + bool cPickup__IsA( const char* a_EntityType) { + return ( bool )cPickup::IsA(a_EntityType); + }; + const char* cPickup__GetClass( void ) { + return ( const char* )cPickup::GetClass(); + }; + Lua__cPickup( int a_X, int a_Y, int a_Z, const cItem& a_Item, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f): cPickup(a_X,a_Y,a_Z,a_Item,a_SpeedX,a_SpeedY,a_SpeedZ){}; + Lua__cPickup( cPacket_PickupSpawn* a_PickupSpawnPacket): cPickup(a_PickupSpawnPacket){}; +}; + +/* method: tolua__set_instance of class Lua__cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_tolua__set_instance00 +static int tolua_AllToLua_Lua__cPickup_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPickup",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPickup__CollectedBy of class Lua__cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_cPickup__CollectedBy00 +static int tolua_AllToLua_Lua__cPickup_cPickup__CollectedBy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0); + cPlayer* a_Dest = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPickup__CollectedBy'", NULL); +#endif + { + bool tolua_ret = (bool) self->cPickup__CollectedBy(a_Dest); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPickup__CollectedBy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Lua__cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new00 +static int tolua_AllToLua_Lua__cPickup_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"cItem",0,&tolua_err)) || + !tolua_isnumber(tolua_S,6,1,&tolua_err) || + !tolua_isnumber(tolua_S,7,1,&tolua_err) || + !tolua_isnumber(tolua_S,8,1,&tolua_err) || + !tolua_isnoobj(tolua_S,9,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0)); + float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f)); + float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f)); + float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f)); + { + Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Lua__cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new00_local +static int tolua_AllToLua_Lua__cPickup_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"cItem",0,&tolua_err)) || + !tolua_isnumber(tolua_S,6,1,&tolua_err) || + !tolua_isnumber(tolua_S,7,1,&tolua_err) || + !tolua_isnumber(tolua_S,8,1,&tolua_err) || + !tolua_isnoobj(tolua_S,9,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,5,0)); + float a_SpeedX = ((float) tolua_tonumber(tolua_S,6,0.f)); + float a_SpeedY = ((float) tolua_tonumber(tolua_S,7,0.f)); + float a_SpeedZ = ((float) tolua_tonumber(tolua_S,8,0.f)); + { + Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_X,a_Y,a_Z,*a_Item,a_SpeedX,a_SpeedY,a_SpeedZ)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Lua__cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new01 +static int tolua_AllToLua_Lua__cPickup_new01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0)); + { + Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_PickupSpawnPacket)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Lua__cPickup_new00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Lua__cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_new01_local +static int tolua_AllToLua_Lua__cPickup_new01_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPickup",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPacket_PickupSpawn",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cPacket_PickupSpawn* a_PickupSpawnPacket = ((cPacket_PickupSpawn*) tolua_tousertype(tolua_S,2,0)); + { + Lua__cPickup* tolua_ret = (Lua__cPickup*) Mtolua_new((Lua__cPickup)(a_PickupSpawnPacket)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPickup"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Lua__cPickup_new00_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class Lua__cPickup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPickup_delete00 +static int tolua_AllToLua_Lua__cPickup_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPickup",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_Lua__cPickup (lua_State* tolua_S) +{ + Lua__cPickup* self = (Lua__cPickup*) tolua_tousertype(tolua_S,1,0); + delete self; + return 0; +} +#endif + +/* method: Get of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_Get00 +static int tolua_AllToLua_cRoot_Get00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + cRoot* tolua_ret = (cRoot*) cRoot::Get(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cRoot"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Get'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetServer of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetServer00 +static int tolua_AllToLua_cRoot_GetServer00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetServer'", NULL); +#endif + { + cServer* tolua_ret = (cServer*) self->GetServer(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cServer"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetServer'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetDefaultWorld of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetDefaultWorld00 +static int tolua_AllToLua_cRoot_GetDefaultWorld00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetDefaultWorld'", NULL); +#endif + { + cWorld* tolua_ret = (cWorld*) self->GetDefaultWorld(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetDefaultWorld'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetWorld of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetWorld00 +static int tolua_AllToLua_cRoot_GetWorld00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); + const AString a_WorldName = ((const AString) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWorld'", NULL); +#endif + { + cWorld* tolua_ret = (cWorld*) self->GetWorld(a_WorldName); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld"); + tolua_pushcppstring(tolua_S,(const char*)a_WorldName); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWorld'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetGroupManager of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetGroupManager00 +static int tolua_AllToLua_cRoot_GetGroupManager00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGroupManager'", NULL); +#endif + { + cGroupManager* tolua_ret = (cGroupManager*) self->GetGroupManager(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cGroupManager"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetGroupManager'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetCraftingRecipes of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetCraftingRecipes00 +static int tolua_AllToLua_cRoot_GetCraftingRecipes00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetCraftingRecipes'", NULL); +#endif + { + cCraftingRecipes* tolua_ret = (cCraftingRecipes*) self->GetCraftingRecipes(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCraftingRecipes"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetCraftingRecipes'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetFurnaceRecipe of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetFurnaceRecipe00 +static int tolua_AllToLua_cRoot_GetFurnaceRecipe00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetFurnaceRecipe'", NULL); +#endif + { + cFurnaceRecipe* tolua_ret = (cFurnaceRecipe*) self->GetFurnaceRecipe(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cFurnaceRecipe"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetFurnaceRecipe'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetWebAdmin of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetWebAdmin00 +static int tolua_AllToLua_cRoot_GetWebAdmin00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWebAdmin'", NULL); +#endif + { + cWebAdmin* tolua_ret = (cWebAdmin*) self->GetWebAdmin(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWebAdmin"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWebAdmin'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPluginManager of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetPluginManager00 +static int tolua_AllToLua_cRoot_GetPluginManager00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPluginManager'", NULL); +#endif + { + cPluginManager* tolua_ret = (cPluginManager*) self->GetPluginManager(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPluginManager"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPluginManager'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ServerCommand of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_ServerCommand00 +static int tolua_AllToLua_cRoot_ServerCommand00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); + const char* a_Cmd = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ServerCommand'", NULL); +#endif + { + self->ServerCommand(a_Cmd); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ServerCommand'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetTotalChunkCount of class cRoot */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetTotalChunkCount00 +static int tolua_AllToLua_cRoot_GetTotalChunkCount00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetTotalChunkCount'", NULL); +#endif + { + int tolua_ret = (int) self->GetTotalChunkCount(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetTotalChunkCount'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_delete00 +static int tolua_AllToLua_cTCPLink_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Connect of class cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_Connect00 +static int tolua_AllToLua_cTCPLink_Connect00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); + const AString a_Address = ((const AString) tolua_tocppstring(tolua_S,2,0)); + unsigned int a_Port = ((unsigned int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Connect'", NULL); +#endif + { + bool tolua_ret = (bool) self->Connect(a_Address,a_Port); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)a_Address); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Connect'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Send of class cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_Send00 +static int tolua_AllToLua_cTCPLink_Send00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); + const char* a_Data = ((const char*) tolua_tostring(tolua_S,2,0)); + unsigned int a_Size = ((unsigned int) tolua_tonumber(tolua_S,3,0)); + int a_Flags = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Send'", NULL); +#endif + { + int tolua_ret = (int) self->Send(a_Data,a_Size,a_Flags); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Send'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SendMessage of class cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_SendMessage00 +static int tolua_AllToLua_cTCPLink_SendMessage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,1,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); + const char* a_Message = ((const char*) tolua_tostring(tolua_S,2,0)); + int a_Flags = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL); +#endif + { + int tolua_ret = (int) self->SendMessage(a_Message,a_Flags); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CloseSocket of class cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTCPLink_CloseSocket00 +static int tolua_AllToLua_cTCPLink_CloseSocket00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTCPLink",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTCPLink* self = (cTCPLink*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CloseSocket'", NULL); +#endif + { + self->CloseSocket(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CloseSocket'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cTCPLink : public cTCPLink, public ToluaBase { +public: + void ReceivedData( char* a_Data, int a_Size) { + if (push_method("ReceivedData", NULL)) { + tolua_pushstring(lua_state, (const char*)a_Data); + tolua_pushnumber(lua_state, (lua_Number)a_Size); + ToluaBase::dbcall(lua_state, 3, 0); + } else { + if (lua_state) + LOG("pure-virtual method cTCPLink::ReceivedData not implemented."); + else { + LOG("pure-virtual method cTCPLink::ReceivedData called with no lua_state. Aborting"); + ::abort(); + }; + return ( void )0; + }; + }; + + Lua__cTCPLink( void ): cTCPLink(){}; +}; + +/* method: tolua__set_instance of class Lua__cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_tolua__set_instance00 +static int tolua_AllToLua_Lua__cTCPLink_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cTCPLink* self = (Lua__cTCPLink*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Lua__cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_new00 +static int tolua_AllToLua_Lua__cTCPLink_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + Lua__cTCPLink* tolua_ret = (Lua__cTCPLink*) Mtolua_new((Lua__cTCPLink)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cTCPLink"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Lua__cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_new00_local +static int tolua_AllToLua_Lua__cTCPLink_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + Lua__cTCPLink* tolua_ret = (Lua__cTCPLink*) Mtolua_new((Lua__cTCPLink)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cTCPLink"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class Lua__cTCPLink */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cTCPLink_delete00 +static int tolua_AllToLua_Lua__cTCPLink_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cTCPLink",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cTCPLink* self = (Lua__cTCPLink*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_Lua__cTCPLink (lua_State* tolua_S) +{ + Lua__cTCPLink* self = (Lua__cTCPLink*) tolua_tousertype(tolua_S,1,0); + delete self; + return 0; +} +#endif + +/* method: new of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new00 +static int tolua_AllToLua_Vector3f_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new00_local +static int tolua_AllToLua_Vector3f_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new01 +static int tolua_AllToLua_Vector3f_new01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new01_local +static int tolua_AllToLua_Vector3f_new01_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new00_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new02 +static int tolua_AllToLua_Vector3f_new02(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new01(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new02_local +static int tolua_AllToLua_Vector3f_new02_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new01_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new03 +static int tolua_AllToLua_Vector3f_new03(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new02(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new03_local +static int tolua_AllToLua_Vector3f_new03_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new02_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new04 +static int tolua_AllToLua_Vector3f_new04(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + { + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new03(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new04_local +static int tolua_AllToLua_Vector3f_new04_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + { + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new03_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new05 +static int tolua_AllToLua_Vector3f_new05(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + float a_x = ((float) tolua_tonumber(tolua_S,2,0)); + float a_y = ((float) tolua_tonumber(tolua_S,3,0)); + float a_z = ((float) tolua_tonumber(tolua_S,4,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(a_x,a_y,a_z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new04(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_new05_local +static int tolua_AllToLua_Vector3f_new05_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + float a_x = ((float) tolua_tonumber(tolua_S,2,0)); + float a_y = ((float) tolua_tonumber(tolua_S,3,0)); + float a_z = ((float) tolua_tonumber(tolua_S,4,0)); + { + Vector3f* tolua_ret = (Vector3f*) Mtolua_new((Vector3f)(a_x,a_y,a_z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f_new04_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Set of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Set00 +static int tolua_AllToLua_Vector3f_Set00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); + float a_x = ((float) tolua_tonumber(tolua_S,2,0)); + float a_y = ((float) tolua_tonumber(tolua_S,3,0)); + float a_z = ((float) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); +#endif + { + self->Set(a_x,a_y,a_z); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Normalize of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Normalize00 +static int tolua_AllToLua_Vector3f_Normalize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Normalize'", NULL); +#endif + { + self->Normalize(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Normalize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NormalizeCopy of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_NormalizeCopy00 +static int tolua_AllToLua_Vector3f_NormalizeCopy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->NormalizeCopy(); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'NormalizeCopy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NormalizeCopy of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_NormalizeCopy01 +static int tolua_AllToLua_Vector3f_NormalizeCopy01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + Vector3f* a_V = ((Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL); +#endif + { + self->NormalizeCopy(*a_V); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_Vector3f_NormalizeCopy00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Length of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Length00 +static int tolua_AllToLua_Vector3f_Length00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Length'", NULL); +#endif + { + float tolua_ret = (float) self->Length(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Length'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SqrLength of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_SqrLength00 +static int tolua_AllToLua_Vector3f_SqrLength00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SqrLength'", NULL); +#endif + { + float tolua_ret = (float) self->SqrLength(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SqrLength'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Dot of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Dot00 +static int tolua_AllToLua_Vector3f_Dot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* a_V = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dot'", NULL); +#endif + { + float tolua_ret = (float) self->Dot(*a_V); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Dot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Cross of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Cross00 +static int tolua_AllToLua_Vector3f_Cross00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Cross'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->Cross(*v); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Cross'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Equals of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f_Equals00 +static int tolua_AllToLua_Vector3f_Equals00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); +#endif + { + bool tolua_ret = (bool) self->Equals(*v); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator+ of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__add00 +static int tolua_AllToLua_Vector3f__add00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->operator+(*v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function '.add'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator+ of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__add01 +static int tolua_AllToLua_Vector3f__add01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->operator+(v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f__add00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator- of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__sub00 +static int tolua_AllToLua_Vector3f__sub00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->operator-(*v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function '.sub'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator- of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__sub01 +static int tolua_AllToLua_Vector3f__sub01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->operator-(v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f__sub00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator* of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__mul00 +static int tolua_AllToLua_Vector3f__mul00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const float f = ((const float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->operator*(f); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function '.mul'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator* of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3f__mul01 +static int tolua_AllToLua_Vector3f__mul01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3f",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3f* self = (const Vector3f*) tolua_tousertype(tolua_S,1,0); + const Vector3f* v2 = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL); +#endif + { + Vector3f tolua_ret = (Vector3f) self->operator*(*v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3f)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3f)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3f"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3f__mul00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: x of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3f_x +static int tolua_get_Vector3f_x(lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->x); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: x of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3f_x +static int tolua_set_Vector3f_x(lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->x = ((float) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: y of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3f_y +static int tolua_get_Vector3f_y(lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->y); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: y of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3f_y +static int tolua_set_Vector3f_y(lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->y = ((float) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: z of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3f_z +static int tolua_get_Vector3f_z(lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->z); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: z of class Vector3f */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3f_z +static int tolua_set_Vector3f_z(lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->z = ((float) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new00 +static int tolua_AllToLua_Vector3d_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new00_local +static int tolua_AllToLua_Vector3d_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new01 +static int tolua_AllToLua_Vector3d_new01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d_new00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new01_local +static int tolua_AllToLua_Vector3d_new01_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3f* v = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d_new00_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new02 +static int tolua_AllToLua_Vector3d_new02(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + { + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d_new01(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new02_local +static int tolua_AllToLua_Vector3d_new02_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + { + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d_new01_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new03 +static int tolua_AllToLua_Vector3d_new03(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + double a_x = ((double) tolua_tonumber(tolua_S,2,0)); + double a_y = ((double) tolua_tonumber(tolua_S,3,0)); + double a_z = ((double) tolua_tonumber(tolua_S,4,0)); + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(a_x,a_y,a_z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d_new02(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new03_local +static int tolua_AllToLua_Vector3d_new03_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + double a_x = ((double) tolua_tonumber(tolua_S,2,0)); + double a_y = ((double) tolua_tonumber(tolua_S,3,0)); + double a_z = ((double) tolua_tonumber(tolua_S,4,0)); + { + Vector3d* tolua_ret = (Vector3d*) Mtolua_new((Vector3d)(a_x,a_y,a_z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d_new02_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Set of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Set00 +static int tolua_AllToLua_Vector3d_Set00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); + double a_x = ((double) tolua_tonumber(tolua_S,2,0)); + double a_y = ((double) tolua_tonumber(tolua_S,3,0)); + double a_z = ((double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); +#endif + { + self->Set(a_x,a_y,a_z); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Normalize of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Normalize00 +static int tolua_AllToLua_Vector3d_Normalize00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Normalize'", NULL); +#endif + { + self->Normalize(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Normalize'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NormalizeCopy of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_NormalizeCopy00 +static int tolua_AllToLua_Vector3d_NormalizeCopy00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->NormalizeCopy(); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'NormalizeCopy'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: NormalizeCopy of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_NormalizeCopy01 +static int tolua_AllToLua_Vector3d_NormalizeCopy01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); + Vector3d* a_V = ((Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'NormalizeCopy'", NULL); +#endif + { + self->NormalizeCopy(*a_V); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_Vector3d_NormalizeCopy00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Length of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Length00 +static int tolua_AllToLua_Vector3d_Length00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Length'", NULL); +#endif + { + double tolua_ret = (double) self->Length(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Length'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SqrLength of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_SqrLength00 +static int tolua_AllToLua_Vector3d_SqrLength00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SqrLength'", NULL); +#endif + { + double tolua_ret = (double) self->SqrLength(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SqrLength'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Dot of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Dot00 +static int tolua_AllToLua_Vector3d_Dot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_V = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dot'", NULL); +#endif + { + double tolua_ret = (double) self->Dot(*a_V); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Dot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Cross of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Cross00 +static int tolua_AllToLua_Vector3d_Cross00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Cross'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->Cross(*v); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Cross'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Equals of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Equals00 +static int tolua_AllToLua_Vector3d_Equals00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); +#endif + { + bool tolua_ret = (bool) self->Equals(*v); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator+ of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__add00 +static int tolua_AllToLua_Vector3d__add00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->operator+(*v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function '.add'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator+ of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__add01 +static int tolua_AllToLua_Vector3d__add01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator+'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->operator+(v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d__add00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator- of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__sub00 +static int tolua_AllToLua_Vector3d__sub00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->operator-(*v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function '.sub'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator- of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__sub01 +static int tolua_AllToLua_Vector3d__sub01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator-'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->operator-(v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d__sub00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator* of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__mul00 +static int tolua_AllToLua_Vector3d__mul00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const double f = ((const double) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->operator*(f); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function '.mul'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: operator* of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d__mul01 +static int tolua_AllToLua_Vector3d__mul01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v2 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'operator*'", NULL); +#endif + { + Vector3d tolua_ret = (Vector3d) self->operator*(*v2); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((Vector3d)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(Vector3d)); + tolua_pushusertype(tolua_S,tolua_obj,"Vector3d"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3d__mul00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: x of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3d_x +static int tolua_get_Vector3d_x(lua_State* tolua_S) +{ + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->x); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: x of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3d_x +static int tolua_set_Vector3d_x(lua_State* tolua_S) +{ + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->x = ((double) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: y of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3d_y +static int tolua_get_Vector3d_y(lua_State* tolua_S) +{ + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->y); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: y of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3d_y +static int tolua_set_Vector3d_y(lua_State* tolua_S) +{ + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->y = ((double) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: z of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3d_z +static int tolua_get_Vector3d_z(lua_State* tolua_S) +{ + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->z); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: z of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3d_z +static int tolua_set_Vector3d_z(lua_State* tolua_S) +{ + Vector3d* self = (Vector3d*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->z = ((double) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new00 +static int tolua_AllToLua_Vector3i_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + { + Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new00_local +static int tolua_AllToLua_Vector3i_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + { + Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(*v)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new01 +static int tolua_AllToLua_Vector3i_new01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + { + { + Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3i_new00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new01_local +static int tolua_AllToLua_Vector3i_new01_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else + { + { + Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3i_new00_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new02 +static int tolua_AllToLua_Vector3i_new02(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + int a_x = ((int) tolua_tonumber(tolua_S,2,0)); + int a_y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_z = ((int) tolua_tonumber(tolua_S,4,0)); + { + Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(a_x,a_y,a_z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3i_new01(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new02_local +static int tolua_AllToLua_Vector3i_new02_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Vector3i",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + int a_x = ((int) tolua_tonumber(tolua_S,2,0)); + int a_y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_z = ((int) tolua_tonumber(tolua_S,4,0)); + { + Vector3i* tolua_ret = (Vector3i*) Mtolua_new((Vector3i)(a_x,a_y,a_z)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Vector3i"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3i_new01_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Set of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Set00 +static int tolua_AllToLua_Vector3i_Set00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Vector3i",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); + int a_x = ((int) tolua_tonumber(tolua_S,2,0)); + int a_y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); +#endif + { + self->Set(a_x,a_y,a_z); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Length of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Length00 +static int tolua_AllToLua_Vector3i_Length00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Length'", NULL); +#endif + { + float tolua_ret = (float) self->Length(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Length'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SqrLength of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_SqrLength00 +static int tolua_AllToLua_Vector3i_SqrLength00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SqrLength'", NULL); +#endif + { + int tolua_ret = (int) self->SqrLength(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SqrLength'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Equals of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Equals00 +static int tolua_AllToLua_Vector3i_Equals00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0); + const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); +#endif + { + bool tolua_ret = (bool) self->Equals(*v); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Equals'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Equals of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_Equals01 +static int tolua_AllToLua_Vector3i_Equals01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3i",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3i* self = (const Vector3i*) tolua_tousertype(tolua_S,1,0); + const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Equals'", NULL); +#endif + { + bool tolua_ret = (bool) self->Equals(v); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_Vector3i_Equals00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: x of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3i_x +static int tolua_get_Vector3i_x(lua_State* tolua_S) +{ + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->x); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: x of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3i_x +static int tolua_set_Vector3i_x(lua_State* tolua_S) +{ + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'x'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->x = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: y of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3i_y +static int tolua_get_Vector3i_y(lua_State* tolua_S) +{ + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->y); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: y of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3i_y +static int tolua_set_Vector3i_y(lua_State* tolua_S) +{ + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'y'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->y = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: z of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3i_z +static int tolua_get_Vector3i_z(lua_State* tolua_S) +{ + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->z); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: z of class Vector3i */ +#ifndef TOLUA_DISABLE_tolua_set_Vector3i_z +static int tolua_set_Vector3i_z(lua_State* tolua_S) +{ + Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'z'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->z = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new00 +static int tolua_AllToLua_cCuboid_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new00_local +static int tolua_AllToLua_cCuboid_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new01 +static int tolua_AllToLua_cCuboid_new01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cCuboid",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const cCuboid* a_Cuboid = ((const cCuboid*) tolua_tousertype(tolua_S,2,0)); + { + cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_Cuboid)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cCuboid_new00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new01_local +static int tolua_AllToLua_cCuboid_new01_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cCuboid",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const cCuboid* a_Cuboid = ((const cCuboid*) tolua_tousertype(tolua_S,2,0)); + { + cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_Cuboid)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cCuboid_new00_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new02 +static int tolua_AllToLua_cCuboid_new02(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3i* a_p1 = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); + const Vector3i* a_p2 = ((const Vector3i*) tolua_tousertype(tolua_S,3,0)); + { + cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_p1,*a_p2)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cCuboid_new01(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_new02_local +static int tolua_AllToLua_cCuboid_new02_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCuboid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3i* a_p1 = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); + const Vector3i* a_p2 = ((const Vector3i*) tolua_tousertype(tolua_S,3,0)); + { + cCuboid* tolua_ret = (cCuboid*) Mtolua_new((cCuboid)(*a_p1,*a_p2)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCuboid"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cCuboid_new01_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: p1 of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_get_cCuboid_p1 +static int tolua_get_cCuboid_p1(lua_State* tolua_S) +{ + cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p1'",NULL); +#endif + tolua_pushusertype(tolua_S,(void*)&self->p1,"Vector3i"); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: p1 of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_set_cCuboid_p1 +static int tolua_set_cCuboid_p1(lua_State* tolua_S) +{ + cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p1'",NULL); + if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3i",0,&tolua_err))) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->p1 = *((Vector3i*) tolua_tousertype(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: p2 of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_get_cCuboid_p2 +static int tolua_get_cCuboid_p2(lua_State* tolua_S) +{ + cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p2'",NULL); +#endif + tolua_pushusertype(tolua_S,(void*)&self->p2,"Vector3i"); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: p2 of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_set_cCuboid_p2 +static int tolua_set_cCuboid_p2(lua_State* tolua_S) +{ + cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'p2'",NULL); + if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3i",0,&tolua_err))) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->p2 = *((Vector3i*) tolua_tousertype(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Sort of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_Sort00 +static int tolua_AllToLua_cCuboid_Sort00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCuboid",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCuboid* self = (cCuboid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Sort'", NULL); +#endif + { + self->Sort(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Sort'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsInside of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_IsInside00 +static int tolua_AllToLua_cCuboid_IsInside00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCuboid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3i",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCuboid* self = (const cCuboid*) tolua_tousertype(tolua_S,1,0); + const Vector3i* v = ((const Vector3i*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInside'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsInside(*v); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsInside'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsInside of class cCuboid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCuboid_IsInside01 +static int tolua_AllToLua_cCuboid_IsInside01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCuboid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const cCuboid* self = (const cCuboid*) tolua_tousertype(tolua_S,1,0); + const Vector3d* v = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInside'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsInside(*v); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cCuboid_IsInside00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cMCLogger */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_new00 +static int tolua_AllToLua_cMCLogger_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cMCLogger",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + char* a_File = ((char*) tolua_tostring(tolua_S,2,0)); + { + cMCLogger* tolua_ret = (cMCLogger*) Mtolua_new((cMCLogger)(a_File)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cMCLogger"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cMCLogger */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_new00_local +static int tolua_AllToLua_cMCLogger_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cMCLogger",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + char* a_File = ((char*) tolua_tostring(tolua_S,2,0)); + { + cMCLogger* tolua_ret = (cMCLogger*) Mtolua_new((cMCLogger)(a_File)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cMCLogger"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cMCLogger */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_delete00 +static int tolua_AllToLua_cMCLogger_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cMCLogger",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cMCLogger* self = (cMCLogger*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: LogSimple of class cMCLogger */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cMCLogger_LogSimple00 +static int tolua_AllToLua_cMCLogger_LogSimple00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cMCLogger",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,1,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cMCLogger* self = (cMCLogger*) tolua_tousertype(tolua_S,1,0); + const char* a_Text = ((const char*) tolua_tostring(tolua_S,2,0)); + int a_LogType = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'LogSimple'", NULL); +#endif + { + self->LogSimple(a_Text,a_LogType); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'LogSimple'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_new00 +static int tolua_AllToLua_cTracer_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cTracer",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); + { + cTracer* tolua_ret = (cTracer*) Mtolua_new((cTracer)(a_World)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cTracer"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_new00_local +static int tolua_AllToLua_cTracer_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cTracer",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); + { + cTracer* tolua_ret = (cTracer*) Mtolua_new((cTracer)(a_World)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cTracer"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: delete of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_delete00 +static int tolua_AllToLua_cTracer_delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTracer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'delete'", NULL); +#endif + Mtolua_delete(self); + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Trace of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_Trace00 +static int tolua_AllToLua_cTracer_Trace00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTracer",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3f",0,&tolua_err)) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); + const Vector3f* a_Start = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); + const Vector3f* a_Direction = ((const Vector3f*) tolua_tousertype(tolua_S,3,0)); + int a_Distance = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Trace'", NULL); +#endif + { + int tolua_ret = (int) self->Trace(*a_Start,*a_Direction,a_Distance); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Trace'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetValues of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_SetValues00 +static int tolua_AllToLua_cTracer_SetValues00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cTracer",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3f",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3f",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); + const Vector3f* a_Start = ((const Vector3f*) tolua_tousertype(tolua_S,2,0)); + const Vector3f* a_Direction = ((const Vector3f*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetValues'", NULL); +#endif + { + self->SetValues(*a_Start,*a_Direction); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetValues'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: BlockHitPosition of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_get_cTracer_BlockHitPosition +static int tolua_get_cTracer_BlockHitPosition(lua_State* tolua_S) +{ + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'BlockHitPosition'",NULL); +#endif + tolua_pushusertype(tolua_S,(void*)&self->BlockHitPosition,"Vector3f"); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: BlockHitPosition of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_set_cTracer_BlockHitPosition +static int tolua_set_cTracer_BlockHitPosition(lua_State* tolua_S) +{ + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'BlockHitPosition'",NULL); + if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err))) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->BlockHitPosition = *((Vector3f*) tolua_tousertype(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: HitNormal of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_get_cTracer_HitNormal +static int tolua_get_cTracer_HitNormal(lua_State* tolua_S) +{ + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'HitNormal'",NULL); +#endif + tolua_pushusertype(tolua_S,(void*)&self->HitNormal,"Vector3f"); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: HitNormal of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_set_cTracer_HitNormal +static int tolua_set_cTracer_HitNormal(lua_State* tolua_S) +{ + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'HitNormal'",NULL); + if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err))) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->HitNormal = *((Vector3f*) tolua_tousertype(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: RealHit of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_get_cTracer_RealHit +static int tolua_get_cTracer_RealHit(lua_State* tolua_S) +{ + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'RealHit'",NULL); +#endif + tolua_pushusertype(tolua_S,(void*)&self->RealHit,"Vector3f"); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: RealHit of class cTracer */ +#ifndef TOLUA_DISABLE_tolua_set_cTracer_RealHit +static int tolua_set_cTracer_RealHit(lua_State* tolua_S) +{ + cTracer* self = (cTracer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'RealHit'",NULL); + if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3f",0,&tolua_err))) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->RealHit = *((Vector3f*) tolua_tousertype(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetName of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_SetName00 +static int tolua_AllToLua_cGroup_SetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); + std::string a_Name = ((std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL); +#endif + { + self->SetName(a_Name); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetName of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_GetName00 +static int tolua_AllToLua_cGroup_GetName00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cGroup",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cGroup* self = (const cGroup*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL); +#endif + { + const std::string tolua_ret = (const std::string) self->GetName(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetName'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetColor of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_SetColor00 +static int tolua_AllToLua_cGroup_SetColor00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); + std::string a_Color = ((std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetColor'", NULL); +#endif + { + self->SetColor(a_Color); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetColor'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddCommand of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_AddCommand00 +static int tolua_AllToLua_cGroup_AddCommand00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); + std::string a_Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddCommand'", NULL); +#endif + { + self->AddCommand(a_Command); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddCommand'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: AddPermission of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_AddPermission00 +static int tolua_AllToLua_cGroup_AddPermission00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); + std::string a_Permission = ((std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddPermission'", NULL); +#endif + { + self->AddPermission(a_Permission); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'AddPermission'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: InheritFrom of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_InheritFrom00 +static int tolua_AllToLua_cGroup_InheritFrom00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cGroup",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); + cGroup* a_Group = ((cGroup*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'InheritFrom'", NULL); +#endif + { + self->InheritFrom(a_Group); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'InheritFrom'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HasCommand of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_HasCommand00 +static int tolua_AllToLua_cGroup_HasCommand00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cGroup",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cGroup* self = (cGroup*) tolua_tousertype(tolua_S,1,0); + std::string a_Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasCommand'", NULL); +#endif + { + bool tolua_ret = (bool) self->HasCommand(a_Command); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'HasCommand'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetColor of class cGroup */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cGroup_GetColor00 +static int tolua_AllToLua_cGroup_GetColor00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cGroup",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cGroup* self = (const cGroup*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetColor'", NULL); +#endif + { + const AString tolua_ret = (const AString) self->GetColor(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetColor'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_ProtocolVersion of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_ProtocolVersion +static int tolua_get_cPacket_Login_m_ProtocolVersion(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ProtocolVersion'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_ProtocolVersion); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_ProtocolVersion of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_ProtocolVersion +static int tolua_set_cPacket_Login_m_ProtocolVersion(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ProtocolVersion'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_ProtocolVersion = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_Username of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_Username +static int tolua_get_cPacket_Login_m_Username(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Username'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->m_Username); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_Username of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_Username +static int tolua_set_cPacket_Login_m_Username(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Username'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_Username = ((AString) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_LevelType of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_LevelType +static int tolua_get_cPacket_Login_m_LevelType(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_LevelType'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->m_LevelType); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_LevelType of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_LevelType +static int tolua_set_cPacket_Login_m_LevelType(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_LevelType'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_LevelType = ((AString) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_ServerMode of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_ServerMode +static int tolua_get_cPacket_Login_m_ServerMode(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ServerMode'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_ServerMode); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_ServerMode of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_ServerMode +static int tolua_set_cPacket_Login_m_ServerMode(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ServerMode'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_ServerMode = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_Difficulty of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_m_Difficulty +static int tolua_get_cPacket_Login_m_Difficulty(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Difficulty'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_Difficulty); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_Difficulty of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_m_Difficulty +static int tolua_set_cPacket_Login_m_Difficulty(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Difficulty'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_Difficulty = ((char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_WorldHeight of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_unsigned_m_WorldHeight +static int tolua_get_cPacket_Login_unsigned_m_WorldHeight(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_WorldHeight'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_WorldHeight); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_WorldHeight of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_unsigned_m_WorldHeight +static int tolua_set_cPacket_Login_unsigned_m_WorldHeight(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_WorldHeight'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_WorldHeight = ((unsigned char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_MaxPlayers of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_Login_unsigned_m_MaxPlayers +static int tolua_get_cPacket_Login_unsigned_m_MaxPlayers(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_MaxPlayers'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_MaxPlayers); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_MaxPlayers of class cPacket_Login */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_Login_unsigned_m_MaxPlayers +static int tolua_set_cPacket_Login_unsigned_m_MaxPlayers(lua_State* tolua_S) +{ + cPacket_Login* self = (cPacket_Login*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_MaxPlayers'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_MaxPlayers = ((unsigned char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPacket_BlockDig_new00 +static int tolua_AllToLua_cPacket_BlockDig_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cPacket_BlockDig",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + cPacket_BlockDig* tolua_ret = (cPacket_BlockDig*) Mtolua_new((cPacket_BlockDig)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket_BlockDig"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPacket_BlockDig_new00_local +static int tolua_AllToLua_cPacket_BlockDig_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cPacket_BlockDig",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + cPacket_BlockDig* tolua_ret = (cPacket_BlockDig*) Mtolua_new((cPacket_BlockDig)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket_BlockDig"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Clone of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPacket_BlockDig_Clone00 +static int tolua_AllToLua_cPacket_BlockDig_Clone00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPacket_BlockDig",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPacket_BlockDig* self = (const cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clone'", NULL); +#endif + { + cPacket* tolua_ret = (cPacket*) self->Clone(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Clone'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_Status of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_Status +static int tolua_get_cPacket_BlockDig_m_Status(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Status'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_Status); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_Status of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_Status +static int tolua_set_cPacket_BlockDig_m_Status(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Status'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_Status = ((char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_PosX of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_PosX +static int tolua_get_cPacket_BlockDig_m_PosX(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_PosX); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_PosX of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_PosX +static int tolua_set_cPacket_BlockDig_m_PosX(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_PosX = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_PosY of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_PosY +static int tolua_get_cPacket_BlockDig_m_PosY(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_PosY); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_PosY of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_PosY +static int tolua_set_cPacket_BlockDig_m_PosY(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_PosY = ((char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_PosZ of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_PosZ +static int tolua_get_cPacket_BlockDig_m_PosZ(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_PosZ); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_PosZ of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_PosZ +static int tolua_set_cPacket_BlockDig_m_PosZ(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_PosZ = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_Direction of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockDig_m_Direction +static int tolua_get_cPacket_BlockDig_m_Direction(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_Direction); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_Direction of class cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockDig_m_Direction +static int tolua_set_cPacket_BlockDig_m_Direction(lua_State* tolua_S) +{ + cPacket_BlockDig* self = (cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_Direction = ((char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + + class Lua__cPacket_BlockDig : public cPacket_BlockDig, public ToluaBase { +public: + cPacket* Clone( void )const { + if (push_method("Clone", tolua_AllToLua_cPacket_BlockDig_Clone00)) { + ToluaBase::dbcall(lua_state, 1, 1); + cPacket* tolua_ret = ( cPacket* )tolua_tousertype(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + return ( cPacket* ) cPacket_BlockDig:: Clone(); + }; + }; + + cPacket* cPacket_BlockDig__Clone( void ) { + return ( cPacket* )cPacket_BlockDig::Clone(); + }; + Lua__cPacket_BlockDig( void ): cPacket_BlockDig(){}; +}; + +/* method: tolua__set_instance of class Lua__cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_tolua__set_instance00 +static int tolua_AllToLua_Lua__cPacket_BlockDig_tolua__set_instance00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPacket_BlockDig* self = (Lua__cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); + lua_State* L = tolua_S; + lua_Object lo = ((lua_Object) tolua_tovalue(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'tolua__set_instance'", NULL); +#endif + { + self->tolua__set_instance(L,lo); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'tolua__set_instance'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: cPacket_BlockDig__Clone of class Lua__cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_cPacket_BlockDig__Clone00 +static int tolua_AllToLua_Lua__cPacket_BlockDig_cPacket_BlockDig__Clone00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + Lua__cPacket_BlockDig* self = (Lua__cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPacket_BlockDig__Clone'", NULL); +#endif + { + cPacket* tolua_ret = (cPacket*) self->cPacket_BlockDig__Clone(); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPacket"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'cPacket_BlockDig__Clone'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class Lua__cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_new00 +static int tolua_AllToLua_Lua__cPacket_BlockDig_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + Lua__cPacket_BlockDig* tolua_ret = (Lua__cPacket_BlockDig*) Mtolua_new((Lua__cPacket_BlockDig)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPacket_BlockDig"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class Lua__cPacket_BlockDig */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPacket_BlockDig_new00_local +static int tolua_AllToLua_Lua__cPacket_BlockDig_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"Lua__cPacket_BlockDig",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + Lua__cPacket_BlockDig* tolua_ret = (Lua__cPacket_BlockDig*) Mtolua_new((Lua__cPacket_BlockDig)()); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"Lua__cPacket_BlockDig"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + + +/* function to release collected object via destructor */ +#ifdef __cplusplus + +static int tolua_collect_Lua__cPacket_BlockDig (lua_State* tolua_S) +{ + Lua__cPacket_BlockDig* self = (Lua__cPacket_BlockDig*) tolua_tousertype(tolua_S,1,0); + delete self; + return 0; +} +#endif + +/* get function: m_PosX of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_PosX +static int tolua_get_cPacket_BlockPlace_m_PosX(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_PosX); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_PosX of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_PosX +static int tolua_set_cPacket_BlockPlace_m_PosX(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosX'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_PosX = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_PosY of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_unsigned_m_PosY +static int tolua_get_cPacket_BlockPlace_unsigned_m_PosY(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_PosY); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_PosY of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_unsigned_m_PosY +static int tolua_set_cPacket_BlockPlace_unsigned_m_PosY(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosY'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_PosY = ((unsigned char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_PosZ of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_PosZ +static int tolua_get_cPacket_BlockPlace_m_PosZ(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_PosZ); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_PosZ of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_PosZ +static int tolua_set_cPacket_BlockPlace_m_PosZ(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PosZ'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_PosZ = ((int) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_Direction of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_Direction +static int tolua_get_cPacket_BlockPlace_m_Direction(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_Direction); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_Direction of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_Direction +static int tolua_set_cPacket_BlockPlace_m_Direction(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Direction'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_Direction = ((char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_ItemType of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_ItemType +static int tolua_get_cPacket_BlockPlace_m_ItemType(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemType'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_ItemType); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_ItemType of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_ItemType +static int tolua_set_cPacket_BlockPlace_m_ItemType(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_ItemType'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_ItemType = ((short) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_Count of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_Count +static int tolua_get_cPacket_BlockPlace_m_Count(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Count'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_Count); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_Count of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_Count +static int tolua_set_cPacket_BlockPlace_m_Count(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Count'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_Count = ((char) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: m_Uses of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_get_cPacket_BlockPlace_m_Uses +static int tolua_get_cPacket_BlockPlace_m_Uses(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Uses'",NULL); +#endif + tolua_pushnumber(tolua_S,(lua_Number)self->m_Uses); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: m_Uses of class cPacket_BlockPlace */ +#ifndef TOLUA_DISABLE_tolua_set_cPacket_BlockPlace_m_Uses +static int tolua_set_cPacket_BlockPlace_m_Uses(lua_State* tolua_S) +{ + cPacket_BlockPlace* self = (cPacket_BlockPlace*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_Uses'",NULL); + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->m_Uses = ((short) tolua_tonumber(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: FillBlocks of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_FillBlocks00 +static int tolua_AllToLua_cLuaChunk_FillBlocks00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + char a_BlockID = ((char) tolua_tonumber(tolua_S,2,0)); + unsigned char a_BlockMeta = ((unsigned char) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'FillBlocks'", NULL); +#endif + { + self->FillBlocks(a_BlockID,a_BlockMeta); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'FillBlocks'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetBlock of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetBlock00 +static int tolua_AllToLua_cLuaChunk_SetBlock00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); + char a_BlockID = ((char) tolua_tonumber(tolua_S,5,0)); + unsigned char a_BlockMeta = ((unsigned char) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlock'", NULL); +#endif + { + self->SetBlock(a_X,a_Y,a_Z,a_BlockID,a_BlockMeta); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetBlock'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlock of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetBlock00 +static int tolua_AllToLua_cLuaChunk_GetBlock00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlock'", NULL); +#endif + { + char tolua_ret = (char) self->GetBlock(a_X,a_Y,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlock'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlockMeta of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetBlockMeta00 +static int tolua_AllToLua_cLuaChunk_GetBlockMeta00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockMeta'", NULL); +#endif + { + char tolua_ret = (char) self->GetBlockMeta(a_X,a_Y,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlockMeta'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetBiome of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetBiome00 +static int tolua_AllToLua_cLuaChunk_SetBiome00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BiomeID = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBiome'", NULL); +#endif + { + self->SetBiome(a_X,a_Z,a_BiomeID); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetBiome'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBiome of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetBiome00 +static int tolua_AllToLua_cLuaChunk_GetBiome00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBiome'", NULL); +#endif + { + int tolua_ret = (int) self->GetBiome(a_X,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBiome'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetHeight of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetHeight00 +static int tolua_AllToLua_cLuaChunk_SetHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); + int a_Height = ((int) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetHeight'", NULL); +#endif + { + self->SetHeight(a_X,a_Z,a_Height); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetHeight of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_GetHeight00 +static int tolua_AllToLua_cLuaChunk_GetHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Z = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHeight'", NULL); +#endif + { + int tolua_ret = (int) self->GetHeight(a_X,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetUseDefaultBiomes of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultBiomes00 +static int tolua_AllToLua_cLuaChunk_SetUseDefaultBiomes00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + bool a_bUseDefaultBiomes = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultBiomes'", NULL); +#endif + { + self->SetUseDefaultBiomes(a_bUseDefaultBiomes); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetUseDefaultBiomes'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsUsingDefaultBiomes of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultBiomes00 +static int tolua_AllToLua_cLuaChunk_IsUsingDefaultBiomes00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultBiomes'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsUsingDefaultBiomes(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultBiomes'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetUseDefaultComposition of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultComposition00 +static int tolua_AllToLua_cLuaChunk_SetUseDefaultComposition00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + bool a_bUseDefaultComposition = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultComposition'", NULL); +#endif + { + self->SetUseDefaultComposition(a_bUseDefaultComposition); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetUseDefaultComposition'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsUsingDefaultComposition of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultComposition00 +static int tolua_AllToLua_cLuaChunk_IsUsingDefaultComposition00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultComposition'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsUsingDefaultComposition(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultComposition'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetUseDefaultStructures of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultStructures00 +static int tolua_AllToLua_cLuaChunk_SetUseDefaultStructures00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + bool a_bUseDefaultStructures = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultStructures'", NULL); +#endif + { + self->SetUseDefaultStructures(a_bUseDefaultStructures); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetUseDefaultStructures'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsUsingDefaultStructures of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultStructures00 +static int tolua_AllToLua_cLuaChunk_IsUsingDefaultStructures00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultStructures'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsUsingDefaultStructures(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultStructures'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetUseDefaultFinish of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_SetUseDefaultFinish00 +static int tolua_AllToLua_cLuaChunk_SetUseDefaultFinish00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); + bool a_bUseDefaultFinish = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetUseDefaultFinish'", NULL); +#endif + { + self->SetUseDefaultFinish(a_bUseDefaultFinish); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetUseDefaultFinish'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsUsingDefaultFinish of class cLuaChunk */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_IsUsingDefaultFinish00 +static int tolua_AllToLua_cLuaChunk_IsUsingDefaultFinish00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaChunk",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaChunk* self = (cLuaChunk*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsUsingDefaultFinish'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsUsingDefaultFinish(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsUsingDefaultFinish'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_new00 +static int tolua_AllToLua_cCraftingGrid_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCraftingGrid",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_Width = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Height = ((int) tolua_tonumber(tolua_S,3,0)); + { + cCraftingGrid* tolua_ret = (cCraftingGrid*) Mtolua_new((cCraftingGrid)(a_Width,a_Height)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCraftingGrid"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_new00_local +static int tolua_AllToLua_cCraftingGrid_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cCraftingGrid",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + int a_Width = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Height = ((int) tolua_tonumber(tolua_S,3,0)); + { + cCraftingGrid* tolua_ret = (cCraftingGrid*) Mtolua_new((cCraftingGrid)(a_Width,a_Height)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cCraftingGrid"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetWidth of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_GetWidth00 +static int tolua_AllToLua_cCraftingGrid_GetWidth00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCraftingGrid",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCraftingGrid* self = (const cCraftingGrid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWidth'", NULL); +#endif + { + int tolua_ret = (int) self->GetWidth(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWidth'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetHeight of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_GetHeight00 +static int tolua_AllToLua_cCraftingGrid_GetHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCraftingGrid",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCraftingGrid* self = (const cCraftingGrid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHeight'", NULL); +#endif + { + int tolua_ret = (int) self->GetHeight(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetItem of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_GetItem00 +static int tolua_AllToLua_cCraftingGrid_GetItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCraftingGrid",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCraftingGrid* self = (const cCraftingGrid*) tolua_tousertype(tolua_S,1,0); + int x = ((int) tolua_tonumber(tolua_S,2,0)); + int y = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetItem'", NULL); +#endif + { + cItem& tolua_ret = (cItem&) self->GetItem(x,y); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetItem of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_SetItem00 +static int tolua_AllToLua_cCraftingGrid_SetItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); + int x = ((int) tolua_tonumber(tolua_S,2,0)); + int y = ((int) tolua_tonumber(tolua_S,3,0)); + ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,4,0)); + int a_ItemCount = ((int) tolua_tonumber(tolua_S,5,0)); + short a_ItemHealth = ((short) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetItem'", NULL); +#endif + { + self->SetItem(x,y,a_ItemType,a_ItemCount,a_ItemHealth); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetItem of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_SetItem01 +static int tolua_AllToLua_cCraftingGrid_SetItem01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,4,&tolua_err) || !tolua_isusertype(tolua_S,4,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); + int x = ((int) tolua_tonumber(tolua_S,2,0)); + int y = ((int) tolua_tonumber(tolua_S,3,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetItem'", NULL); +#endif + { + self->SetItem(x,y,*a_Item); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cCraftingGrid_SetItem00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Clear of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_Clear00 +static int tolua_AllToLua_cCraftingGrid_Clear00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); +#endif + { + self->Clear(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ConsumeGrid of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_ConsumeGrid00 +static int tolua_AllToLua_cCraftingGrid_ConsumeGrid00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cCraftingGrid",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); + const cCraftingGrid* a_Grid = ((const cCraftingGrid*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ConsumeGrid'", NULL); +#endif + { + self->ConsumeGrid(*a_Grid); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ConsumeGrid'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Dump of class cCraftingGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_Dump00 +static int tolua_AllToLua_cCraftingGrid_Dump00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingGrid",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingGrid* self = (cCraftingGrid*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dump'", NULL); +#endif + { + self->Dump(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Dump'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Clear of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_Clear00 +static int tolua_AllToLua_cCraftingRecipe_Clear00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); +#endif + { + self->Clear(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetIngredientsWidth of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetIngredientsWidth00 +static int tolua_AllToLua_cCraftingRecipe_GetIngredientsWidth00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIngredientsWidth'", NULL); +#endif + { + int tolua_ret = (int) self->GetIngredientsWidth(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetIngredientsWidth'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetIngredientsHeight of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetIngredientsHeight00 +static int tolua_AllToLua_cCraftingRecipe_GetIngredientsHeight00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIngredientsHeight'", NULL); +#endif + { + int tolua_ret = (int) self->GetIngredientsHeight(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetIngredientsHeight'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetIngredient of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetIngredient00 +static int tolua_AllToLua_cCraftingRecipe_GetIngredient00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); + int x = ((int) tolua_tonumber(tolua_S,2,0)); + int y = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIngredient'", NULL); +#endif + { + cItem& tolua_ret = (cItem&) self->GetIngredient(x,y); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetIngredient'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetResult of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_GetResult00 +static int tolua_AllToLua_cCraftingRecipe_GetResult00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cCraftingRecipe* self = (const cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetResult'", NULL); +#endif + { + const cItem& tolua_ret = (const cItem&) self->GetResult(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetResult'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetResult of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetResult00 +static int tolua_AllToLua_cCraftingRecipe_SetResult00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); + ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0)); + int a_ItemCount = ((int) tolua_tonumber(tolua_S,3,0)); + short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetResult'", NULL); +#endif + { + self->SetResult(a_ItemType,a_ItemCount,a_ItemHealth); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetResult'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetResult of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetResult01 +static int tolua_AllToLua_cCraftingRecipe_SetResult01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetResult'", NULL); +#endif + { + self->SetResult(*a_Item); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cCraftingRecipe_SetResult00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetIngredient of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetIngredient00 +static int tolua_AllToLua_cCraftingRecipe_SetIngredient00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); + int x = ((int) tolua_tonumber(tolua_S,2,0)); + int y = ((int) tolua_tonumber(tolua_S,3,0)); + ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,4,0)); + int a_ItemCount = ((int) tolua_tonumber(tolua_S,5,0)); + short a_ItemHealth = ((short) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetIngredient'", NULL); +#endif + { + self->SetIngredient(x,y,a_ItemType,a_ItemCount,a_ItemHealth); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetIngredient'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetIngredient of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_SetIngredient01 +static int tolua_AllToLua_cCraftingRecipe_SetIngredient01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,4,&tolua_err) || !tolua_isusertype(tolua_S,4,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); + int x = ((int) tolua_tonumber(tolua_S,2,0)); + int y = ((int) tolua_tonumber(tolua_S,3,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetIngredient'", NULL); +#endif + { + self->SetIngredient(x,y,*a_Item); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cCraftingRecipe_SetIngredient00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ConsumeIngredients of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_ConsumeIngredients00 +static int tolua_AllToLua_cCraftingRecipe_ConsumeIngredients00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cCraftingGrid",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); + cCraftingGrid* a_CraftingGrid = ((cCraftingGrid*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ConsumeIngredients'", NULL); +#endif + { + self->ConsumeIngredients(*a_CraftingGrid); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ConsumeIngredients'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Dump of class cCraftingRecipe */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingRecipe_Dump00 +static int tolua_AllToLua_cCraftingRecipe_Dump00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cCraftingRecipe",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cCraftingRecipe* self = (cCraftingRecipe*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Dump'", NULL); +#endif + { + self->Dump(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Dump'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Get of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Get00 +static int tolua_AllToLua_cLuaItems_Get00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); + int a_Idx = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Get'", NULL); +#endif + { + cItem& tolua_ret = (cItem&) self->Get(a_Idx); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Get'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Set of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Set00 +static int tolua_AllToLua_cLuaItems_Set00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); + int a_Idx = ((int) tolua_tonumber(tolua_S,2,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); +#endif + { + self->Set(a_Idx,*a_Item); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Set'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Add of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Add00 +static int tolua_AllToLua_cLuaItems_Add00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Add'", NULL); +#endif + { + self->Add(*a_Item); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Add'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Delete of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Delete00 +static int tolua_AllToLua_cLuaItems_Delete00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); + int a_Idx = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Delete'", NULL); +#endif + { + self->Delete(a_Idx); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Delete'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Clear of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Clear00 +static int tolua_AllToLua_cLuaItems_Clear00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); +#endif + { + self->Clear(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Size of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Size00 +static int tolua_AllToLua_cLuaItems_Size00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Size'", NULL); +#endif + { + int tolua_ret = (int) self->Size(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Size'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Add of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Add01 +static int tolua_AllToLua_cLuaItems_Add01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); + ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,2,0)); + char a_ItemCount = ((char) tolua_tonumber(tolua_S,3,0)); + short a_ItemHealth = ((short) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Add'", NULL); +#endif + { + self->Add(a_ItemType,a_ItemCount,a_ItemHealth); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cLuaItems_Add00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Set of class cLuaItems */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaItems_Set01 +static int tolua_AllToLua_cLuaItems_Set01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cLuaItems",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else + { + cLuaItems* self = (cLuaItems*) tolua_tousertype(tolua_S,1,0); + int a_Idx = ((int) tolua_tonumber(tolua_S,2,0)); + ENUM_ITEM_ID a_ItemType = ((ENUM_ITEM_ID) (int) tolua_tonumber(tolua_S,3,0)); + char a_ItemCount = ((char) tolua_tonumber(tolua_S,4,0)); + short a_ItemHealth = ((short) tolua_tonumber(tolua_S,5,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Set'", NULL); +#endif + { + self->Set(a_Idx,a_ItemType,a_ItemCount,a_ItemHealth); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cLuaItems_Set00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* Open function */ +TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) +{ + tolua_open(tolua_S); + tolua_reg_types(tolua_S); + tolua_module(tolua_S,NULL,1); + tolua_beginmodule(tolua_S,NULL); + tolua_cclass(tolua_S,"cTorch","cTorch","",NULL); + tolua_beginmodule(tolua_S,"cTorch"); + tolua_function(tolua_S,"DirectionToMetaData",tolua_AllToLua_cTorch_DirectionToMetaData00); + tolua_function(tolua_S,"MetaDataToDirection",tolua_AllToLua_cTorch_MetaDataToDirection00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cStairs","cStairs","",NULL); + tolua_beginmodule(tolua_S,"cStairs"); + tolua_function(tolua_S,"RotationToMetaData",tolua_AllToLua_cStairs_RotationToMetaData00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cStep","cStep","",NULL); + tolua_beginmodule(tolua_S,"cStep"); + tolua_function(tolua_S,"DirectionToMetaData",tolua_AllToLua_cStep_DirectionToMetaData00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cLadder","cLadder","",NULL); + tolua_beginmodule(tolua_S,"cLadder"); + tolua_function(tolua_S,"DirectionToMetaData",tolua_AllToLua_cLadder_DirectionToMetaData00); + tolua_function(tolua_S,"MetaDataToDirection",tolua_AllToLua_cLadder_MetaDataToDirection00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cIniFile","cIniFile","",tolua_collect_cIniFile); + #else + tolua_cclass(tolua_S,"cIniFile","cIniFile","",NULL); + #endif + tolua_beginmodule(tolua_S,"cIniFile"); + tolua_constant(tolua_S,"noID",cIniFile::noID); + tolua_function(tolua_S,"new",tolua_AllToLua_cIniFile_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cIniFile_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cIniFile_new00_local); + tolua_function(tolua_S,"CaseSensitive",tolua_AllToLua_cIniFile_CaseSensitive00); + tolua_function(tolua_S,"CaseInsensitive",tolua_AllToLua_cIniFile_CaseInsensitive00); + tolua_function(tolua_S,"Path",tolua_AllToLua_cIniFile_Path00); + tolua_function(tolua_S,"Path",tolua_AllToLua_cIniFile_Path01); + tolua_function(tolua_S,"SetPath",tolua_AllToLua_cIniFile_SetPath00); + tolua_function(tolua_S,"ReadFile",tolua_AllToLua_cIniFile_ReadFile00); + tolua_function(tolua_S,"WriteFile",tolua_AllToLua_cIniFile_WriteFile00); + tolua_function(tolua_S,"Erase",tolua_AllToLua_cIniFile_Erase00); + tolua_function(tolua_S,"Clear",tolua_AllToLua_cIniFile_Clear00); + tolua_function(tolua_S,"Reset",tolua_AllToLua_cIniFile_Reset00); + tolua_function(tolua_S,"FindKey",tolua_AllToLua_cIniFile_FindKey00); + tolua_function(tolua_S,"FindValue",tolua_AllToLua_cIniFile_FindValue00); + tolua_function(tolua_S,"NumKeys",tolua_AllToLua_cIniFile_NumKeys00); + tolua_function(tolua_S,"GetNumKeys",tolua_AllToLua_cIniFile_GetNumKeys00); + tolua_function(tolua_S,"AddKeyName",tolua_AllToLua_cIniFile_AddKeyName00); + tolua_function(tolua_S,"KeyName",tolua_AllToLua_cIniFile_KeyName00); + tolua_function(tolua_S,"GetKeyName",tolua_AllToLua_cIniFile_GetKeyName00); + tolua_function(tolua_S,"NumValues",tolua_AllToLua_cIniFile_NumValues00); + tolua_function(tolua_S,"GetNumValues",tolua_AllToLua_cIniFile_GetNumValues00); + tolua_function(tolua_S,"NumValues",tolua_AllToLua_cIniFile_NumValues01); + tolua_function(tolua_S,"GetNumValues",tolua_AllToLua_cIniFile_GetNumValues01); + tolua_function(tolua_S,"ValueName",tolua_AllToLua_cIniFile_ValueName00); + tolua_function(tolua_S,"GetValueName",tolua_AllToLua_cIniFile_GetValueName00); + tolua_function(tolua_S,"ValueName",tolua_AllToLua_cIniFile_ValueName01); + tolua_function(tolua_S,"GetValueName",tolua_AllToLua_cIniFile_GetValueName01); + tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue00); + tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue01); + tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue02); + tolua_function(tolua_S,"GetValue",tolua_AllToLua_cIniFile_GetValue03); + tolua_function(tolua_S,"GetValueF",tolua_AllToLua_cIniFile_GetValueF00); + tolua_function(tolua_S,"GetValueI",tolua_AllToLua_cIniFile_GetValueI00); + tolua_function(tolua_S,"GetValueB",tolua_AllToLua_cIniFile_GetValueB00); + tolua_function(tolua_S,"GetValueSet",tolua_AllToLua_cIniFile_GetValueSet00); + tolua_function(tolua_S,"GetValueSet",tolua_AllToLua_cIniFile_GetValueSet01); + tolua_function(tolua_S,"GetValueSetF",tolua_AllToLua_cIniFile_GetValueSetF00); + tolua_function(tolua_S,"GetValueSetI",tolua_AllToLua_cIniFile_GetValueSetI00); + tolua_function(tolua_S,"GetValueSetB",tolua_AllToLua_cIniFile_GetValueSetB00); + tolua_function(tolua_S,"SetValue",tolua_AllToLua_cIniFile_SetValue00); + tolua_function(tolua_S,"SetValue",tolua_AllToLua_cIniFile_SetValue01); + tolua_function(tolua_S,"SetValueI",tolua_AllToLua_cIniFile_SetValueI00); + tolua_function(tolua_S,"SetValueB",tolua_AllToLua_cIniFile_SetValueB00); + tolua_function(tolua_S,"SetValueF",tolua_AllToLua_cIniFile_SetValueF00); + tolua_function(tolua_S,"DeleteValueByID",tolua_AllToLua_cIniFile_DeleteValueByID00); + tolua_function(tolua_S,"DeleteValue",tolua_AllToLua_cIniFile_DeleteValue00); + tolua_function(tolua_S,"DeleteKey",tolua_AllToLua_cIniFile_DeleteKey00); + tolua_function(tolua_S,"NumHeaderComments",tolua_AllToLua_cIniFile_NumHeaderComments00); + tolua_function(tolua_S,"HeaderComment",tolua_AllToLua_cIniFile_HeaderComment00); + tolua_function(tolua_S,"HeaderComment",tolua_AllToLua_cIniFile_HeaderComment01); + tolua_function(tolua_S,"DeleteHeaderComment",tolua_AllToLua_cIniFile_DeleteHeaderComment00); + tolua_function(tolua_S,"DeleteHeaderComments",tolua_AllToLua_cIniFile_DeleteHeaderComments00); + tolua_function(tolua_S,"NumKeyComments",tolua_AllToLua_cIniFile_NumKeyComments00); + tolua_function(tolua_S,"NumKeyComments",tolua_AllToLua_cIniFile_NumKeyComments01); + tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment00); + tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment01); + tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment02); + tolua_function(tolua_S,"KeyComment",tolua_AllToLua_cIniFile_KeyComment03); + tolua_function(tolua_S,"DeleteKeyComment",tolua_AllToLua_cIniFile_DeleteKeyComment00); + tolua_function(tolua_S,"DeleteKeyComment",tolua_AllToLua_cIniFile_DeleteKeyComment01); + tolua_function(tolua_S,"DeleteKeyComments",tolua_AllToLua_cIniFile_DeleteKeyComments00); + tolua_function(tolua_S,"DeleteKeyComments",tolua_AllToLua_cIniFile_DeleteKeyComments01); + tolua_endmodule(tolua_S); + tolua_constant(tolua_S,"E_BLOCK_AIR",E_BLOCK_AIR); + tolua_constant(tolua_S,"E_BLOCK_STONE",E_BLOCK_STONE); + tolua_constant(tolua_S,"E_BLOCK_GRASS",E_BLOCK_GRASS); + tolua_constant(tolua_S,"E_BLOCK_DIRT",E_BLOCK_DIRT); + tolua_constant(tolua_S,"E_BLOCK_COBBLESTONE",E_BLOCK_COBBLESTONE); + tolua_constant(tolua_S,"E_BLOCK_PLANKS",E_BLOCK_PLANKS); + tolua_constant(tolua_S,"E_BLOCK_WOOD",E_BLOCK_WOOD); + tolua_constant(tolua_S,"E_BLOCK_SAPLING",E_BLOCK_SAPLING); + tolua_constant(tolua_S,"E_BLOCK_BEDROCK",E_BLOCK_BEDROCK); + tolua_constant(tolua_S,"E_BLOCK_WATER",E_BLOCK_WATER); + tolua_constant(tolua_S,"E_BLOCK_STATIONARY_WATER",E_BLOCK_STATIONARY_WATER); + tolua_constant(tolua_S,"E_BLOCK_LAVA",E_BLOCK_LAVA); + tolua_constant(tolua_S,"E_BLOCK_STATIONARY_LAVA",E_BLOCK_STATIONARY_LAVA); + tolua_constant(tolua_S,"E_BLOCK_SAND",E_BLOCK_SAND); + tolua_constant(tolua_S,"E_BLOCK_GRAVEL",E_BLOCK_GRAVEL); + tolua_constant(tolua_S,"E_BLOCK_GOLD_ORE",E_BLOCK_GOLD_ORE); + tolua_constant(tolua_S,"E_BLOCK_IRON_ORE",E_BLOCK_IRON_ORE); + tolua_constant(tolua_S,"E_BLOCK_COAL_ORE",E_BLOCK_COAL_ORE); + tolua_constant(tolua_S,"E_BLOCK_LOG",E_BLOCK_LOG); + tolua_constant(tolua_S,"E_BLOCK_LEAVES",E_BLOCK_LEAVES); + tolua_constant(tolua_S,"E_BLOCK_SPONGE",E_BLOCK_SPONGE); + tolua_constant(tolua_S,"E_BLOCK_GLASS",E_BLOCK_GLASS); + tolua_constant(tolua_S,"E_BLOCK_LAPIS_ORE",E_BLOCK_LAPIS_ORE); + tolua_constant(tolua_S,"E_BLOCK_LAPIS_BLOCK",E_BLOCK_LAPIS_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_DISPENSER",E_BLOCK_DISPENSER); + tolua_constant(tolua_S,"E_BLOCK_SANDSTONE",E_BLOCK_SANDSTONE); + tolua_constant(tolua_S,"E_BLOCK_NOTE_BLOCK",E_BLOCK_NOTE_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_BED",E_BLOCK_BED); + tolua_constant(tolua_S,"E_BLOCK_POWERED_RAIL",E_BLOCK_POWERED_RAIL); + tolua_constant(tolua_S,"E_BLOCK_DETECTOR_RAIL",E_BLOCK_DETECTOR_RAIL); + tolua_constant(tolua_S,"E_BLOCK_STICKY_PISTON",E_BLOCK_STICKY_PISTON); + tolua_constant(tolua_S,"E_BLOCK_COBWEB",E_BLOCK_COBWEB); + tolua_constant(tolua_S,"E_BLOCK_TALL_GRASS",E_BLOCK_TALL_GRASS); + tolua_constant(tolua_S,"E_BLOCK_DEAD_BUSH",E_BLOCK_DEAD_BUSH); + tolua_constant(tolua_S,"E_BLOCK_PISTON",E_BLOCK_PISTON); + tolua_constant(tolua_S,"E_BLOCK_PISTON_EXTENSION",E_BLOCK_PISTON_EXTENSION); + tolua_constant(tolua_S,"E_BLOCK_WHITE_CLOTH",E_BLOCK_WHITE_CLOTH); + tolua_constant(tolua_S,"E_BLOCK_WOOL",E_BLOCK_WOOL); + tolua_constant(tolua_S,"E_BLOCK_PISTON_MOVED_BLOCK",E_BLOCK_PISTON_MOVED_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_YELLOW_FLOWER",E_BLOCK_YELLOW_FLOWER); + tolua_constant(tolua_S,"E_BLOCK_RED_ROSE",E_BLOCK_RED_ROSE); + tolua_constant(tolua_S,"E_BLOCK_BROWN_MUSHROOM",E_BLOCK_BROWN_MUSHROOM); + tolua_constant(tolua_S,"E_BLOCK_RED_MUSHROOM",E_BLOCK_RED_MUSHROOM); + tolua_constant(tolua_S,"E_BLOCK_GOLD_BLOCK",E_BLOCK_GOLD_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_IRON_BLOCK",E_BLOCK_IRON_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_DOUBLE_STONE_SLAB",E_BLOCK_DOUBLE_STONE_SLAB); + tolua_constant(tolua_S,"E_BLOCK_DOUBLE_STEP",E_BLOCK_DOUBLE_STEP); + tolua_constant(tolua_S,"E_BLOCK_STONE_SLAB",E_BLOCK_STONE_SLAB); + tolua_constant(tolua_S,"E_BLOCK_STEP",E_BLOCK_STEP); + tolua_constant(tolua_S,"E_BLOCK_BRICK",E_BLOCK_BRICK); + tolua_constant(tolua_S,"E_BLOCK_TNT",E_BLOCK_TNT); + tolua_constant(tolua_S,"E_BLOCK_BOOKCASE",E_BLOCK_BOOKCASE); + tolua_constant(tolua_S,"E_BLOCK_MOSSY_COBBLESTONE",E_BLOCK_MOSSY_COBBLESTONE); + tolua_constant(tolua_S,"E_BLOCK_OBSIDIAN",E_BLOCK_OBSIDIAN); + tolua_constant(tolua_S,"E_BLOCK_TORCH",E_BLOCK_TORCH); + tolua_constant(tolua_S,"E_BLOCK_FIRE",E_BLOCK_FIRE); + tolua_constant(tolua_S,"E_BLOCK_MOB_SPAWNER",E_BLOCK_MOB_SPAWNER); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_STAIRS",E_BLOCK_WOODEN_STAIRS); + tolua_constant(tolua_S,"E_BLOCK_CHEST",E_BLOCK_CHEST); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_WIRE",E_BLOCK_REDSTONE_WIRE); + tolua_constant(tolua_S,"E_BLOCK_DIAMOND_ORE",E_BLOCK_DIAMOND_ORE); + tolua_constant(tolua_S,"E_BLOCK_DIAMOND_BLOCK",E_BLOCK_DIAMOND_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_CRAFTING_TABLE",E_BLOCK_CRAFTING_TABLE); + tolua_constant(tolua_S,"E_BLOCK_WORKBENCH",E_BLOCK_WORKBENCH); + tolua_constant(tolua_S,"E_BLOCK_CROPS",E_BLOCK_CROPS); + tolua_constant(tolua_S,"E_BLOCK_SOIL",E_BLOCK_SOIL); + tolua_constant(tolua_S,"E_BLOCK_FARMLAND",E_BLOCK_FARMLAND); + tolua_constant(tolua_S,"E_BLOCK_FURNACE",E_BLOCK_FURNACE); + tolua_constant(tolua_S,"E_BLOCK_LIT_FURNACE",E_BLOCK_LIT_FURNACE); + tolua_constant(tolua_S,"E_BLOCK_BURNING_FURNACE",E_BLOCK_BURNING_FURNACE); + tolua_constant(tolua_S,"E_BLOCK_SIGN_POST",E_BLOCK_SIGN_POST); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOOR",E_BLOCK_WOODEN_DOOR); + tolua_constant(tolua_S,"E_BLOCK_LADDER",E_BLOCK_LADDER); + tolua_constant(tolua_S,"E_BLOCK_RAIL",E_BLOCK_RAIL); + tolua_constant(tolua_S,"E_BLOCK_MINECART_TRACKS",E_BLOCK_MINECART_TRACKS); + tolua_constant(tolua_S,"E_BLOCK_COBBLESTONE_STAIRS",E_BLOCK_COBBLESTONE_STAIRS); + tolua_constant(tolua_S,"E_BLOCK_WALLSIGN",E_BLOCK_WALLSIGN); + tolua_constant(tolua_S,"E_BLOCK_LEVER",E_BLOCK_LEVER); + tolua_constant(tolua_S,"E_BLOCK_STONE_PRESSURE_PLATE",E_BLOCK_STONE_PRESSURE_PLATE); + tolua_constant(tolua_S,"E_BLOCK_IRON_DOOR",E_BLOCK_IRON_DOOR); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_PRESSURE_PLATE",E_BLOCK_WOODEN_PRESSURE_PLATE); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_ORE",E_BLOCK_REDSTONE_ORE); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_ORE_GLOWING",E_BLOCK_REDSTONE_ORE_GLOWING); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_TORCH_OFF",E_BLOCK_REDSTONE_TORCH_OFF); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_TORCH_ON",E_BLOCK_REDSTONE_TORCH_ON); + tolua_constant(tolua_S,"E_BLOCK_STONE_BUTTON",E_BLOCK_STONE_BUTTON); + tolua_constant(tolua_S,"E_BLOCK_SNOW",E_BLOCK_SNOW); + tolua_constant(tolua_S,"E_BLOCK_ICE",E_BLOCK_ICE); + tolua_constant(tolua_S,"E_BLOCK_SNOW_BLOCK",E_BLOCK_SNOW_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_CACTUS",E_BLOCK_CACTUS); + tolua_constant(tolua_S,"E_BLOCK_CLAY",E_BLOCK_CLAY); + tolua_constant(tolua_S,"E_BLOCK_SUGARCANE",E_BLOCK_SUGARCANE); + tolua_constant(tolua_S,"E_BLOCK_REEDS",E_BLOCK_REEDS); + tolua_constant(tolua_S,"E_BLOCK_JUKEBOX",E_BLOCK_JUKEBOX); + tolua_constant(tolua_S,"E_BLOCK_FENCE",E_BLOCK_FENCE); + tolua_constant(tolua_S,"E_BLOCK_PUMPKIN",E_BLOCK_PUMPKIN); + tolua_constant(tolua_S,"E_BLOCK_BLOODSTONE",E_BLOCK_BLOODSTONE); + tolua_constant(tolua_S,"E_BLOCK_NETHERRACK",E_BLOCK_NETHERRACK); + tolua_constant(tolua_S,"E_BLOCK_SOULSAND",E_BLOCK_SOULSAND); + tolua_constant(tolua_S,"E_BLOCK_GLOWSTONE",E_BLOCK_GLOWSTONE); + tolua_constant(tolua_S,"E_BLOCK_PORT",E_BLOCK_PORT); + tolua_constant(tolua_S,"E_BLOCK_NETHER_PORTAL",E_BLOCK_NETHER_PORTAL); + tolua_constant(tolua_S,"E_BLOCK_JACK_O_LANTERN",E_BLOCK_JACK_O_LANTERN); + tolua_constant(tolua_S,"E_BLOCK_CAKE",E_BLOCK_CAKE); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_REPEATER_OFF",E_BLOCK_REDSTONE_REPEATER_OFF); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_REPEATER_ON",E_BLOCK_REDSTONE_REPEATER_ON); + tolua_constant(tolua_S,"E_BLOCK_LOCKED_CHEST",E_BLOCK_LOCKED_CHEST); + tolua_constant(tolua_S,"E_BLOCK_TRAPDOOR",E_BLOCK_TRAPDOOR); + tolua_constant(tolua_S,"E_BLOCK_SILVERFISH_EGG",E_BLOCK_SILVERFISH_EGG); + tolua_constant(tolua_S,"E_BLOCK_STONE_BRICKS",E_BLOCK_STONE_BRICKS); + tolua_constant(tolua_S,"E_BLOCK_HUGE_BROWN_MUSHROOM",E_BLOCK_HUGE_BROWN_MUSHROOM); + tolua_constant(tolua_S,"E_BLOCK_HUGE_RED_MUSHROOM",E_BLOCK_HUGE_RED_MUSHROOM); + tolua_constant(tolua_S,"E_BLOCK_IRON_BAR",E_BLOCK_IRON_BAR); + tolua_constant(tolua_S,"E_BLOCK_GLASS_PLANE",E_BLOCK_GLASS_PLANE); + tolua_constant(tolua_S,"E_BLOCK_MELON",E_BLOCK_MELON); + tolua_constant(tolua_S,"E_BLOCK_PUMPKIN_STEM",E_BLOCK_PUMPKIN_STEM); + tolua_constant(tolua_S,"E_BLOCK_MELON_STEM",E_BLOCK_MELON_STEM); + tolua_constant(tolua_S,"E_BLOCK_VINES",E_BLOCK_VINES); + tolua_constant(tolua_S,"E_BLOCK_FENCE_GATE",E_BLOCK_FENCE_GATE); + tolua_constant(tolua_S,"E_BLOCK_BRICK_STAIRS",E_BLOCK_BRICK_STAIRS); + tolua_constant(tolua_S,"E_BLOCK_STONE_BRICK_STAIRS",E_BLOCK_STONE_BRICK_STAIRS); + tolua_constant(tolua_S,"E_BLOCK_MYCELIUM",E_BLOCK_MYCELIUM); + tolua_constant(tolua_S,"E_BLOCK_LILY_PAD",E_BLOCK_LILY_PAD); + tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK",E_BLOCK_NETHER_BRICK); + tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK_FENCE",E_BLOCK_NETHER_BRICK_FENCE); + tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK_STAIRS",E_BLOCK_NETHER_BRICK_STAIRS); + tolua_constant(tolua_S,"E_BLOCK_NETHER_WART",E_BLOCK_NETHER_WART); + tolua_constant(tolua_S,"E_BLOCK_ENCHANTMENT_TABLE",E_BLOCK_ENCHANTMENT_TABLE); + tolua_constant(tolua_S,"E_BLOCK_BREWING_STAND",E_BLOCK_BREWING_STAND); + tolua_constant(tolua_S,"E_BLOCK_CAULDRON",E_BLOCK_CAULDRON); + tolua_constant(tolua_S,"E_BLOCK_END_PORTAL",E_BLOCK_END_PORTAL); + tolua_constant(tolua_S,"E_BLOCK_END_PORTAL_FRAME",E_BLOCK_END_PORTAL_FRAME); + tolua_constant(tolua_S,"E_BLOCK_END_STONE",E_BLOCK_END_STONE); + tolua_constant(tolua_S,"E_BLOCK_DRAGON_EGG",E_BLOCK_DRAGON_EGG); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_LAMP_OFF",E_BLOCK_REDSTONE_LAMP_OFF); + tolua_constant(tolua_S,"E_BLOCK_REDSTONE_LAMP_ON",E_BLOCK_REDSTONE_LAMP_ON); + tolua_constant(tolua_S,"E_BLOCK_DOUBLE_WOODEN_SLAB",E_BLOCK_DOUBLE_WOODEN_SLAB); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_SLAB",E_BLOCK_WOODEN_SLAB); + tolua_constant(tolua_S,"E_BLOCK_COCA_PLANT",E_BLOCK_COCA_PLANT); + tolua_constant(tolua_S,"E_BLOCK_SANDSTONE_STAIRS",E_BLOCK_SANDSTONE_STAIRS); + tolua_constant(tolua_S,"E_BLOCK_EMERALD_ORE",E_BLOCK_EMERALD_ORE); + tolua_constant(tolua_S,"E_BLOCK_ENDER_CHEST",E_BLOCK_ENDER_CHEST); + tolua_constant(tolua_S,"E_BLOCK_TRIPWIRE_HOOK",E_BLOCK_TRIPWIRE_HOOK); + tolua_constant(tolua_S,"E_BLOCK_TRIPWIRE",E_BLOCK_TRIPWIRE); + tolua_constant(tolua_S,"E_BLOCK_EMERALD_BLOCK",E_BLOCK_EMERALD_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_",E_BLOCK_); + tolua_constant(tolua_S,"E_ITEM_EMPTY",E_ITEM_EMPTY); + tolua_constant(tolua_S,"E_ITEM_STONE",E_ITEM_STONE); + tolua_constant(tolua_S,"E_ITEM_GRASS",E_ITEM_GRASS); + tolua_constant(tolua_S,"E_ITEM_DIRT",E_ITEM_DIRT); + tolua_constant(tolua_S,"E_ITEM_COBBLESTONE",E_ITEM_COBBLESTONE); + tolua_constant(tolua_S,"E_ITEM_PLANKS",E_ITEM_PLANKS); + tolua_constant(tolua_S,"E_ITEM_WOOD",E_ITEM_WOOD); + tolua_constant(tolua_S,"E_ITEM_SAPLING",E_ITEM_SAPLING); + tolua_constant(tolua_S,"E_ITEM_BEDROCK",E_ITEM_BEDROCK); + tolua_constant(tolua_S,"E_ITEM_WATER",E_ITEM_WATER); + tolua_constant(tolua_S,"E_ITEM_STATIONARY_WATER",E_ITEM_STATIONARY_WATER); + tolua_constant(tolua_S,"E_ITEM_LAVA",E_ITEM_LAVA); + tolua_constant(tolua_S,"E_ITEM_STATIONARY_LAVA",E_ITEM_STATIONARY_LAVA); + tolua_constant(tolua_S,"E_ITEM_SAND",E_ITEM_SAND); + tolua_constant(tolua_S,"E_ITEM_GRAVEL",E_ITEM_GRAVEL); + tolua_constant(tolua_S,"E_ITEM_GOLD_ORE",E_ITEM_GOLD_ORE); + tolua_constant(tolua_S,"E_ITEM_IRON_ORE",E_ITEM_IRON_ORE); + tolua_constant(tolua_S,"E_ITEM_COAL_ORE",E_ITEM_COAL_ORE); + tolua_constant(tolua_S,"E_ITEM_LOG",E_ITEM_LOG); + tolua_constant(tolua_S,"E_ITEM_LEAVES",E_ITEM_LEAVES); + tolua_constant(tolua_S,"E_ITEM_SPONGE",E_ITEM_SPONGE); + tolua_constant(tolua_S,"E_ITEM_GLASS",E_ITEM_GLASS); + tolua_constant(tolua_S,"E_ITEM_LAPIS_ORE",E_ITEM_LAPIS_ORE); + tolua_constant(tolua_S,"E_ITEM_LAPIS_BLOCK",E_ITEM_LAPIS_BLOCK); + tolua_constant(tolua_S,"E_ITEM_DISPENSER",E_ITEM_DISPENSER); + tolua_constant(tolua_S,"E_ITEM_SANDSTONE",E_ITEM_SANDSTONE); + tolua_constant(tolua_S,"E_ITEM_NOTE_ITEM",E_ITEM_NOTE_ITEM); + tolua_constant(tolua_S,"E_ITEM_POWERED_RAIL",E_ITEM_POWERED_RAIL); + tolua_constant(tolua_S,"E_ITEM_DETECTOR_RAIL",E_ITEM_DETECTOR_RAIL); + tolua_constant(tolua_S,"E_ITEM_STICKY_PISTON",E_ITEM_STICKY_PISTON); + tolua_constant(tolua_S,"E_ITEM_COBWEB",E_ITEM_COBWEB); + tolua_constant(tolua_S,"E_ITEM_TALL_GRASS",E_ITEM_TALL_GRASS); + tolua_constant(tolua_S,"E_ITEM_DEAD_BRUSH",E_ITEM_DEAD_BRUSH); + tolua_constant(tolua_S,"E_ITEM_PISTON",E_ITEM_PISTON); + tolua_constant(tolua_S,"E_ITEM_PISTON_EXTENSION",E_ITEM_PISTON_EXTENSION); + tolua_constant(tolua_S,"E_ITEM_WHITE_CLOTH",E_ITEM_WHITE_CLOTH); + tolua_constant(tolua_S,"E_ITEM_PISTON_MOVED_BLOCK",E_ITEM_PISTON_MOVED_BLOCK); + tolua_constant(tolua_S,"E_ITEM_YELLOW_FLOWER",E_ITEM_YELLOW_FLOWER); + tolua_constant(tolua_S,"E_ITEM_RED_ROSE",E_ITEM_RED_ROSE); + tolua_constant(tolua_S,"E_ITEM_BROWN_MUSHROOM",E_ITEM_BROWN_MUSHROOM); + tolua_constant(tolua_S,"E_ITEM_RED_MUSHROOM",E_ITEM_RED_MUSHROOM); + tolua_constant(tolua_S,"E_ITEM_GOLD_BLOCK",E_ITEM_GOLD_BLOCK); + tolua_constant(tolua_S,"E_ITEM_IRON_BLOCK",E_ITEM_IRON_BLOCK); + tolua_constant(tolua_S,"E_ITEM_DOUBLE_STONE_SLAB",E_ITEM_DOUBLE_STONE_SLAB); + tolua_constant(tolua_S,"E_ITEM_DOUBLE_STEP",E_ITEM_DOUBLE_STEP); + tolua_constant(tolua_S,"E_ITEM_STONE_SLAB",E_ITEM_STONE_SLAB); + tolua_constant(tolua_S,"E_ITEM_STEP",E_ITEM_STEP); + tolua_constant(tolua_S,"E_ITEM_BRICK",E_ITEM_BRICK); + tolua_constant(tolua_S,"E_ITEM_TNT",E_ITEM_TNT); + tolua_constant(tolua_S,"E_ITEM_BOOKCASE",E_ITEM_BOOKCASE); + tolua_constant(tolua_S,"E_ITEM_MOSSY_COBBLESTONE",E_ITEM_MOSSY_COBBLESTONE); + tolua_constant(tolua_S,"E_ITEM_OBSIDIAN",E_ITEM_OBSIDIAN); + tolua_constant(tolua_S,"E_ITEM_TORCH",E_ITEM_TORCH); + tolua_constant(tolua_S,"E_ITEM_FIRE",E_ITEM_FIRE); + tolua_constant(tolua_S,"E_ITEM_MOB_SPAWNER",E_ITEM_MOB_SPAWNER); + tolua_constant(tolua_S,"E_ITEM_WOODEN_STAIRS",E_ITEM_WOODEN_STAIRS); + tolua_constant(tolua_S,"E_ITEM_CHEST",E_ITEM_CHEST); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_WIRE",E_ITEM_REDSTONE_WIRE); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_ORE",E_ITEM_DIAMOND_ORE); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_BLOCK",E_ITEM_DIAMOND_BLOCK); + tolua_constant(tolua_S,"E_ITEM_WORKBENCH",E_ITEM_WORKBENCH); + tolua_constant(tolua_S,"E_ITEM_CROPS",E_ITEM_CROPS); + tolua_constant(tolua_S,"E_ITEM_SOIL",E_ITEM_SOIL); + tolua_constant(tolua_S,"E_ITEM_FURNACE",E_ITEM_FURNACE); + tolua_constant(tolua_S,"E_ITEM_BURNING_FURNACE",E_ITEM_BURNING_FURNACE); + tolua_constant(tolua_S,"E_ITEM_SIGN_POST",E_ITEM_SIGN_POST); + tolua_constant(tolua_S,"E_ITEM_LADDER",E_ITEM_LADDER); + tolua_constant(tolua_S,"E_ITEM_MINECART_TRACKS",E_ITEM_MINECART_TRACKS); + tolua_constant(tolua_S,"E_ITEM_COBBLESTONE_STAIRS",E_ITEM_COBBLESTONE_STAIRS); + tolua_constant(tolua_S,"E_ITEM_WALLSIGN",E_ITEM_WALLSIGN); + tolua_constant(tolua_S,"E_ITEM_LEVER",E_ITEM_LEVER); + tolua_constant(tolua_S,"E_ITEM_STONE_PRESSURE_PLATE",E_ITEM_STONE_PRESSURE_PLATE); + tolua_constant(tolua_S,"E_ITEM_WOODEN_PRESSURE_PLATE",E_ITEM_WOODEN_PRESSURE_PLATE); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_ORE",E_ITEM_REDSTONE_ORE); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_ORE_GLOWING",E_ITEM_REDSTONE_ORE_GLOWING); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_TORCH_ON",E_ITEM_REDSTONE_TORCH_ON); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_TORCH_OFF",E_ITEM_REDSTONE_TORCH_OFF); + tolua_constant(tolua_S,"E_ITEM_STONE_BUTTON",E_ITEM_STONE_BUTTON); + tolua_constant(tolua_S,"E_ITEM_SNOW",E_ITEM_SNOW); + tolua_constant(tolua_S,"E_ITEM_ICE",E_ITEM_ICE); + tolua_constant(tolua_S,"E_ITEM_SNOW_BLOCK",E_ITEM_SNOW_BLOCK); + tolua_constant(tolua_S,"E_ITEM_CACTUS",E_ITEM_CACTUS); + tolua_constant(tolua_S,"E_ITEM_REEDS",E_ITEM_REEDS); + tolua_constant(tolua_S,"E_ITEM_JUKEBOX",E_ITEM_JUKEBOX); + tolua_constant(tolua_S,"E_ITEM_FENCE",E_ITEM_FENCE); + tolua_constant(tolua_S,"E_ITEM_PUMPKIN",E_ITEM_PUMPKIN); + tolua_constant(tolua_S,"E_ITEM_BLOODSTONE",E_ITEM_BLOODSTONE); + tolua_constant(tolua_S,"E_ITEM_SOULSAND",E_ITEM_SOULSAND); + tolua_constant(tolua_S,"E_ITEM_GLOWSTONE",E_ITEM_GLOWSTONE); + tolua_constant(tolua_S,"E_ITEM_PORT",E_ITEM_PORT); + tolua_constant(tolua_S,"E_ITEM_JACK_O_LANTERN",E_ITEM_JACK_O_LANTERN); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER_OFF",E_ITEM_REDSTONE_REPEATER_OFF); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER_ON",E_ITEM_REDSTONE_REPEATER_ON); + tolua_constant(tolua_S,"E_ITEM_LOCKED_CHEST",E_ITEM_LOCKED_CHEST); + tolua_constant(tolua_S,"E_ITEM_TRAPDOOR",E_ITEM_TRAPDOOR); + tolua_constant(tolua_S,"E_ITEM_SILVERFISH_EGG",E_ITEM_SILVERFISH_EGG); + tolua_constant(tolua_S,"E_ITEM_STONE_BRICKS",E_ITEM_STONE_BRICKS); + tolua_constant(tolua_S,"E_ITEM_HUGE_BROWN_MUSHROOM",E_ITEM_HUGE_BROWN_MUSHROOM); + tolua_constant(tolua_S,"E_ITEM_HUGE_RED_MUSHROOM",E_ITEM_HUGE_RED_MUSHROOM); + tolua_constant(tolua_S,"E_ITEM_IRON_BAR",E_ITEM_IRON_BAR); + tolua_constant(tolua_S,"E_ITEM_GLASS_PLANE",E_ITEM_GLASS_PLANE); + tolua_constant(tolua_S,"E_ITEM_MELON",E_ITEM_MELON); + tolua_constant(tolua_S,"E_ITEM_PUMPKIN_STEM",E_ITEM_PUMPKIN_STEM); + tolua_constant(tolua_S,"E_ITEM_MELON_STEM",E_ITEM_MELON_STEM); + tolua_constant(tolua_S,"E_ITEM_VINES",E_ITEM_VINES); + tolua_constant(tolua_S,"E_ITEM_FENCE_GATE",E_ITEM_FENCE_GATE); + tolua_constant(tolua_S,"E_ITEM_BRICK_STAIRS",E_ITEM_BRICK_STAIRS); + tolua_constant(tolua_S,"E_ITEM_STONE_BRICK_STAIRS",E_ITEM_STONE_BRICK_STAIRS); + tolua_constant(tolua_S,"E_ITEM_MYCELIUM",E_ITEM_MYCELIUM); + tolua_constant(tolua_S,"E_ITEM_LILY_PAD",E_ITEM_LILY_PAD); + tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK",E_ITEM_NETHER_BRICK); + tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK_FENCE",E_ITEM_NETHER_BRICK_FENCE); + tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK_STAIRS",E_ITEM_NETHER_BRICK_STAIRS); + tolua_constant(tolua_S,"E_ITEM_ENCHANTMENT_TABLE",E_ITEM_ENCHANTMENT_TABLE); + tolua_constant(tolua_S,"E_ITEM_END_PORTAL",E_ITEM_END_PORTAL); + tolua_constant(tolua_S,"E_ITEM_END_PORTAL_FRAME",E_ITEM_END_PORTAL_FRAME); + tolua_constant(tolua_S,"E_ITEM_END_STONE",E_ITEM_END_STONE); + tolua_constant(tolua_S,"E_ITEM_DOUBLE_WOODEN_SLAB",E_ITEM_DOUBLE_WOODEN_SLAB); + tolua_constant(tolua_S,"E_ITEM_WOODEN_SLAB",E_ITEM_WOODEN_SLAB); + tolua_constant(tolua_S,"E_ITEM_COCA_PLANT",E_ITEM_COCA_PLANT); + tolua_constant(tolua_S,"E_ITEM_SANDSTONE_STAIRS",E_ITEM_SANDSTONE_STAIRS); + tolua_constant(tolua_S,"E_ITEM_EMERALD_ORE",E_ITEM_EMERALD_ORE); + tolua_constant(tolua_S,"E_ITEM_ENDER_CHEST",E_ITEM_ENDER_CHEST); + tolua_constant(tolua_S,"E_ITEM_TRIPWIRE_HOOK",E_ITEM_TRIPWIRE_HOOK); + tolua_constant(tolua_S,"E_ITEM_TRIPWIRE",E_ITEM_TRIPWIRE); + tolua_constant(tolua_S,"E_ITEM_EMERALD_BLOCK",E_ITEM_EMERALD_BLOCK); + tolua_constant(tolua_S,"E_ITEM_IRON_SHOVEL",E_ITEM_IRON_SHOVEL); + tolua_constant(tolua_S,"E_ITEM_IRON_PICKAXE",E_ITEM_IRON_PICKAXE); + tolua_constant(tolua_S,"E_ITEM_IRON_AXE",E_ITEM_IRON_AXE); + tolua_constant(tolua_S,"E_ITEM_FLINT_AND_STEEL",E_ITEM_FLINT_AND_STEEL); + tolua_constant(tolua_S,"E_ITEM_RED_APPLE",E_ITEM_RED_APPLE); + tolua_constant(tolua_S,"E_ITEM_APPLE",E_ITEM_APPLE); + tolua_constant(tolua_S,"E_ITEM_BOW",E_ITEM_BOW); + tolua_constant(tolua_S,"E_ITEM_ARROW",E_ITEM_ARROW); + tolua_constant(tolua_S,"E_ITEM_COAL",E_ITEM_COAL); + tolua_constant(tolua_S,"E_ITEM_DIAMOND",E_ITEM_DIAMOND); + tolua_constant(tolua_S,"E_ITEM_IRON",E_ITEM_IRON); + tolua_constant(tolua_S,"E_ITEM_GOLD",E_ITEM_GOLD); + tolua_constant(tolua_S,"E_ITEM_IRON_SWORD",E_ITEM_IRON_SWORD); + tolua_constant(tolua_S,"E_ITEM_WOODEN_SWORD",E_ITEM_WOODEN_SWORD); + tolua_constant(tolua_S,"E_ITEM_WOODEN_SHOVEL",E_ITEM_WOODEN_SHOVEL); + tolua_constant(tolua_S,"E_ITEM_WOODEN_PICKAXE",E_ITEM_WOODEN_PICKAXE); + tolua_constant(tolua_S,"E_ITEM_WOODEN_AXE",E_ITEM_WOODEN_AXE); + tolua_constant(tolua_S,"E_ITEM_STONE_SWORD",E_ITEM_STONE_SWORD); + tolua_constant(tolua_S,"E_ITEM_STONE_SHOVEL",E_ITEM_STONE_SHOVEL); + tolua_constant(tolua_S,"E_ITEM_STONE_PICKAXE",E_ITEM_STONE_PICKAXE); + tolua_constant(tolua_S,"E_ITEM_STONE_AXE",E_ITEM_STONE_AXE); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_SWORD",E_ITEM_DIAMOND_SWORD); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_SHOVEL",E_ITEM_DIAMOND_SHOVEL); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_PICKAXE",E_ITEM_DIAMOND_PICKAXE); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_AXE",E_ITEM_DIAMOND_AXE); + tolua_constant(tolua_S,"E_ITEM_STICK",E_ITEM_STICK); + tolua_constant(tolua_S,"E_ITEM_BOWL",E_ITEM_BOWL); + tolua_constant(tolua_S,"E_ITEM_MUSHROOM_SOUP",E_ITEM_MUSHROOM_SOUP); + tolua_constant(tolua_S,"E_ITEM_GOLD_SWORD",E_ITEM_GOLD_SWORD); + tolua_constant(tolua_S,"E_ITEM_GOLD_SHOVEL",E_ITEM_GOLD_SHOVEL); + tolua_constant(tolua_S,"E_ITEM_GOLD_PICKAXE",E_ITEM_GOLD_PICKAXE); + tolua_constant(tolua_S,"E_ITEM_GOLD_AXE",E_ITEM_GOLD_AXE); + tolua_constant(tolua_S,"E_ITEM_STRING",E_ITEM_STRING); + tolua_constant(tolua_S,"E_ITEM_FEATHER",E_ITEM_FEATHER); + tolua_constant(tolua_S,"E_ITEM_GUNPOWDER",E_ITEM_GUNPOWDER); + tolua_constant(tolua_S,"E_ITEM_WOODEN_HOE",E_ITEM_WOODEN_HOE); + tolua_constant(tolua_S,"E_ITEM_STONE_HOE",E_ITEM_STONE_HOE); + tolua_constant(tolua_S,"E_ITEM_IRON_HOE",E_ITEM_IRON_HOE); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_HOE",E_ITEM_DIAMOND_HOE); + tolua_constant(tolua_S,"E_ITEM_GOLD_HOE",E_ITEM_GOLD_HOE); + tolua_constant(tolua_S,"E_ITEM_SEEDS",E_ITEM_SEEDS); + tolua_constant(tolua_S,"E_ITEM_WHEAT",E_ITEM_WHEAT); + tolua_constant(tolua_S,"E_ITEM_BREAD",E_ITEM_BREAD); + tolua_constant(tolua_S,"E_ITEM_LEATHER_CAP",E_ITEM_LEATHER_CAP); + tolua_constant(tolua_S,"E_ITEM_LEATHER_TUNIC",E_ITEM_LEATHER_TUNIC); + tolua_constant(tolua_S,"E_ITEM_LEATHER_PANTS",E_ITEM_LEATHER_PANTS); + tolua_constant(tolua_S,"E_ITEM_LEATHER_BOOTS",E_ITEM_LEATHER_BOOTS); + tolua_constant(tolua_S,"E_ITEM_CHAIN_HELMET",E_ITEM_CHAIN_HELMET); + tolua_constant(tolua_S,"E_ITEM_CHAIN_CHESTPLATE",E_ITEM_CHAIN_CHESTPLATE); + tolua_constant(tolua_S,"E_ITEM_CHAIN_LEGGINGS",E_ITEM_CHAIN_LEGGINGS); + tolua_constant(tolua_S,"E_ITEM_CHAIN_BOOTS",E_ITEM_CHAIN_BOOTS); + tolua_constant(tolua_S,"E_ITEM_IRON_HELMET",E_ITEM_IRON_HELMET); + tolua_constant(tolua_S,"E_ITEM_IRON_CHESTPLATE",E_ITEM_IRON_CHESTPLATE); + tolua_constant(tolua_S,"E_ITEM_IRON_LEGGINGS",E_ITEM_IRON_LEGGINGS); + tolua_constant(tolua_S,"E_ITEM_IRON_BOOTS",E_ITEM_IRON_BOOTS); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_HELMET",E_ITEM_DIAMOND_HELMET); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_CHESTPLATE",E_ITEM_DIAMOND_CHESTPLATE); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_LEGGINGS",E_ITEM_DIAMOND_LEGGINGS); + tolua_constant(tolua_S,"E_ITEM_DIAMOND_BOOTS",E_ITEM_DIAMOND_BOOTS); + tolua_constant(tolua_S,"E_ITEM_GOLD_HELMET",E_ITEM_GOLD_HELMET); + tolua_constant(tolua_S,"E_ITEM_GOLD_CHESTPLATE",E_ITEM_GOLD_CHESTPLATE); + tolua_constant(tolua_S,"E_ITEM_GOLD_LEGGINGS",E_ITEM_GOLD_LEGGINGS); + tolua_constant(tolua_S,"E_ITEM_GOLD_BOOTS",E_ITEM_GOLD_BOOTS); + tolua_constant(tolua_S,"E_ITEM_FLINT",E_ITEM_FLINT); + tolua_constant(tolua_S,"E_ITEM_RAW_MEAT",E_ITEM_RAW_MEAT); + tolua_constant(tolua_S,"E_ITEM_COOKED_MEAT",E_ITEM_COOKED_MEAT); + tolua_constant(tolua_S,"E_ITEM_PAINTINGS",E_ITEM_PAINTINGS); + tolua_constant(tolua_S,"E_ITEM_GOLDEN_APPLE",E_ITEM_GOLDEN_APPLE); + tolua_constant(tolua_S,"E_ITEM_SIGN",E_ITEM_SIGN); + tolua_constant(tolua_S,"E_ITEM_WOODEN_DOOR",E_ITEM_WOODEN_DOOR); + tolua_constant(tolua_S,"E_ITEM_BUCKET",E_ITEM_BUCKET); + tolua_constant(tolua_S,"E_ITEM_WATER_BUCKET",E_ITEM_WATER_BUCKET); + tolua_constant(tolua_S,"E_ITEM_LAVA_BUCKET",E_ITEM_LAVA_BUCKET); + tolua_constant(tolua_S,"E_ITEM_MINECART",E_ITEM_MINECART); + tolua_constant(tolua_S,"E_ITEM_SADDLE",E_ITEM_SADDLE); + tolua_constant(tolua_S,"E_ITEM_IRON_DOOR",E_ITEM_IRON_DOOR); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_DUST",E_ITEM_REDSTONE_DUST); + tolua_constant(tolua_S,"E_ITEM_SNOWBALL",E_ITEM_SNOWBALL); + tolua_constant(tolua_S,"E_ITEM_BOAT",E_ITEM_BOAT); + tolua_constant(tolua_S,"E_ITEM_LEATHER",E_ITEM_LEATHER); + tolua_constant(tolua_S,"E_ITEM_MILK",E_ITEM_MILK); + tolua_constant(tolua_S,"E_ITEM_CLAY_BRICK",E_ITEM_CLAY_BRICK); + tolua_constant(tolua_S,"E_ITEM_CLAY",E_ITEM_CLAY); + tolua_constant(tolua_S,"E_ITEM_SUGARCANE",E_ITEM_SUGARCANE); + tolua_constant(tolua_S,"E_ITEM_SUGAR_CANE",E_ITEM_SUGAR_CANE); + tolua_constant(tolua_S,"E_ITEM_PAPER",E_ITEM_PAPER); + tolua_constant(tolua_S,"E_ITEM_BOOK",E_ITEM_BOOK); + tolua_constant(tolua_S,"E_ITEM_SLIMEBALL",E_ITEM_SLIMEBALL); + tolua_constant(tolua_S,"E_ITEM_CHEST_MINECART",E_ITEM_CHEST_MINECART); + tolua_constant(tolua_S,"E_ITEM_FURNACE_MINECART",E_ITEM_FURNACE_MINECART); + tolua_constant(tolua_S,"E_ITEM_EGG",E_ITEM_EGG); + tolua_constant(tolua_S,"E_ITEM_COMPASS",E_ITEM_COMPASS); + tolua_constant(tolua_S,"E_ITEM_FISHING_ROD",E_ITEM_FISHING_ROD); + tolua_constant(tolua_S,"E_ITEM_CLOCK",E_ITEM_CLOCK); + tolua_constant(tolua_S,"E_ITEM_GLOWSTONE_DUST",E_ITEM_GLOWSTONE_DUST); + tolua_constant(tolua_S,"E_ITEM_RAW_FISH",E_ITEM_RAW_FISH); + tolua_constant(tolua_S,"E_ITEM_COOKED_FISH",E_ITEM_COOKED_FISH); + tolua_constant(tolua_S,"E_ITEM_DYE",E_ITEM_DYE); + tolua_constant(tolua_S,"E_ITEM_BONE",E_ITEM_BONE); + tolua_constant(tolua_S,"E_ITEM_SUGAR",E_ITEM_SUGAR); + tolua_constant(tolua_S,"E_ITEM_CAKE",E_ITEM_CAKE); + tolua_constant(tolua_S,"E_ITEM_BED",E_ITEM_BED); + tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER",E_ITEM_REDSTONE_REPEATER); + tolua_constant(tolua_S,"E_ITEM_COOKIE",E_ITEM_COOKIE); + tolua_constant(tolua_S,"E_ITEM_MAP",E_ITEM_MAP); + tolua_constant(tolua_S,"E_ITEM_SHEARS",E_ITEM_SHEARS); + tolua_constant(tolua_S,"E_ITEM_MELON_SLICE",E_ITEM_MELON_SLICE); + tolua_constant(tolua_S,"E_ITEM_PUMPKIN_SEEDS",E_ITEM_PUMPKIN_SEEDS); + tolua_constant(tolua_S,"E_ITEM_MELON_SEEDS",E_ITEM_MELON_SEEDS); + tolua_constant(tolua_S,"E_ITEM_RAW_BEEF",E_ITEM_RAW_BEEF); + tolua_constant(tolua_S,"E_ITEM_STEAK",E_ITEM_STEAK); + tolua_constant(tolua_S,"E_ITEM_RAW_CHICKEN",E_ITEM_RAW_CHICKEN); + tolua_constant(tolua_S,"E_ITEM_COOKED_CHICKEN",E_ITEM_COOKED_CHICKEN); + tolua_constant(tolua_S,"E_ITEM_ROTTEN_FLESH",E_ITEM_ROTTEN_FLESH); + tolua_constant(tolua_S,"E_ITEM_ENDER_PEARL",E_ITEM_ENDER_PEARL); + tolua_constant(tolua_S,"E_ITEM_BLAZE_ROD",E_ITEM_BLAZE_ROD); + tolua_constant(tolua_S,"E_ITEM_GHAST_TEAR",E_ITEM_GHAST_TEAR); + tolua_constant(tolua_S,"E_ITEM_GOLD_NUGGET",E_ITEM_GOLD_NUGGET); + tolua_constant(tolua_S,"E_ITEM_NETHER_WART",E_ITEM_NETHER_WART); + tolua_constant(tolua_S,"E_ITEM_POTIONS",E_ITEM_POTIONS); + tolua_constant(tolua_S,"E_ITEM_GLASS_BOTTLE",E_ITEM_GLASS_BOTTLE); + tolua_constant(tolua_S,"E_ITEM_SPIDER_EYE",E_ITEM_SPIDER_EYE); + tolua_constant(tolua_S,"E_ITEM_FERMENTED_SPIDER_EYE",E_ITEM_FERMENTED_SPIDER_EYE); + tolua_constant(tolua_S,"E_ITEM_BLAZE_POWDER",E_ITEM_BLAZE_POWDER); + tolua_constant(tolua_S,"E_ITEM_MAGMA_CREAM",E_ITEM_MAGMA_CREAM); + tolua_constant(tolua_S,"E_ITEM_BREWING_STAND",E_ITEM_BREWING_STAND); + tolua_constant(tolua_S,"E_ITEM_CAULDRON",E_ITEM_CAULDRON); + tolua_constant(tolua_S,"E_ITEM_EYE_OF_ENDER",E_ITEM_EYE_OF_ENDER); + tolua_constant(tolua_S,"E_ITEM_GLISTERING_MELON",E_ITEM_GLISTERING_MELON); + tolua_constant(tolua_S,"E_ITEM_SPAWN_EGG",E_ITEM_SPAWN_EGG); + tolua_constant(tolua_S,"E_ITEM_BOTTLE_O_ENCHANTING",E_ITEM_BOTTLE_O_ENCHANTING); + tolua_constant(tolua_S,"E_ITEM_FIRE_CHARGE",E_ITEM_FIRE_CHARGE); + tolua_constant(tolua_S,"E_ITEM_BOOK_AND_QUILL",E_ITEM_BOOK_AND_QUILL); + tolua_constant(tolua_S,"E_ITEM_WRITTEN_BOOK",E_ITEM_WRITTEN_BOOK); + tolua_constant(tolua_S,"E_ITEM_EMERALD",E_ITEM_EMERALD); + tolua_constant(tolua_S,"E_ITEM_13_DISC",E_ITEM_13_DISC); + tolua_constant(tolua_S,"E_ITEM_CAT_DISC",E_ITEM_CAT_DISC); + tolua_constant(tolua_S,"E_ITEM_BLOCKS_DISC",E_ITEM_BLOCKS_DISC); + tolua_constant(tolua_S,"E_ITEM_CHIRP_DISC",E_ITEM_CHIRP_DISC); + tolua_constant(tolua_S,"E_ITEM_FAR_DISC",E_ITEM_FAR_DISC); + tolua_constant(tolua_S,"E_ITEM_MALL_DISC",E_ITEM_MALL_DISC); + tolua_constant(tolua_S,"E_ITEM_MELLOHI_DISC",E_ITEM_MELLOHI_DISC); + tolua_constant(tolua_S,"E_ITEM_STAL_DISC",E_ITEM_STAL_DISC); + tolua_constant(tolua_S,"E_ITEM_STRAD_DISC",E_ITEM_STRAD_DISC); + tolua_constant(tolua_S,"E_ITEM_WARD_DISC",E_ITEM_WARD_DISC); + tolua_constant(tolua_S,"E_ITEM_11_DISC",E_ITEM_11_DISC); + tolua_constant(tolua_S,"E_META_PLANKS_APPLE",E_META_PLANKS_APPLE); + tolua_constant(tolua_S,"E_META_PLANKS_CONIFER",E_META_PLANKS_CONIFER); + tolua_constant(tolua_S,"E_META_PLANKS_BIRCH",E_META_PLANKS_BIRCH); + tolua_constant(tolua_S,"E_META_PLANKS_JUNGLE",E_META_PLANKS_JUNGLE); + tolua_constant(tolua_S,"E_META_LOG_APPLE",E_META_LOG_APPLE); + tolua_constant(tolua_S,"E_META_LOG_CONIFER",E_META_LOG_CONIFER); + tolua_constant(tolua_S,"E_META_LOG_BIRCH",E_META_LOG_BIRCH); + tolua_constant(tolua_S,"E_META_LOG_JUNGLE",E_META_LOG_JUNGLE); + tolua_constant(tolua_S,"E_META_LEAVES_APPLE",E_META_LEAVES_APPLE); + tolua_constant(tolua_S,"E_META_LEAVES_CONIFER",E_META_LEAVES_CONIFER); + tolua_constant(tolua_S,"E_META_LEAVES_BIRCH",E_META_LEAVES_BIRCH); + tolua_constant(tolua_S,"E_META_LEAVES_JUNGLE",E_META_LEAVES_JUNGLE); + tolua_constant(tolua_S,"E_META_SAPLING_APPLE",E_META_SAPLING_APPLE); + tolua_constant(tolua_S,"E_META_SAPLING_CONIFER",E_META_SAPLING_CONIFER); + tolua_constant(tolua_S,"E_META_SAPLING_BIRCH",E_META_SAPLING_BIRCH); + tolua_constant(tolua_S,"E_META_SAPLING_JUNGLE",E_META_SAPLING_JUNGLE); + tolua_constant(tolua_S,"E_META_TALL_GRASS_DEAD_SHRUB",E_META_TALL_GRASS_DEAD_SHRUB); + tolua_constant(tolua_S,"E_META_TALL_GRASS_GRASS",E_META_TALL_GRASS_GRASS); + tolua_constant(tolua_S,"E_META_TALL_GRASS_FERN",E_META_TALL_GRASS_FERN); + tolua_constant(tolua_S,"E_META_SANDSTONE_NORMAL",E_META_SANDSTONE_NORMAL); + tolua_constant(tolua_S,"E_META_SANDSTONE_ORNAMENT",E_META_SANDSTONE_ORNAMENT); + tolua_constant(tolua_S,"E_META_SANDSTONE_SMOOTH",E_META_SANDSTONE_SMOOTH); + tolua_constant(tolua_S,"E_META_WOOL_WHITE",E_META_WOOL_WHITE); + tolua_constant(tolua_S,"E_META_WOOL_ORANGE",E_META_WOOL_ORANGE); + tolua_constant(tolua_S,"E_META_WOOL_MAGENTA",E_META_WOOL_MAGENTA); + tolua_constant(tolua_S,"E_META_WOOL_LIGHTBLUE",E_META_WOOL_LIGHTBLUE); + tolua_constant(tolua_S,"E_META_WOOL_YELLOW",E_META_WOOL_YELLOW); + tolua_constant(tolua_S,"E_META_WOOL_LIGHTGREEN",E_META_WOOL_LIGHTGREEN); + tolua_constant(tolua_S,"E_META_WOOL_PINK",E_META_WOOL_PINK); + tolua_constant(tolua_S,"E_META_WOOL_GRAY",E_META_WOOL_GRAY); + tolua_constant(tolua_S,"E_META_WOOL_LIGHTGRAY",E_META_WOOL_LIGHTGRAY); + tolua_constant(tolua_S,"E_META_WOOL_CYAN",E_META_WOOL_CYAN); + tolua_constant(tolua_S,"E_META_WOOL_PURPLE",E_META_WOOL_PURPLE); + tolua_constant(tolua_S,"E_META_WOOL_BLUE",E_META_WOOL_BLUE); + tolua_constant(tolua_S,"E_META_WOOL_BROWN",E_META_WOOL_BROWN); + tolua_constant(tolua_S,"E_META_WOOL_GREEN",E_META_WOOL_GREEN); + tolua_constant(tolua_S,"E_META_WOOL_RED",E_META_WOOL_RED); + tolua_constant(tolua_S,"E_META_WOOL_BLACK",E_META_WOOL_BLACK); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE",E_META_DOUBLE_STEP_STONE); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_SANDSTONE",E_META_DOUBLE_STEP_SANDSTONE); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_WOODEN",E_META_DOUBLE_STEP_WOODEN); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_COBBLESTONE",E_META_DOUBLE_STEP_COBBLESTONE); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_BRICK",E_META_DOUBLE_STEP_BRICK); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE_BRICK",E_META_DOUBLE_STEP_STONE_BRICK); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE_SECRET",E_META_DOUBLE_STEP_STONE_SECRET); + tolua_constant(tolua_S,"E_META_STEP_STONE",E_META_STEP_STONE); + tolua_constant(tolua_S,"E_META_STEP_SANDSTONE",E_META_STEP_SANDSTONE); + tolua_constant(tolua_S,"E_META_STEP_PLANKS",E_META_STEP_PLANKS); + tolua_constant(tolua_S,"E_META_STEP_COBBLESTONE",E_META_STEP_COBBLESTONE); + tolua_constant(tolua_S,"E_META_STEP_BRICK",E_META_STEP_BRICK); + tolua_constant(tolua_S,"E_META_STEP_STONE_BRICK",E_META_STEP_STONE_BRICK); + tolua_constant(tolua_S,"E_META_STEP_STONE_SECRET",E_META_STEP_STONE_SECRET); + tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_STONE",E_META_SILVERFISH_EGG_STONE); + tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_COBBLESTONE",E_META_SILVERFISH_EGG_COBBLESTONE); + tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_STONE_BRICK",E_META_SILVERFISH_EGG_STONE_BRICK); + tolua_constant(tolua_S,"E_META_STONE_BRICK_NORMAL",E_META_STONE_BRICK_NORMAL); + tolua_constant(tolua_S,"E_META_STONE_BRICK_MOSSY",E_META_STONE_BRICK_MOSSY); + tolua_constant(tolua_S,"E_META_STONE_BRICK_CRACKED",E_META_STONE_BRICK_CRACKED); + tolua_constant(tolua_S,"E_META_STONE_BRICK_ORNAMENT",E_META_STONE_BRICK_ORNAMENT); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_APPLE",E_BLOCK_WOODEN_DOUBLE_STEP_APPLE); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER",E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH",E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE",E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_APPLE",E_BLOCK_WOODEN_STEP_APPLE); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_CONIFER",E_BLOCK_WOODEN_STEP_CONIFER); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_BIRCH",E_BLOCK_WOODEN_STEP_BIRCH); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_JUNGLE",E_BLOCK_WOODEN_STEP_JUNGLE); + tolua_constant(tolua_S,"E_META_COAL_NORMAL",E_META_COAL_NORMAL); + tolua_constant(tolua_S,"E_META_COAL_CHARCOAL",E_META_COAL_CHARCOAL); + tolua_constant(tolua_S,"E_META_GOLDEN_APPLE_NORMAL",E_META_GOLDEN_APPLE_NORMAL); + tolua_constant(tolua_S,"E_META_GOLDEN_APPLE_ENCHANTED",E_META_GOLDEN_APPLE_ENCHANTED); + tolua_constant(tolua_S,"E_META_DYE_BLACK",E_META_DYE_BLACK); + tolua_constant(tolua_S,"E_META_DYE_RED",E_META_DYE_RED); + tolua_constant(tolua_S,"E_META_DYE_GREEN",E_META_DYE_GREEN); + tolua_constant(tolua_S,"E_META_DYE_BROWN",E_META_DYE_BROWN); + tolua_constant(tolua_S,"E_META_DYE_BLUE",E_META_DYE_BLUE); + tolua_constant(tolua_S,"E_META_DYE_PURPLE",E_META_DYE_PURPLE); + tolua_constant(tolua_S,"E_META_DYE_CYAN",E_META_DYE_CYAN); + tolua_constant(tolua_S,"E_META_DYE_LIGHTGRAY",E_META_DYE_LIGHTGRAY); + tolua_constant(tolua_S,"E_META_DYE_GRAY",E_META_DYE_GRAY); + tolua_constant(tolua_S,"E_META_DYE_PINK",E_META_DYE_PINK); + tolua_constant(tolua_S,"E_META_DYE_LIGHTGREEN",E_META_DYE_LIGHTGREEN); + tolua_constant(tolua_S,"E_META_DYE_YELLOW",E_META_DYE_YELLOW); + tolua_constant(tolua_S,"E_META_DYE_LIGHTBLUE",E_META_DYE_LIGHTBLUE); + tolua_constant(tolua_S,"E_META_DYE_MAGENTA",E_META_DYE_MAGENTA); + tolua_constant(tolua_S,"E_META_DYE_ORANGE",E_META_DYE_ORANGE); + tolua_constant(tolua_S,"E_META_DYE_WHITE",E_META_DYE_WHITE); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_CREEPER",E_META_SPAWN_EGG_CREEPER); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SKELETON",E_META_SPAWN_EGG_SKELETON); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SPIDER",E_META_SPAWN_EGG_SPIDER); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_ZOMBIE",E_META_SPAWN_EGG_ZOMBIE); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SLIME",E_META_SPAWN_EGG_SLIME); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_GHAST",E_META_SPAWN_EGG_GHAST); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_ZOMBIE_PIGMAN",E_META_SPAWN_EGG_ZOMBIE_PIGMAN); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_ENDERMAN",E_META_SPAWN_EGG_ENDERMAN); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_CAVE_SPIDER",E_META_SPAWN_EGG_CAVE_SPIDER); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SILVERFISH",E_META_SPAWN_EGG_SILVERFISH); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_BLAZE",E_META_SPAWN_EGG_BLAZE); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_MAGMA_CUBE",E_META_SPAWN_EGG_MAGMA_CUBE); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_GIANT",E_META_SPAWN_EGG_GIANT); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_ENDER_DRAGON",E_META_SPAWN_EGG_ENDER_DRAGON); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_PIG",E_META_SPAWN_EGG_PIG); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SHEEP",E_META_SPAWN_EGG_SHEEP); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_COW",E_META_SPAWN_EGG_COW); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_CHICKEN",E_META_SPAWN_EGG_CHICKEN); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SQUID",E_META_SPAWN_EGG_SQUID); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_WOLF",E_META_SPAWN_EGG_WOLF); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_MOOSHROOM",E_META_SPAWN_EGG_MOOSHROOM); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_OCELOT",E_META_SPAWN_EGG_OCELOT); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_VILLAGER",E_META_SPAWN_EGG_VILLAGER); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SNOW_GOLEM",E_META_SPAWN_EGG_SNOW_GOLEM); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_IRON_GOLEM",E_META_SPAWN_EGG_IRON_GOLEM); + tolua_function(tolua_S,"BlockStringToType",tolua_AllToLua_BlockStringToType00); + tolua_function(tolua_S,"StringToItem",tolua_AllToLua_StringToItem00); + tolua_constant(tolua_S,"E_KEEP_ALIVE",E_KEEP_ALIVE); + tolua_constant(tolua_S,"E_LOGIN",E_LOGIN); + tolua_constant(tolua_S,"E_HANDSHAKE",E_HANDSHAKE); + tolua_constant(tolua_S,"E_CHAT",E_CHAT); + tolua_constant(tolua_S,"E_UPDATE_TIME",E_UPDATE_TIME); + tolua_constant(tolua_S,"E_ENTITY_EQUIPMENT",E_ENTITY_EQUIPMENT); + tolua_constant(tolua_S,"E_USE_ENTITY",E_USE_ENTITY); + tolua_constant(tolua_S,"E_UPDATE_HEALTH",E_UPDATE_HEALTH); + tolua_constant(tolua_S,"E_RESPAWN",E_RESPAWN); + tolua_constant(tolua_S,"E_FLYING",E_FLYING); + tolua_constant(tolua_S,"E_PLAYERPOS",E_PLAYERPOS); + tolua_constant(tolua_S,"E_PLAYERLOOK",E_PLAYERLOOK); + tolua_constant(tolua_S,"E_PLAYERMOVELOOK",E_PLAYERMOVELOOK); + tolua_constant(tolua_S,"E_BLOCK_DIG",E_BLOCK_DIG); + tolua_constant(tolua_S,"E_BLOCK_PLACE",E_BLOCK_PLACE); + tolua_constant(tolua_S,"E_ITEM_SWITCH",E_ITEM_SWITCH); + tolua_constant(tolua_S,"E_ADD_TO_INV",E_ADD_TO_INV); + tolua_constant(tolua_S,"E_ANIMATION",E_ANIMATION); + tolua_constant(tolua_S,"E_PACKET_13",E_PACKET_13); + tolua_constant(tolua_S,"E_NAMED_ENTITY_SPAWN",E_NAMED_ENTITY_SPAWN); + tolua_constant(tolua_S,"E_PICKUP_SPAWN",E_PICKUP_SPAWN); + tolua_constant(tolua_S,"E_COLLECT_ITEM",E_COLLECT_ITEM); + tolua_constant(tolua_S,"E_ADD_VEHICLE",E_ADD_VEHICLE); + tolua_constant(tolua_S,"E_SPAWN_MOB",E_SPAWN_MOB); + tolua_constant(tolua_S,"E_DESTROY_ENT",E_DESTROY_ENT); + tolua_constant(tolua_S,"E_ENTITY",E_ENTITY); + tolua_constant(tolua_S,"E_REL_ENT_MOVE",E_REL_ENT_MOVE); + tolua_constant(tolua_S,"E_ENT_LOOK",E_ENT_LOOK); + tolua_constant(tolua_S,"E_REL_ENT_MOVE_LOOK",E_REL_ENT_MOVE_LOOK); + tolua_constant(tolua_S,"E_ENT_TELEPORT",E_ENT_TELEPORT); + tolua_constant(tolua_S,"E_ENT_HEAD_LOOK",E_ENT_HEAD_LOOK); + tolua_constant(tolua_S,"E_ENT_STATUS",E_ENT_STATUS); + tolua_constant(tolua_S,"E_METADATA",E_METADATA); + tolua_constant(tolua_S,"E_PRE_CHUNK",E_PRE_CHUNK); + tolua_constant(tolua_S,"E_MAP_CHUNK",E_MAP_CHUNK); + tolua_constant(tolua_S,"E_MULTI_BLOCK",E_MULTI_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_CHANGE",E_BLOCK_CHANGE); + tolua_constant(tolua_S,"E_BLOCK_ACTION",E_BLOCK_ACTION); + tolua_constant(tolua_S,"E_EXPLOSION",E_EXPLOSION); + tolua_constant(tolua_S,"E_SOUND_EFFECT",E_SOUND_EFFECT); + tolua_constant(tolua_S,"E_NEW_INVALID_STATE",E_NEW_INVALID_STATE); + tolua_constant(tolua_S,"E_THUNDERBOLT",E_THUNDERBOLT); + tolua_constant(tolua_S,"E_WINDOW_OPEN",E_WINDOW_OPEN); + tolua_constant(tolua_S,"E_WINDOW_CLOSE",E_WINDOW_CLOSE); + tolua_constant(tolua_S,"E_WINDOW_CLICK",E_WINDOW_CLICK); + tolua_constant(tolua_S,"E_INVENTORY_SLOT",E_INVENTORY_SLOT); + tolua_constant(tolua_S,"E_INVENTORY_WHOLE",E_INVENTORY_WHOLE); + tolua_constant(tolua_S,"E_INVENTORY_PROGRESS",E_INVENTORY_PROGRESS); + tolua_constant(tolua_S,"E_CREATIVE_INVENTORY_ACTION",E_CREATIVE_INVENTORY_ACTION); + tolua_constant(tolua_S,"E_UPDATE_SIGN",E_UPDATE_SIGN); + tolua_constant(tolua_S,"E_PLAYER_LIST_ITEM",E_PLAYER_LIST_ITEM); + tolua_constant(tolua_S,"E_PLAYER_ABILITIES",E_PLAYER_ABILITIES); + tolua_constant(tolua_S,"E_PING",E_PING); + tolua_constant(tolua_S,"E_DISCONNECT",E_DISCONNECT); + tolua_array(tolua_S,"g_BlockLightValue",tolua_get_AllToLua_g_BlockLightValue,tolua_set_AllToLua_g_BlockLightValue); + tolua_array(tolua_S,"g_BlockSpreadLightFalloff",tolua_get_AllToLua_g_BlockSpreadLightFalloff,tolua_set_AllToLua_g_BlockSpreadLightFalloff); + tolua_array(tolua_S,"g_BlockTransparent",tolua_get_AllToLua_g_BlockTransparent,tolua_set_AllToLua_g_BlockTransparent); + tolua_array(tolua_S,"g_BlockOneHitDig",tolua_get_AllToLua_g_BlockOneHitDig,tolua_set_AllToLua_g_BlockOneHitDig); + tolua_function(tolua_S,"IsValidBlock",tolua_AllToLua_IsValidBlock00); + tolua_function(tolua_S,"IsValidItem",tolua_AllToLua_IsValidItem00); + tolua_function(tolua_S,"AddDirection",tolua_AllToLua_AddDirection00); + tolua_module(tolua_S,"ItemCategory",0); + tolua_beginmodule(tolua_S,"ItemCategory"); + tolua_function(tolua_S,"IsPickaxe",tolua_AllToLua_ItemCategory_IsPickaxe00); + tolua_function(tolua_S,"IsAxe",tolua_AllToLua_ItemCategory_IsAxe00); + tolua_function(tolua_S,"IsSword",tolua_AllToLua_ItemCategory_IsSword00); + tolua_function(tolua_S,"IsHoe",tolua_AllToLua_ItemCategory_IsHoe00); + tolua_function(tolua_S,"IsShovel",tolua_AllToLua_ItemCategory_IsShovel00); + tolua_function(tolua_S,"IsTool",tolua_AllToLua_ItemCategory_IsTool00); + tolua_endmodule(tolua_S); + tolua_constant(tolua_S,"eGameMode_Survival",eGameMode_Survival); + tolua_constant(tolua_S,"eGameMode_Creative",eGameMode_Creative); + tolua_constant(tolua_S,"eWeather_Sunny",eWeather_Sunny); + tolua_constant(tolua_S,"eWeather_Rain",eWeather_Rain); + tolua_constant(tolua_S,"eWeather_ThunderStorm",eWeather_ThunderStorm); + tolua_function(tolua_S,"GetTime",tolua_AllToLua_GetTime00); + tolua_function(tolua_S,"GetChar",tolua_AllToLua_GetChar00); + tolua_cclass(tolua_S,"cStringMap","cStringMap","",NULL); + tolua_beginmodule(tolua_S,"cStringMap"); + tolua_function(tolua_S,"clear",tolua_AllToLua_cStringMap_clear00); + tolua_function(tolua_S,"size",tolua_AllToLua_cStringMap_size00); + tolua_function(tolua_S,"get",tolua_AllToLua_cStringMap_get00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cChatColor","cChatColor","",NULL); + tolua_beginmodule(tolua_S,"cChatColor"); + tolua_variable(tolua_S,"Color",tolua_get_cChatColor_Color,NULL); + tolua_variable(tolua_S,"Delimiter",tolua_get_cChatColor_Delimiter,NULL); + tolua_variable(tolua_S,"Black",tolua_get_cChatColor_Black,NULL); + tolua_variable(tolua_S,"Navy",tolua_get_cChatColor_Navy,NULL); + tolua_variable(tolua_S,"Green",tolua_get_cChatColor_Green,NULL); + tolua_variable(tolua_S,"Blue",tolua_get_cChatColor_Blue,NULL); + tolua_variable(tolua_S,"Red",tolua_get_cChatColor_Red,NULL); + tolua_variable(tolua_S,"Purple",tolua_get_cChatColor_Purple,NULL); + tolua_variable(tolua_S,"Gold",tolua_get_cChatColor_Gold,NULL); + tolua_variable(tolua_S,"LightGray",tolua_get_cChatColor_LightGray,NULL); + tolua_variable(tolua_S,"Gray",tolua_get_cChatColor_Gray,NULL); + tolua_variable(tolua_S,"DarkPurple",tolua_get_cChatColor_DarkPurple,NULL); + tolua_variable(tolua_S,"LightGreen",tolua_get_cChatColor_LightGreen,NULL); + tolua_variable(tolua_S,"LightBlue",tolua_get_cChatColor_LightBlue,NULL); + tolua_variable(tolua_S,"Rose",tolua_get_cChatColor_Rose,NULL); + tolua_variable(tolua_S,"LightPurple",tolua_get_cChatColor_LightPurple,NULL); + tolua_variable(tolua_S,"Yellow",tolua_get_cChatColor_Yellow,NULL); + tolua_variable(tolua_S,"White",tolua_get_cChatColor_White,NULL); + tolua_variable(tolua_S,"Random",tolua_get_cChatColor_Random,NULL); + tolua_variable(tolua_S,"Bold",tolua_get_cChatColor_Bold,NULL); + tolua_variable(tolua_S,"Strikethrough",tolua_get_cChatColor_Strikethrough,NULL); + tolua_variable(tolua_S,"Underlined",tolua_get_cChatColor_Underlined,NULL); + tolua_variable(tolua_S,"Italic",tolua_get_cChatColor_Italic,NULL); + tolua_variable(tolua_S,"Plain",tolua_get_cChatColor_Plain,NULL); + tolua_function(tolua_S,"MakeColor",tolua_AllToLua_cChatColor_MakeColor00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cClientHandle","cClientHandle","",NULL); + tolua_beginmodule(tolua_S,"cClientHandle"); + tolua_function(tolua_S,"GetPlayer",tolua_AllToLua_cClientHandle_GetPlayer00); + tolua_function(tolua_S,"Kick",tolua_AllToLua_cClientHandle_Kick00); + tolua_function(tolua_S,"GetUsername",tolua_AllToLua_cClientHandle_GetUsername00); + tolua_function(tolua_S,"GetPing",tolua_AllToLua_cClientHandle_GetPing00); + tolua_function(tolua_S,"SetViewDistance",tolua_AllToLua_cClientHandle_SetViewDistance00); + tolua_function(tolua_S,"GetViewDistance",tolua_AllToLua_cClientHandle_GetViewDistance00); + tolua_function(tolua_S,"GetUniqueID",tolua_AllToLua_cClientHandle_GetUniqueID00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cEntity","cEntity","",tolua_collect_cEntity); + #else + tolua_cclass(tolua_S,"cEntity","cEntity","",NULL); + #endif + tolua_beginmodule(tolua_S,"cEntity"); + tolua_function(tolua_S,"delete",tolua_AllToLua_cEntity_delete00); + tolua_function(tolua_S,"Initialize",tolua_AllToLua_cEntity_Initialize00); + tolua_constant(tolua_S,"eEntityType_Entity",cEntity::eEntityType_Entity); + tolua_constant(tolua_S,"eEntityType_Player",cEntity::eEntityType_Player); + tolua_constant(tolua_S,"eEntityType_Pickup",cEntity::eEntityType_Pickup); + tolua_function(tolua_S,"GetEntityType",tolua_AllToLua_cEntity_GetEntityType00); + tolua_function(tolua_S,"IsA",tolua_AllToLua_cEntity_IsA00); + tolua_function(tolua_S,"GetClass",tolua_AllToLua_cEntity_GetClass00); + tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cEntity_GetWorld00); + tolua_function(tolua_S,"GetPosition",tolua_AllToLua_cEntity_GetPosition00); + tolua_function(tolua_S,"GetPosX",tolua_AllToLua_cEntity_GetPosX00); + tolua_function(tolua_S,"GetPosY",tolua_AllToLua_cEntity_GetPosY00); + tolua_function(tolua_S,"GetPosZ",tolua_AllToLua_cEntity_GetPosZ00); + tolua_function(tolua_S,"GetRot",tolua_AllToLua_cEntity_GetRot00); + tolua_function(tolua_S,"GetRotation",tolua_AllToLua_cEntity_GetRotation00); + tolua_function(tolua_S,"GetPitch",tolua_AllToLua_cEntity_GetPitch00); + tolua_function(tolua_S,"GetRoll",tolua_AllToLua_cEntity_GetRoll00); + tolua_function(tolua_S,"GetLookVector",tolua_AllToLua_cEntity_GetLookVector00); + tolua_function(tolua_S,"GetChunkX",tolua_AllToLua_cEntity_GetChunkX00); + tolua_function(tolua_S,"GetChunkY",tolua_AllToLua_cEntity_GetChunkY00); + tolua_function(tolua_S,"GetChunkZ",tolua_AllToLua_cEntity_GetChunkZ00); + tolua_function(tolua_S,"SetPosX",tolua_AllToLua_cEntity_SetPosX00); + tolua_function(tolua_S,"SetPosY",tolua_AllToLua_cEntity_SetPosY00); + tolua_function(tolua_S,"SetPosZ",tolua_AllToLua_cEntity_SetPosZ00); + tolua_function(tolua_S,"SetPosition",tolua_AllToLua_cEntity_SetPosition00); + tolua_function(tolua_S,"SetPosition",tolua_AllToLua_cEntity_SetPosition01); + tolua_function(tolua_S,"SetRot",tolua_AllToLua_cEntity_SetRot00); + tolua_function(tolua_S,"SetRotation",tolua_AllToLua_cEntity_SetRotation00); + tolua_function(tolua_S,"SetPitch",tolua_AllToLua_cEntity_SetPitch00); + tolua_function(tolua_S,"SetRoll",tolua_AllToLua_cEntity_SetRoll00); + tolua_function(tolua_S,"GetUniqueID",tolua_AllToLua_cEntity_GetUniqueID00); + tolua_function(tolua_S,"IsDestroyed",tolua_AllToLua_cEntity_IsDestroyed00); + tolua_function(tolua_S,"Destroy",tolua_AllToLua_cEntity_Destroy00); + tolua_function(tolua_S,"Tick",tolua_AllToLua_cEntity_Tick00); + tolua_function(tolua_S,"SpawnOn",tolua_AllToLua_cEntity_SpawnOn00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Lua__cEntity","Lua__cEntity","cEntity",tolua_collect_Lua__cEntity); + #else + tolua_cclass(tolua_S,"Lua__cEntity","Lua__cEntity","cEntity",NULL); + #endif + tolua_beginmodule(tolua_S,"Lua__cEntity"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cEntity_tolua__set_instance00); + tolua_function(tolua_S,"cEntity__Initialize",tolua_AllToLua_Lua__cEntity_cEntity__Initialize00); + tolua_function(tolua_S,"cEntity__GetEntityType",tolua_AllToLua_Lua__cEntity_cEntity__GetEntityType00); + tolua_function(tolua_S,"cEntity__IsA",tolua_AllToLua_Lua__cEntity_cEntity__IsA00); + tolua_function(tolua_S,"cEntity__GetClass",tolua_AllToLua_Lua__cEntity_cEntity__GetClass00); + tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cEntity_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cEntity_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cEntity_new00_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cEntity_delete00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"TakeDamageInfo","TakeDamageInfo","",NULL); + tolua_beginmodule(tolua_S,"TakeDamageInfo"); + tolua_variable(tolua_S,"Damage",tolua_get_TakeDamageInfo_Damage,tolua_set_TakeDamageInfo_Damage); + tolua_variable(tolua_S,"Instigator",tolua_get_TakeDamageInfo_Instigator_ptr,tolua_set_TakeDamageInfo_Instigator_ptr); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cPawn","cPawn","cEntity",NULL); + tolua_beginmodule(tolua_S,"cPawn"); + tolua_function(tolua_S,"TeleportToEntity",tolua_AllToLua_cPawn_TeleportToEntity00); + tolua_function(tolua_S,"TeleportTo",tolua_AllToLua_cPawn_TeleportTo00); + tolua_function(tolua_S,"Heal",tolua_AllToLua_cPawn_Heal00); + tolua_function(tolua_S,"TakeDamage",tolua_AllToLua_cPawn_TakeDamage00); + tolua_function(tolua_S,"KilledBy",tolua_AllToLua_cPawn_KilledBy00); + tolua_function(tolua_S,"GetHealth",tolua_AllToLua_cPawn_GetHealth00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"Lua__cPawn","Lua__cPawn","cPawn",NULL); + tolua_beginmodule(tolua_S,"Lua__cPawn"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPawn_tolua__set_instance00); + tolua_function(tolua_S,"cPawn__TeleportToEntity",tolua_AllToLua_Lua__cPawn_cPawn__TeleportToEntity00); + tolua_function(tolua_S,"cPawn__TeleportTo",tolua_AllToLua_Lua__cPawn_cPawn__TeleportTo00); + tolua_function(tolua_S,"cPawn__TakeDamage",tolua_AllToLua_Lua__cPawn_cPawn__TakeDamage00); + tolua_function(tolua_S,"cPawn__KilledBy",tolua_AllToLua_Lua__cPawn_cPawn__KilledBy00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cPlayer","cPlayer","cPawn",NULL); + tolua_beginmodule(tolua_S,"cPlayer"); + tolua_function(tolua_S,"Initialize",tolua_AllToLua_cPlayer_Initialize00); + tolua_function(tolua_S,"GetEyeHeight",tolua_AllToLua_cPlayer_GetEyeHeight00); + tolua_function(tolua_S,"GetEyePosition",tolua_AllToLua_cPlayer_GetEyePosition00); + tolua_function(tolua_S,"GetFlying",tolua_AllToLua_cPlayer_GetFlying00); + tolua_function(tolua_S,"GetStance",tolua_AllToLua_cPlayer_GetStance00); + tolua_function(tolua_S,"GetInventory",tolua_AllToLua_cPlayer_GetInventory00); + tolua_function(tolua_S,"TeleportTo",tolua_AllToLua_cPlayer_TeleportTo00); + tolua_function(tolua_S,"GetGameMode",tolua_AllToLua_cPlayer_GetGameMode00); + tolua_function(tolua_S,"GetIP",tolua_AllToLua_cPlayer_GetIP00); + tolua_function(tolua_S,"GetLastBlockActionTime",tolua_AllToLua_cPlayer_GetLastBlockActionTime00); + tolua_function(tolua_S,"GetLastBlockActionCnt",tolua_AllToLua_cPlayer_GetLastBlockActionCnt00); + tolua_function(tolua_S,"SetLastBlockActionCnt",tolua_AllToLua_cPlayer_SetLastBlockActionCnt00); + tolua_function(tolua_S,"SetLastBlockActionTime",tolua_AllToLua_cPlayer_SetLastBlockActionTime00); + tolua_function(tolua_S,"SetGameMode",tolua_AllToLua_cPlayer_SetGameMode00); + tolua_function(tolua_S,"MoveTo",tolua_AllToLua_cPlayer_MoveTo00); + tolua_function(tolua_S,"GetClientHandle",tolua_AllToLua_cPlayer_GetClientHandle00); + tolua_function(tolua_S,"SendMessage",tolua_AllToLua_cPlayer_SendMessage00); + tolua_function(tolua_S,"GetName",tolua_AllToLua_cPlayer_GetName00); + tolua_function(tolua_S,"SetName",tolua_AllToLua_cPlayer_SetName00); + tolua_function(tolua_S,"AddToGroup",tolua_AllToLua_cPlayer_AddToGroup00); + tolua_function(tolua_S,"CanUseCommand",tolua_AllToLua_cPlayer_CanUseCommand00); + tolua_function(tolua_S,"HasPermission",tolua_AllToLua_cPlayer_HasPermission00); + tolua_function(tolua_S,"IsInGroup",tolua_AllToLua_cPlayer_IsInGroup00); + tolua_function(tolua_S,"GetColor",tolua_AllToLua_cPlayer_GetColor00); + tolua_function(tolua_S,"TossItem",tolua_AllToLua_cPlayer_TossItem00); + tolua_function(tolua_S,"Heal",tolua_AllToLua_cPlayer_Heal00); + tolua_function(tolua_S,"TakeDamage",tolua_AllToLua_cPlayer_TakeDamage00); + tolua_function(tolua_S,"KilledBy",tolua_AllToLua_cPlayer_KilledBy00); + tolua_function(tolua_S,"Respawn",tolua_AllToLua_cPlayer_Respawn00); + tolua_function(tolua_S,"SetVisible",tolua_AllToLua_cPlayer_SetVisible00); + tolua_function(tolua_S,"IsVisible",tolua_AllToLua_cPlayer_IsVisible00); + tolua_function(tolua_S,"MoveToWorld",tolua_AllToLua_cPlayer_MoveToWorld00); + tolua_function(tolua_S,"LoadPermissionsFromDisk",tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"Lua__cPlayer","Lua__cPlayer","cPlayer",NULL); + tolua_beginmodule(tolua_S,"Lua__cPlayer"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPlayer_tolua__set_instance00); + tolua_function(tolua_S,"cPlayer__Initialize",tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00); + tolua_function(tolua_S,"cPlayer__TeleportTo",tolua_AllToLua_Lua__cPlayer_cPlayer__TeleportTo00); + tolua_function(tolua_S,"cPlayer__MoveTo",tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cPluginManager","cPluginManager","",NULL); + tolua_beginmodule(tolua_S,"cPluginManager"); + tolua_constant(tolua_S,"HOOK_TICK",cPluginManager::HOOK_TICK); + tolua_constant(tolua_S,"HOOK_CHAT",cPluginManager::HOOK_CHAT); + tolua_constant(tolua_S,"HOOK_COLLECT_ITEM",cPluginManager::HOOK_COLLECT_ITEM); + tolua_constant(tolua_S,"HOOK_BLOCK_DIG",cPluginManager::HOOK_BLOCK_DIG); + tolua_constant(tolua_S,"HOOK_BLOCK_PLACE",cPluginManager::HOOK_BLOCK_PLACE); + tolua_constant(tolua_S,"HOOK_DISCONNECT",cPluginManager::HOOK_DISCONNECT); + tolua_constant(tolua_S,"HOOK_HANDSHAKE",cPluginManager::HOOK_HANDSHAKE); + tolua_constant(tolua_S,"HOOK_LOGIN",cPluginManager::HOOK_LOGIN); + tolua_constant(tolua_S,"HOOK_PLAYER_SPAWN",cPluginManager::HOOK_PLAYER_SPAWN); + tolua_constant(tolua_S,"HOOK_PLAYER_JOIN",cPluginManager::HOOK_PLAYER_JOIN); + tolua_constant(tolua_S,"HOOK_PLAYER_MOVE",cPluginManager::HOOK_PLAYER_MOVE); + tolua_constant(tolua_S,"HOOK_TAKE_DAMAGE",cPluginManager::HOOK_TAKE_DAMAGE); + tolua_constant(tolua_S,"HOOK_KILLED",cPluginManager::HOOK_KILLED); + tolua_constant(tolua_S,"HOOK_CHUNK_GENERATED",cPluginManager::HOOK_CHUNK_GENERATED); + tolua_constant(tolua_S,"HOOK_CHUNK_GENERATING",cPluginManager::HOOK_CHUNK_GENERATING); + tolua_constant(tolua_S,"HOOK_BLOCK_TO_DROPS",cPluginManager::HOOK_BLOCK_TO_DROPS); + tolua_constant(tolua_S,"HOOK_PRE_CRAFTING",cPluginManager::HOOK_PRE_CRAFTING); + tolua_constant(tolua_S,"HOOK_CRAFTING_NO_RECIPE",cPluginManager::HOOK_CRAFTING_NO_RECIPE); + tolua_constant(tolua_S,"HOOK_POST_CRAFTING",cPluginManager::HOOK_POST_CRAFTING); + tolua_constant(tolua_S,"HOOK_BLOCK_TO_PICKUP",cPluginManager::HOOK_BLOCK_TO_PICKUP); + tolua_constant(tolua_S,"HOOK_WEATHER_CHANGE",cPluginManager::HOOK_WEATHER_CHANGE); + tolua_constant(tolua_S,"E_PLUGIN_TICK",cPluginManager::E_PLUGIN_TICK); + tolua_constant(tolua_S,"E_PLUGIN_CHAT",cPluginManager::E_PLUGIN_CHAT); + tolua_constant(tolua_S,"E_PLUGIN_COLLECT_ITEM",cPluginManager::E_PLUGIN_COLLECT_ITEM); + tolua_constant(tolua_S,"E_PLUGIN_BLOCK_DIG",cPluginManager::E_PLUGIN_BLOCK_DIG); + tolua_constant(tolua_S,"E_PLUGIN_BLOCK_PLACE",cPluginManager::E_PLUGIN_BLOCK_PLACE); + tolua_constant(tolua_S,"E_PLUGIN_DISCONNECT",cPluginManager::E_PLUGIN_DISCONNECT); + tolua_constant(tolua_S,"E_PLUGIN_HANDSHAKE",cPluginManager::E_PLUGIN_HANDSHAKE); + tolua_constant(tolua_S,"E_PLUGIN_LOGIN",cPluginManager::E_PLUGIN_LOGIN); + tolua_constant(tolua_S,"E_PLUGIN_PLAYER_SPAWN",cPluginManager::E_PLUGIN_PLAYER_SPAWN); + tolua_constant(tolua_S,"E_PLUGIN_PLAYER_JOIN",cPluginManager::E_PLUGIN_PLAYER_JOIN); + tolua_constant(tolua_S,"E_PLUGIN_PLAYER_MOVE",cPluginManager::E_PLUGIN_PLAYER_MOVE); + tolua_constant(tolua_S,"E_PLUGIN_TAKE_DAMAGE",cPluginManager::E_PLUGIN_TAKE_DAMAGE); + tolua_constant(tolua_S,"E_PLUGIN_KILLED",cPluginManager::E_PLUGIN_KILLED); + tolua_constant(tolua_S,"E_PLUGIN_CHUNK_GENERATED",cPluginManager::E_PLUGIN_CHUNK_GENERATED); + tolua_constant(tolua_S,"E_PLUGIN_CHUNK_GENERATING",cPluginManager::E_PLUGIN_CHUNK_GENERATING); + tolua_constant(tolua_S,"E_PLUGIN_BLOCK_TO_DROPS",cPluginManager::E_PLUGIN_BLOCK_TO_DROPS); + tolua_function(tolua_S,"GetPluginManager",tolua_AllToLua_cPluginManager_GetPluginManager00); + tolua_function(tolua_S,"GetPlugin",tolua_AllToLua_cPluginManager_GetPlugin00); + tolua_function(tolua_S,"ReloadPlugins",tolua_AllToLua_cPluginManager_ReloadPlugins00); + tolua_function(tolua_S,"AddPlugin",tolua_AllToLua_cPluginManager_AddPlugin00); + tolua_function(tolua_S,"AddHook",tolua_AllToLua_cPluginManager_AddHook00); + tolua_function(tolua_S,"GetNumPlugins",tolua_AllToLua_cPluginManager_GetNumPlugins00); + tolua_function(tolua_S,"RemovePlugin",tolua_AllToLua_cPluginManager_RemovePlugin00); + tolua_function(tolua_S,"RemoveLuaPlugin",tolua_AllToLua_cPluginManager_RemoveLuaPlugin00); + tolua_function(tolua_S,"GetLuaPlugin",tolua_AllToLua_cPluginManager_GetLuaPlugin00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cPlugin","cPlugin","",tolua_collect_cPlugin); + #else + tolua_cclass(tolua_S,"cPlugin","cPlugin","",NULL); + #endif + tolua_beginmodule(tolua_S,"cPlugin"); + tolua_function(tolua_S,"delete",tolua_AllToLua_cPlugin_delete00); + tolua_function(tolua_S,"OnDisable",tolua_AllToLua_cPlugin_OnDisable00); + tolua_function(tolua_S,"Initialize",tolua_AllToLua_cPlugin_Initialize00); + tolua_function(tolua_S,"Tick",tolua_AllToLua_cPlugin_Tick00); + tolua_function(tolua_S,"OnCollectItem",tolua_AllToLua_cPlugin_OnCollectItem00); + tolua_function(tolua_S,"OnDisconnect",tolua_AllToLua_cPlugin_OnDisconnect00); + tolua_function(tolua_S,"OnBlockPlace",tolua_AllToLua_cPlugin_OnBlockPlace00); + tolua_function(tolua_S,"OnBlockDig",tolua_AllToLua_cPlugin_OnBlockDig00); + tolua_function(tolua_S,"OnChat",tolua_AllToLua_cPlugin_OnChat00); + tolua_function(tolua_S,"OnLogin",tolua_AllToLua_cPlugin_OnLogin00); + tolua_function(tolua_S,"OnPlayerSpawn",tolua_AllToLua_cPlugin_OnPlayerSpawn00); + tolua_function(tolua_S,"OnPlayerJoin",tolua_AllToLua_cPlugin_OnPlayerJoin00); + tolua_function(tolua_S,"OnPlayerMove",tolua_AllToLua_cPlugin_OnPlayerMove00); + tolua_function(tolua_S,"OnTakeDamage",tolua_AllToLua_cPlugin_OnTakeDamage00); + tolua_function(tolua_S,"OnKilled",tolua_AllToLua_cPlugin_OnKilled00); + tolua_function(tolua_S,"OnChunkGenerated",tolua_AllToLua_cPlugin_OnChunkGenerated00); + tolua_function(tolua_S,"OnChunkGenerating",tolua_AllToLua_cPlugin_OnChunkGenerating00); + tolua_function(tolua_S,"OnPreCrafting",tolua_AllToLua_cPlugin_OnPreCrafting00); + tolua_function(tolua_S,"OnCraftingNoRecipe",tolua_AllToLua_cPlugin_OnCraftingNoRecipe00); + tolua_function(tolua_S,"OnPostCrafting",tolua_AllToLua_cPlugin_OnPostCrafting00); + tolua_function(tolua_S,"OnBlockToPickup",tolua_AllToLua_cPlugin_OnBlockToPickup00); + tolua_function(tolua_S,"GetName",tolua_AllToLua_cPlugin_GetName00); + tolua_function(tolua_S,"SetName",tolua_AllToLua_cPlugin_SetName00); + tolua_function(tolua_S,"GetVersion",tolua_AllToLua_cPlugin_GetVersion00); + tolua_function(tolua_S,"SetVersion",tolua_AllToLua_cPlugin_SetVersion00); + tolua_cclass(tolua_S,"CommandStruct","cPlugin::CommandStruct","",NULL); + tolua_beginmodule(tolua_S,"CommandStruct"); + tolua_variable(tolua_S,"Command",tolua_get_cPlugin__CommandStruct_Command,tolua_set_cPlugin__CommandStruct_Command); + tolua_variable(tolua_S,"Description",tolua_get_cPlugin__CommandStruct_Description,tolua_set_cPlugin__CommandStruct_Description); + tolua_variable(tolua_S,"Permission",tolua_get_cPlugin__CommandStruct_Permission,tolua_set_cPlugin__CommandStruct_Permission); + tolua_endmodule(tolua_S); + tolua_function(tolua_S,"AddCommand",tolua_AllToLua_cPlugin_AddCommand00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Lua__cPlugin","Lua__cPlugin","cPlugin",tolua_collect_Lua__cPlugin); + #else + tolua_cclass(tolua_S,"Lua__cPlugin","Lua__cPlugin","cPlugin",NULL); + #endif + tolua_beginmodule(tolua_S,"Lua__cPlugin"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPlugin_tolua__set_instance00); + tolua_function(tolua_S,"cPlugin__OnDisable",tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisable00); + tolua_function(tolua_S,"cPlugin__Tick",tolua_AllToLua_Lua__cPlugin_cPlugin__Tick00); + tolua_function(tolua_S,"cPlugin__OnCollectItem",tolua_AllToLua_Lua__cPlugin_cPlugin__OnCollectItem00); + tolua_function(tolua_S,"cPlugin__OnDisconnect",tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00); + tolua_function(tolua_S,"cPlugin__OnBlockPlace",tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockPlace00); + tolua_function(tolua_S,"cPlugin__OnBlockDig",tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockDig00); + tolua_function(tolua_S,"cPlugin__OnChat",tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00); + tolua_function(tolua_S,"cPlugin__OnLogin",tolua_AllToLua_Lua__cPlugin_cPlugin__OnLogin00); + tolua_function(tolua_S,"cPlugin__OnPlayerSpawn",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerSpawn00); + tolua_function(tolua_S,"cPlugin__OnPlayerJoin",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerJoin00); + tolua_function(tolua_S,"cPlugin__OnPlayerMove",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPlayerMove00); + tolua_function(tolua_S,"cPlugin__OnTakeDamage",tolua_AllToLua_Lua__cPlugin_cPlugin__OnTakeDamage00); + tolua_function(tolua_S,"cPlugin__OnKilled",tolua_AllToLua_Lua__cPlugin_cPlugin__OnKilled00); + tolua_function(tolua_S,"cPlugin__OnChunkGenerated",tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerated00); + tolua_function(tolua_S,"cPlugin__OnChunkGenerating",tolua_AllToLua_Lua__cPlugin_cPlugin__OnChunkGenerating00); + tolua_function(tolua_S,"cPlugin__OnPreCrafting",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPreCrafting00); + tolua_function(tolua_S,"cPlugin__OnCraftingNoRecipe",tolua_AllToLua_Lua__cPlugin_cPlugin__OnCraftingNoRecipe00); + tolua_function(tolua_S,"cPlugin__OnPostCrafting",tolua_AllToLua_Lua__cPlugin_cPlugin__OnPostCrafting00); + tolua_function(tolua_S,"cPlugin__OnBlockToPickup",tolua_AllToLua_Lua__cPlugin_cPlugin__OnBlockToPickup00); + tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPlugin_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPlugin_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPlugin_new00_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cPlugin_delete00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cPlugin_NewLua","cPlugin_NewLua","cPlugin",NULL); + tolua_beginmodule(tolua_S,"cPlugin_NewLua"); + tolua_function(tolua_S,"OnDisable",tolua_AllToLua_cPlugin_NewLua_OnDisable00); + tolua_function(tolua_S,"Initialize",tolua_AllToLua_cPlugin_NewLua_Initialize00); + tolua_function(tolua_S,"Tick",tolua_AllToLua_cPlugin_NewLua_Tick00); + tolua_function(tolua_S,"CreateWebPlugin",tolua_AllToLua_cPlugin_NewLua_CreateWebPlugin00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"Lua__cPlugin_NewLua","Lua__cPlugin_NewLua","cPlugin_NewLua",NULL); + tolua_beginmodule(tolua_S,"Lua__cPlugin_NewLua"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPlugin_NewLua_tolua__set_instance00); + tolua_function(tolua_S,"cPlugin_NewLua__OnDisable",tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__OnDisable00); + tolua_function(tolua_S,"cPlugin_NewLua__Initialize",tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Initialize00); + tolua_function(tolua_S,"cPlugin_NewLua__Tick",tolua_AllToLua_Lua__cPlugin_NewLua_cPlugin_NewLua__Tick00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cPlugin_Lua","cPlugin_Lua","",NULL); + tolua_beginmodule(tolua_S,"cPlugin_Lua"); + tolua_function(tolua_S,"GetFileName",tolua_AllToLua_cPlugin_Lua_GetFileName00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cServer","cServer","",NULL); + tolua_beginmodule(tolua_S,"cServer"); + tolua_function(tolua_S,"GetServer",tolua_AllToLua_cServer_GetServer00); + tolua_function(tolua_S,"ServerCommand",tolua_AllToLua_cServer_ServerCommand00); + tolua_function(tolua_S,"SendMessage",tolua_AllToLua_cServer_SendMessage00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cWorld","cWorld","",NULL); + tolua_beginmodule(tolua_S,"cWorld"); + tolua_function(tolua_S,"GetTime",tolua_AllToLua_cWorld_GetTime00); + tolua_function(tolua_S,"GetGameMode",tolua_AllToLua_cWorld_GetGameMode00); + tolua_function(tolua_S,"SetWorldTime",tolua_AllToLua_cWorld_SetWorldTime00); + tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cWorld_GetHeight00); + tolua_function(tolua_S,"UnloadUnusedChunks",tolua_AllToLua_cWorld_UnloadUnusedChunks00); + tolua_function(tolua_S,"GetMaxPlayers",tolua_AllToLua_cWorld_GetMaxPlayers00); + tolua_function(tolua_S,"SetMaxPlayers",tolua_AllToLua_cWorld_SetMaxPlayers00); + tolua_function(tolua_S,"GetNumPlayers",tolua_AllToLua_cWorld_GetNumPlayers00); + tolua_function(tolua_S,"GetPlayer",tolua_AllToLua_cWorld_GetPlayer00); + tolua_function(tolua_S,"UpdateSign",tolua_AllToLua_cWorld_UpdateSign00); + tolua_function(tolua_S,"RegenerateChunk",tolua_AllToLua_cWorld_RegenerateChunk00); + tolua_function(tolua_S,"GenerateChunk",tolua_AllToLua_cWorld_GenerateChunk00); + tolua_function(tolua_S,"SetBlock",tolua_AllToLua_cWorld_SetBlock00); + tolua_function(tolua_S,"FastSetBlock",tolua_AllToLua_cWorld_FastSetBlock00); + tolua_function(tolua_S,"GetBlock",tolua_AllToLua_cWorld_GetBlock00); + tolua_function(tolua_S,"GetBlock",tolua_AllToLua_cWorld_GetBlock01); + tolua_function(tolua_S,"GetBlockMeta",tolua_AllToLua_cWorld_GetBlockMeta00); + tolua_function(tolua_S,"GetBlockMeta",tolua_AllToLua_cWorld_GetBlockMeta01); + tolua_function(tolua_S,"SetBlockMeta",tolua_AllToLua_cWorld_SetBlockMeta00); + tolua_function(tolua_S,"SetBlockMeta",tolua_AllToLua_cWorld_SetBlockMeta01); + tolua_function(tolua_S,"GetBlockSkyLight",tolua_AllToLua_cWorld_GetBlockSkyLight00); + tolua_function(tolua_S,"GetBlockTypeMeta",tolua_AllToLua_cWorld_GetBlockTypeMeta00); + tolua_function(tolua_S,"DigBlock",tolua_AllToLua_cWorld_DigBlock00); + tolua_function(tolua_S,"SendBlockTo",tolua_AllToLua_cWorld_SendBlockTo00); + tolua_function(tolua_S,"GetSpawnX",tolua_AllToLua_cWorld_GetSpawnX00); + tolua_function(tolua_S,"GetSpawnY",tolua_AllToLua_cWorld_GetSpawnY00); + tolua_function(tolua_S,"GetSpawnZ",tolua_AllToLua_cWorld_GetSpawnZ00); + tolua_function(tolua_S,"GetBlockEntity",tolua_AllToLua_cWorld_GetBlockEntity00); + tolua_function(tolua_S,"GrowTree",tolua_AllToLua_cWorld_GrowTree00); + tolua_function(tolua_S,"GrowTreeFromSapling",tolua_AllToLua_cWorld_GrowTreeFromSapling00); + tolua_function(tolua_S,"GrowTreeByBiome",tolua_AllToLua_cWorld_GrowTreeByBiome00); + tolua_function(tolua_S,"GrowPlant",tolua_AllToLua_cWorld_GrowPlant00); + tolua_function(tolua_S,"GrowMelonPumpkin",tolua_AllToLua_cWorld_GrowMelonPumpkin00); + tolua_function(tolua_S,"GetBiomeAt",tolua_AllToLua_cWorld_GetBiomeAt00); + tolua_function(tolua_S,"GetName",tolua_AllToLua_cWorld_GetName00); + tolua_function(tolua_S,"SaveAllChunks",tolua_AllToLua_cWorld_SaveAllChunks00); + tolua_function(tolua_S,"GetNumChunks",tolua_AllToLua_cWorld_GetNumChunks00); + tolua_function(tolua_S,"GetGeneratorQueueLength",tolua_AllToLua_cWorld_GetGeneratorQueueLength00); + tolua_function(tolua_S,"GetLightingQueueLength",tolua_AllToLua_cWorld_GetLightingQueueLength00); + tolua_function(tolua_S,"GetStorageLoadQueueLength",tolua_AllToLua_cWorld_GetStorageLoadQueueLength00); + tolua_function(tolua_S,"GetStorageSaveQueueLength",tolua_AllToLua_cWorld_GetStorageSaveQueueLength00); + tolua_function(tolua_S,"CastThunderbolt",tolua_AllToLua_cWorld_CastThunderbolt00); + tolua_function(tolua_S,"SetWeather",tolua_AllToLua_cWorld_SetWeather00); + tolua_function(tolua_S,"ChangeWeather",tolua_AllToLua_cWorld_ChangeWeather00); + tolua_function(tolua_S,"GetWeather",tolua_AllToLua_cWorld_GetWeather00); + tolua_function(tolua_S,"SetNextBlockTick",tolua_AllToLua_cWorld_SetNextBlockTick00); + tolua_function(tolua_S,"GetMaxSugarcaneHeight",tolua_AllToLua_cWorld_GetMaxSugarcaneHeight00); + tolua_function(tolua_S,"GetMaxCactusHeight",tolua_AllToLua_cWorld_GetMaxCactusHeight00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cInventory","cInventory","",NULL); + tolua_beginmodule(tolua_S,"cInventory"); + tolua_function(tolua_S,"Clear",tolua_AllToLua_cInventory_Clear00); + tolua_function(tolua_S,"AddItem",tolua_AllToLua_cInventory_AddItem00); + tolua_function(tolua_S,"RemoveItem",tolua_AllToLua_cInventory_RemoveItem00); + tolua_function(tolua_S,"GetSlot",tolua_AllToLua_cInventory_GetSlot00); + tolua_function(tolua_S,"GetFromHotBar",tolua_AllToLua_cInventory_GetFromHotBar00); + tolua_function(tolua_S,"GetEquippedItem",tolua_AllToLua_cInventory_GetEquippedItem00); + tolua_function(tolua_S,"SetEquippedSlot",tolua_AllToLua_cInventory_SetEquippedSlot00); + tolua_function(tolua_S,"GetEquippedSlot",tolua_AllToLua_cInventory_GetEquippedSlot00); + tolua_function(tolua_S,"SendSlot",tolua_AllToLua_cInventory_SendSlot00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cItem","cItem","",tolua_collect_cItem); + #else + tolua_cclass(tolua_S,"cItem","cItem","",NULL); + #endif + tolua_beginmodule(tolua_S,"cItem"); + tolua_function(tolua_S,"new",tolua_AllToLua_cItem_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cItem_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cItem_new00_local); + tolua_function(tolua_S,"Empty",tolua_AllToLua_cItem_Empty00); + tolua_function(tolua_S,"Clear",tolua_AllToLua_cItem_Clear00); + tolua_function(tolua_S,"IsEmpty",tolua_AllToLua_cItem_IsEmpty00); + tolua_function(tolua_S,"Equals",tolua_AllToLua_cItem_Equals00); + tolua_function(tolua_S,"GetMaxDuration",tolua_AllToLua_cItem_GetMaxDuration00); + tolua_function(tolua_S,"DamageItem",tolua_AllToLua_cItem_DamageItem00); + tolua_function(tolua_S,"HasDuration",tolua_AllToLua_cItem_HasDuration00); + tolua_function(tolua_S,"GetJson",tolua_AllToLua_cItem_GetJson00); + tolua_function(tolua_S,"FromJson",tolua_AllToLua_cItem_FromJson00); + tolua_function(tolua_S,"IsEnchantable",tolua_AllToLua_cItem_IsEnchantable00); + tolua_variable(tolua_S,"m_ItemID",tolua_get_cItem_m_ItemID,tolua_set_cItem_m_ItemID); + tolua_variable(tolua_S,"m_ItemCount",tolua_get_cItem_m_ItemCount,tolua_set_cItem_m_ItemCount); + tolua_variable(tolua_S,"m_ItemHealth",tolua_get_cItem_m_ItemHealth,tolua_set_cItem_m_ItemHealth); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"HTTPFormData","HTTPFormData","",NULL); + tolua_beginmodule(tolua_S,"HTTPFormData"); + tolua_variable(tolua_S,"Name",tolua_get_HTTPFormData_Name,tolua_set_HTTPFormData_Name); + tolua_variable(tolua_S,"Value",tolua_get_HTTPFormData_Value,tolua_set_HTTPFormData_Value); + tolua_variable(tolua_S,"Type",tolua_get_HTTPFormData_Type,tolua_set_HTTPFormData_Type); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"HTTPRequest","HTTPRequest","",NULL); + tolua_beginmodule(tolua_S,"HTTPRequest"); + tolua_variable(tolua_S,"Method",tolua_get_HTTPRequest_Method,tolua_set_HTTPRequest_Method); + tolua_variable(tolua_S,"Path",tolua_get_HTTPRequest_Path,tolua_set_HTTPRequest_Path); + tolua_variable(tolua_S,"Username",tolua_get_HTTPRequest_Username,tolua_set_HTTPRequest_Username); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cWebPlugin","cWebPlugin","",tolua_collect_cWebPlugin); + #else + tolua_cclass(tolua_S,"cWebPlugin","cWebPlugin","",NULL); + #endif + tolua_beginmodule(tolua_S,"cWebPlugin"); + tolua_function(tolua_S,"delete",tolua_AllToLua_cWebPlugin_delete00); + tolua_function(tolua_S,"SetName",tolua_AllToLua_cWebPlugin_SetName00); + tolua_function(tolua_S,"GetName",tolua_AllToLua_cWebPlugin_GetName00); + tolua_function(tolua_S,"HandleRequest",tolua_AllToLua_cWebPlugin_HandleRequest00); + tolua_function(tolua_S,"Initialize",tolua_AllToLua_cWebPlugin_Initialize00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Lua__cWebPlugin","Lua__cWebPlugin","cWebPlugin",tolua_collect_Lua__cWebPlugin); + #else + tolua_cclass(tolua_S,"Lua__cWebPlugin","Lua__cWebPlugin","cWebPlugin",NULL); + #endif + tolua_beginmodule(tolua_S,"Lua__cWebPlugin"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cWebPlugin_tolua__set_instance00); + tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cWebPlugin_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cWebPlugin_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cWebPlugin_new00_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cWebPlugin_delete00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cWebPlugin_Lua","cWebPlugin_Lua","cWebPlugin",NULL); + tolua_beginmodule(tolua_S,"cWebPlugin_Lua"); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cPickup","cPickup","cEntity",tolua_collect_cPickup); + #else + tolua_cclass(tolua_S,"cPickup","cPickup","cEntity",NULL); + #endif + tolua_beginmodule(tolua_S,"cPickup"); + tolua_function(tolua_S,"new",tolua_AllToLua_cPickup_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cPickup_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cPickup_new00_local); + tolua_function(tolua_S,"new",tolua_AllToLua_cPickup_new01); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cPickup_new01_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cPickup_new01_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_cPickup_delete00); + tolua_function(tolua_S,"GetItem",tolua_AllToLua_cPickup_GetItem00); + tolua_function(tolua_S,"CollectedBy",tolua_AllToLua_cPickup_CollectedBy00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Lua__cPickup","Lua__cPickup","cPickup",tolua_collect_Lua__cPickup); + #else + tolua_cclass(tolua_S,"Lua__cPickup","Lua__cPickup","cPickup",NULL); + #endif + tolua_beginmodule(tolua_S,"Lua__cPickup"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPickup_tolua__set_instance00); + tolua_function(tolua_S,"cPickup__CollectedBy",tolua_AllToLua_Lua__cPickup_cPickup__CollectedBy00); + tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPickup_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPickup_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPickup_new00_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPickup_new01); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPickup_new01_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPickup_new01_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cPickup_delete00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cRoot","cRoot","",NULL); + tolua_beginmodule(tolua_S,"cRoot"); + tolua_function(tolua_S,"Get",tolua_AllToLua_cRoot_Get00); + tolua_function(tolua_S,"GetServer",tolua_AllToLua_cRoot_GetServer00); + tolua_function(tolua_S,"GetDefaultWorld",tolua_AllToLua_cRoot_GetDefaultWorld00); + tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cRoot_GetWorld00); + tolua_function(tolua_S,"GetGroupManager",tolua_AllToLua_cRoot_GetGroupManager00); + tolua_function(tolua_S,"GetCraftingRecipes",tolua_AllToLua_cRoot_GetCraftingRecipes00); + tolua_function(tolua_S,"GetFurnaceRecipe",tolua_AllToLua_cRoot_GetFurnaceRecipe00); + tolua_function(tolua_S,"GetWebAdmin",tolua_AllToLua_cRoot_GetWebAdmin00); + tolua_function(tolua_S,"GetPluginManager",tolua_AllToLua_cRoot_GetPluginManager00); + tolua_function(tolua_S,"ServerCommand",tolua_AllToLua_cRoot_ServerCommand00); + tolua_function(tolua_S,"GetTotalChunkCount",tolua_AllToLua_cRoot_GetTotalChunkCount00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cTCPLink","cTCPLink","",tolua_collect_cTCPLink); + #else + tolua_cclass(tolua_S,"cTCPLink","cTCPLink","",NULL); + #endif + tolua_beginmodule(tolua_S,"cTCPLink"); + tolua_function(tolua_S,"delete",tolua_AllToLua_cTCPLink_delete00); + tolua_function(tolua_S,"Connect",tolua_AllToLua_cTCPLink_Connect00); + tolua_function(tolua_S,"Send",tolua_AllToLua_cTCPLink_Send00); + tolua_function(tolua_S,"SendMessage",tolua_AllToLua_cTCPLink_SendMessage00); + tolua_function(tolua_S,"CloseSocket",tolua_AllToLua_cTCPLink_CloseSocket00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Lua__cTCPLink","Lua__cTCPLink","cTCPLink",tolua_collect_Lua__cTCPLink); + #else + tolua_cclass(tolua_S,"Lua__cTCPLink","Lua__cTCPLink","cTCPLink",NULL); + #endif + tolua_beginmodule(tolua_S,"Lua__cTCPLink"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cTCPLink_tolua__set_instance00); + tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cTCPLink_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cTCPLink_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cTCPLink_new00_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_Lua__cTCPLink_delete00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Vector3f","Vector3f","",tolua_collect_Vector3f); + #else + tolua_cclass(tolua_S,"Vector3f","Vector3f","",NULL); + #endif + tolua_beginmodule(tolua_S,"Vector3f"); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new00_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new01); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new01_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new01_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new02); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new02_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new02_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new03); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new03_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new03_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new04); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new04_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new04_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3f_new05); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3f_new05_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3f_new05_local); + tolua_function(tolua_S,"Set",tolua_AllToLua_Vector3f_Set00); + tolua_function(tolua_S,"Normalize",tolua_AllToLua_Vector3f_Normalize00); + tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3f_NormalizeCopy00); + tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3f_NormalizeCopy01); + tolua_function(tolua_S,"Length",tolua_AllToLua_Vector3f_Length00); + tolua_function(tolua_S,"SqrLength",tolua_AllToLua_Vector3f_SqrLength00); + tolua_function(tolua_S,"Dot",tolua_AllToLua_Vector3f_Dot00); + tolua_function(tolua_S,"Cross",tolua_AllToLua_Vector3f_Cross00); + tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3f_Equals00); + tolua_function(tolua_S,".add",tolua_AllToLua_Vector3f__add00); + tolua_function(tolua_S,".add",tolua_AllToLua_Vector3f__add01); + tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3f__sub00); + tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3f__sub01); + tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3f__mul00); + tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3f__mul01); + tolua_variable(tolua_S,"x",tolua_get_Vector3f_x,tolua_set_Vector3f_x); + tolua_variable(tolua_S,"y",tolua_get_Vector3f_y,tolua_set_Vector3f_y); + tolua_variable(tolua_S,"z",tolua_get_Vector3f_z,tolua_set_Vector3f_z); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Vector3d","Vector3d","",tolua_collect_Vector3d); + #else + tolua_cclass(tolua_S,"Vector3d","Vector3d","",NULL); + #endif + tolua_beginmodule(tolua_S,"Vector3d"); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new00_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new01); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new01_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new01_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new02); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new02_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new02_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new03); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new03_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new03_local); + tolua_function(tolua_S,"Set",tolua_AllToLua_Vector3d_Set00); + tolua_function(tolua_S,"Normalize",tolua_AllToLua_Vector3d_Normalize00); + tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3d_NormalizeCopy00); + tolua_function(tolua_S,"NormalizeCopy",tolua_AllToLua_Vector3d_NormalizeCopy01); + tolua_function(tolua_S,"Length",tolua_AllToLua_Vector3d_Length00); + tolua_function(tolua_S,"SqrLength",tolua_AllToLua_Vector3d_SqrLength00); + tolua_function(tolua_S,"Dot",tolua_AllToLua_Vector3d_Dot00); + tolua_function(tolua_S,"Cross",tolua_AllToLua_Vector3d_Cross00); + tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3d_Equals00); + tolua_function(tolua_S,".add",tolua_AllToLua_Vector3d__add00); + tolua_function(tolua_S,".add",tolua_AllToLua_Vector3d__add01); + tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3d__sub00); + tolua_function(tolua_S,".sub",tolua_AllToLua_Vector3d__sub01); + tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3d__mul00); + tolua_function(tolua_S,".mul",tolua_AllToLua_Vector3d__mul01); + tolua_variable(tolua_S,"x",tolua_get_Vector3d_x,tolua_set_Vector3d_x); + tolua_variable(tolua_S,"y",tolua_get_Vector3d_y,tolua_set_Vector3d_y); + tolua_variable(tolua_S,"z",tolua_get_Vector3d_z,tolua_set_Vector3d_z); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Vector3i","Vector3i","",tolua_collect_Vector3i); + #else + tolua_cclass(tolua_S,"Vector3i","Vector3i","",NULL); + #endif + tolua_beginmodule(tolua_S,"Vector3i"); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3i_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3i_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3i_new00_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3i_new01); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3i_new01_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3i_new01_local); + tolua_function(tolua_S,"new",tolua_AllToLua_Vector3i_new02); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3i_new02_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Vector3i_new02_local); + tolua_function(tolua_S,"Set",tolua_AllToLua_Vector3i_Set00); + tolua_function(tolua_S,"Length",tolua_AllToLua_Vector3i_Length00); + tolua_function(tolua_S,"SqrLength",tolua_AllToLua_Vector3i_SqrLength00); + tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3i_Equals00); + tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3i_Equals01); + tolua_variable(tolua_S,"x",tolua_get_Vector3i_x,tolua_set_Vector3i_x); + tolua_variable(tolua_S,"y",tolua_get_Vector3i_y,tolua_set_Vector3i_y); + tolua_variable(tolua_S,"z",tolua_get_Vector3i_z,tolua_set_Vector3i_z); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cCuboid","cCuboid","",tolua_collect_cCuboid); + #else + tolua_cclass(tolua_S,"cCuboid","cCuboid","",NULL); + #endif + tolua_beginmodule(tolua_S,"cCuboid"); + tolua_function(tolua_S,"new",tolua_AllToLua_cCuboid_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cCuboid_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cCuboid_new00_local); + tolua_function(tolua_S,"new",tolua_AllToLua_cCuboid_new01); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cCuboid_new01_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cCuboid_new01_local); + tolua_function(tolua_S,"new",tolua_AllToLua_cCuboid_new02); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cCuboid_new02_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cCuboid_new02_local); + tolua_variable(tolua_S,"p1",tolua_get_cCuboid_p1,tolua_set_cCuboid_p1); + tolua_variable(tolua_S,"p2",tolua_get_cCuboid_p2,tolua_set_cCuboid_p2); + tolua_function(tolua_S,"Sort",tolua_AllToLua_cCuboid_Sort00); + tolua_function(tolua_S,"IsInside",tolua_AllToLua_cCuboid_IsInside00); + tolua_function(tolua_S,"IsInside",tolua_AllToLua_cCuboid_IsInside01); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cMCLogger","cMCLogger","",tolua_collect_cMCLogger); + #else + tolua_cclass(tolua_S,"cMCLogger","cMCLogger","",NULL); + #endif + tolua_beginmodule(tolua_S,"cMCLogger"); + tolua_function(tolua_S,"new",tolua_AllToLua_cMCLogger_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cMCLogger_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cMCLogger_new00_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_cMCLogger_delete00); + tolua_function(tolua_S,"LogSimple",tolua_AllToLua_cMCLogger_LogSimple00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cTracer","cTracer","",tolua_collect_cTracer); + #else + tolua_cclass(tolua_S,"cTracer","cTracer","",NULL); + #endif + tolua_beginmodule(tolua_S,"cTracer"); + tolua_function(tolua_S,"new",tolua_AllToLua_cTracer_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cTracer_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cTracer_new00_local); + tolua_function(tolua_S,"delete",tolua_AllToLua_cTracer_delete00); + tolua_function(tolua_S,"Trace",tolua_AllToLua_cTracer_Trace00); + tolua_function(tolua_S,"SetValues",tolua_AllToLua_cTracer_SetValues00); + tolua_variable(tolua_S,"BlockHitPosition",tolua_get_cTracer_BlockHitPosition,tolua_set_cTracer_BlockHitPosition); + tolua_variable(tolua_S,"HitNormal",tolua_get_cTracer_HitNormal,tolua_set_cTracer_HitNormal); + tolua_variable(tolua_S,"RealHit",tolua_get_cTracer_RealHit,tolua_set_cTracer_RealHit); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cGroup","cGroup","",NULL); + tolua_beginmodule(tolua_S,"cGroup"); + tolua_function(tolua_S,"SetName",tolua_AllToLua_cGroup_SetName00); + tolua_function(tolua_S,"GetName",tolua_AllToLua_cGroup_GetName00); + tolua_function(tolua_S,"SetColor",tolua_AllToLua_cGroup_SetColor00); + tolua_function(tolua_S,"AddCommand",tolua_AllToLua_cGroup_AddCommand00); + tolua_function(tolua_S,"AddPermission",tolua_AllToLua_cGroup_AddPermission00); + tolua_function(tolua_S,"InheritFrom",tolua_AllToLua_cGroup_InheritFrom00); + tolua_function(tolua_S,"HasCommand",tolua_AllToLua_cGroup_HasCommand00); + tolua_function(tolua_S,"GetColor",tolua_AllToLua_cGroup_GetColor00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cPacket_Login","cPacket_Login","cPacket",NULL); + tolua_beginmodule(tolua_S,"cPacket_Login"); + tolua_variable(tolua_S,"m_ProtocolVersion",tolua_get_cPacket_Login_m_ProtocolVersion,tolua_set_cPacket_Login_m_ProtocolVersion); + tolua_variable(tolua_S,"m_Username",tolua_get_cPacket_Login_m_Username,tolua_set_cPacket_Login_m_Username); + tolua_variable(tolua_S,"m_LevelType",tolua_get_cPacket_Login_m_LevelType,tolua_set_cPacket_Login_m_LevelType); + tolua_variable(tolua_S,"m_ServerMode",tolua_get_cPacket_Login_m_ServerMode,tolua_set_cPacket_Login_m_ServerMode); + tolua_variable(tolua_S,"m_Difficulty",tolua_get_cPacket_Login_m_Difficulty,tolua_set_cPacket_Login_m_Difficulty); + tolua_variable(tolua_S,"m_WorldHeight",tolua_get_cPacket_Login_unsigned_m_WorldHeight,tolua_set_cPacket_Login_unsigned_m_WorldHeight); + tolua_variable(tolua_S,"m_MaxPlayers",tolua_get_cPacket_Login_unsigned_m_MaxPlayers,tolua_set_cPacket_Login_unsigned_m_MaxPlayers); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cPacket_BlockDig","cPacket_BlockDig","cPacket",tolua_collect_cPacket_BlockDig); + #else + tolua_cclass(tolua_S,"cPacket_BlockDig","cPacket_BlockDig","cPacket",NULL); + #endif + tolua_beginmodule(tolua_S,"cPacket_BlockDig"); + tolua_function(tolua_S,"new",tolua_AllToLua_cPacket_BlockDig_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cPacket_BlockDig_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cPacket_BlockDig_new00_local); + tolua_function(tolua_S,"Clone",tolua_AllToLua_cPacket_BlockDig_Clone00); + tolua_variable(tolua_S,"m_Status",tolua_get_cPacket_BlockDig_m_Status,tolua_set_cPacket_BlockDig_m_Status); + tolua_variable(tolua_S,"m_PosX",tolua_get_cPacket_BlockDig_m_PosX,tolua_set_cPacket_BlockDig_m_PosX); + tolua_variable(tolua_S,"m_PosY",tolua_get_cPacket_BlockDig_m_PosY,tolua_set_cPacket_BlockDig_m_PosY); + tolua_variable(tolua_S,"m_PosZ",tolua_get_cPacket_BlockDig_m_PosZ,tolua_set_cPacket_BlockDig_m_PosZ); + tolua_variable(tolua_S,"m_Direction",tolua_get_cPacket_BlockDig_m_Direction,tolua_set_cPacket_BlockDig_m_Direction); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"Lua__cPacket_BlockDig","Lua__cPacket_BlockDig","cPacket_BlockDig",tolua_collect_Lua__cPacket_BlockDig); + #else + tolua_cclass(tolua_S,"Lua__cPacket_BlockDig","Lua__cPacket_BlockDig","cPacket_BlockDig",NULL); + #endif + tolua_beginmodule(tolua_S,"Lua__cPacket_BlockDig"); + tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPacket_BlockDig_tolua__set_instance00); + tolua_function(tolua_S,"cPacket_BlockDig__Clone",tolua_AllToLua_Lua__cPacket_BlockDig_cPacket_BlockDig__Clone00); + tolua_function(tolua_S,"new",tolua_AllToLua_Lua__cPacket_BlockDig_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_Lua__cPacket_BlockDig_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_Lua__cPacket_BlockDig_new00_local); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cPacket_BlockPlace","cPacket_BlockPlace","cPacket",NULL); + tolua_beginmodule(tolua_S,"cPacket_BlockPlace"); + tolua_variable(tolua_S,"m_PosX",tolua_get_cPacket_BlockPlace_m_PosX,tolua_set_cPacket_BlockPlace_m_PosX); + tolua_variable(tolua_S,"m_PosY",tolua_get_cPacket_BlockPlace_unsigned_m_PosY,tolua_set_cPacket_BlockPlace_unsigned_m_PosY); + tolua_variable(tolua_S,"m_PosZ",tolua_get_cPacket_BlockPlace_m_PosZ,tolua_set_cPacket_BlockPlace_m_PosZ); + tolua_variable(tolua_S,"m_Direction",tolua_get_cPacket_BlockPlace_m_Direction,tolua_set_cPacket_BlockPlace_m_Direction); + tolua_variable(tolua_S,"m_ItemType",tolua_get_cPacket_BlockPlace_m_ItemType,tolua_set_cPacket_BlockPlace_m_ItemType); + tolua_variable(tolua_S,"m_Count",tolua_get_cPacket_BlockPlace_m_Count,tolua_set_cPacket_BlockPlace_m_Count); + tolua_variable(tolua_S,"m_Uses",tolua_get_cPacket_BlockPlace_m_Uses,tolua_set_cPacket_BlockPlace_m_Uses); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cLuaChunk","cLuaChunk","",NULL); + tolua_beginmodule(tolua_S,"cLuaChunk"); + tolua_function(tolua_S,"FillBlocks",tolua_AllToLua_cLuaChunk_FillBlocks00); + tolua_function(tolua_S,"SetBlock",tolua_AllToLua_cLuaChunk_SetBlock00); + tolua_function(tolua_S,"GetBlock",tolua_AllToLua_cLuaChunk_GetBlock00); + tolua_function(tolua_S,"GetBlockMeta",tolua_AllToLua_cLuaChunk_GetBlockMeta00); + tolua_function(tolua_S,"SetBiome",tolua_AllToLua_cLuaChunk_SetBiome00); + tolua_function(tolua_S,"GetBiome",tolua_AllToLua_cLuaChunk_GetBiome00); + tolua_function(tolua_S,"SetHeight",tolua_AllToLua_cLuaChunk_SetHeight00); + tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cLuaChunk_GetHeight00); + tolua_function(tolua_S,"SetUseDefaultBiomes",tolua_AllToLua_cLuaChunk_SetUseDefaultBiomes00); + tolua_function(tolua_S,"IsUsingDefaultBiomes",tolua_AllToLua_cLuaChunk_IsUsingDefaultBiomes00); + tolua_function(tolua_S,"SetUseDefaultComposition",tolua_AllToLua_cLuaChunk_SetUseDefaultComposition00); + tolua_function(tolua_S,"IsUsingDefaultComposition",tolua_AllToLua_cLuaChunk_IsUsingDefaultComposition00); + tolua_function(tolua_S,"SetUseDefaultStructures",tolua_AllToLua_cLuaChunk_SetUseDefaultStructures00); + tolua_function(tolua_S,"IsUsingDefaultStructures",tolua_AllToLua_cLuaChunk_IsUsingDefaultStructures00); + tolua_function(tolua_S,"SetUseDefaultFinish",tolua_AllToLua_cLuaChunk_SetUseDefaultFinish00); + tolua_function(tolua_S,"IsUsingDefaultFinish",tolua_AllToLua_cLuaChunk_IsUsingDefaultFinish00); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cCraftingGrid","cCraftingGrid","",tolua_collect_cCraftingGrid); + #else + tolua_cclass(tolua_S,"cCraftingGrid","cCraftingGrid","",NULL); + #endif + tolua_beginmodule(tolua_S,"cCraftingGrid"); + tolua_function(tolua_S,"new",tolua_AllToLua_cCraftingGrid_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cCraftingGrid_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cCraftingGrid_new00_local); + tolua_function(tolua_S,"GetWidth",tolua_AllToLua_cCraftingGrid_GetWidth00); + tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cCraftingGrid_GetHeight00); + tolua_function(tolua_S,"GetItem",tolua_AllToLua_cCraftingGrid_GetItem00); + tolua_function(tolua_S,"SetItem",tolua_AllToLua_cCraftingGrid_SetItem00); + tolua_function(tolua_S,"SetItem",tolua_AllToLua_cCraftingGrid_SetItem01); + tolua_function(tolua_S,"Clear",tolua_AllToLua_cCraftingGrid_Clear00); + tolua_function(tolua_S,"ConsumeGrid",tolua_AllToLua_cCraftingGrid_ConsumeGrid00); + tolua_function(tolua_S,"Dump",tolua_AllToLua_cCraftingGrid_Dump00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cCraftingRecipe","cCraftingRecipe","",NULL); + tolua_beginmodule(tolua_S,"cCraftingRecipe"); + tolua_function(tolua_S,"Clear",tolua_AllToLua_cCraftingRecipe_Clear00); + tolua_function(tolua_S,"GetIngredientsWidth",tolua_AllToLua_cCraftingRecipe_GetIngredientsWidth00); + tolua_function(tolua_S,"GetIngredientsHeight",tolua_AllToLua_cCraftingRecipe_GetIngredientsHeight00); + tolua_function(tolua_S,"GetIngredient",tolua_AllToLua_cCraftingRecipe_GetIngredient00); + tolua_function(tolua_S,"GetResult",tolua_AllToLua_cCraftingRecipe_GetResult00); + tolua_function(tolua_S,"SetResult",tolua_AllToLua_cCraftingRecipe_SetResult00); + tolua_function(tolua_S,"SetResult",tolua_AllToLua_cCraftingRecipe_SetResult01); + tolua_function(tolua_S,"SetIngredient",tolua_AllToLua_cCraftingRecipe_SetIngredient00); + tolua_function(tolua_S,"SetIngredient",tolua_AllToLua_cCraftingRecipe_SetIngredient01); + tolua_function(tolua_S,"ConsumeIngredients",tolua_AllToLua_cCraftingRecipe_ConsumeIngredients00); + tolua_function(tolua_S,"Dump",tolua_AllToLua_cCraftingRecipe_Dump00); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cLuaItems","cLuaItems","",NULL); + tolua_beginmodule(tolua_S,"cLuaItems"); + tolua_function(tolua_S,"Get",tolua_AllToLua_cLuaItems_Get00); + tolua_function(tolua_S,"Set",tolua_AllToLua_cLuaItems_Set00); + tolua_function(tolua_S,"Add",tolua_AllToLua_cLuaItems_Add00); + tolua_function(tolua_S,"Delete",tolua_AllToLua_cLuaItems_Delete00); + tolua_function(tolua_S,"Clear",tolua_AllToLua_cLuaItems_Clear00); + tolua_function(tolua_S,"Size",tolua_AllToLua_cLuaItems_Size00); + tolua_function(tolua_S,"Add",tolua_AllToLua_cLuaItems_Add01); + tolua_function(tolua_S,"Set",tolua_AllToLua_cLuaItems_Set01); + tolua_endmodule(tolua_S); + tolua_endmodule(tolua_S); + return 1; +} + + +#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501 + TOLUA_API int luaopen_AllToLua (lua_State* tolua_S) { + return tolua_AllToLua_open(tolua_S); +}; +#endif + diff --git a/source/Bindings.h b/source/Bindings.h index 8bfe98708..ab12fc8fa 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,8 +1,8 @@ -/*
-** Lua binding: AllToLua
-** Generated automatically by tolua++-1.0.92 on Thu Jun 14 14:20:17 2012.
-*/
-
-/* Exported function */
-TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S);
-
+/* +** Lua binding: AllToLua +** Generated automatically by tolua++-1.0.92 on Thu Jun 14 14:20:17 2012. +*/ + +/* Exported function */ +TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); + diff --git a/source/BioGen.cpp b/source/BioGen.cpp index e897e229d..8603a7452 100644 --- a/source/BioGen.cpp +++ b/source/BioGen.cpp @@ -1,293 +1,293 @@ -
-// BioGen.cpp
-
-// Implements the various biome generators
-
-#include "Globals.h"
-#include "BioGen.h"
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cBioGenConstant:
-
-void cBioGenConstant::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
-{
- for (int i = 0; i < ARRAYCOUNT(a_BiomeMap); i++)
- {
- a_BiomeMap[i] = m_Biome;
- }
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cBioGenCache:
-
-cBioGenCache::cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize) :
- m_BioGenToCache(a_BioGenToCache),
- m_CacheSize(a_CacheSize),
- m_CacheOrder(new int[a_CacheSize]),
- m_CacheData(new sCacheData[a_CacheSize]),
- m_NumHits(0),
- m_NumMisses(0),
- m_TotalChain(0)
-{
- for (int i = 0; i < m_CacheSize; i++)
- {
- m_CacheOrder[i] = i;
- m_CacheData[i].m_ChunkX = 0x7fffffff;
- m_CacheData[i].m_ChunkZ = 0x7fffffff;
- }
-}
-
-
-
-
-
-cBioGenCache::~cBioGenCache()
-{
- delete m_CacheData;
- delete m_CacheOrder;
- delete m_BioGenToCache;
-}
-
-
-
-
-
-void cBioGenCache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
-{
- if (((m_NumHits + m_NumMisses) % 1024) == 10)
- {
- LOGD("BioGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses));
- LOGD("BioGenCache: Avg cache chain length: %.2f", (float)m_TotalChain / m_NumHits);
- }
-
- for (int i = 0; i < m_CacheSize; i++)
- {
- if (
- (m_CacheData[m_CacheOrder[i]].m_ChunkX != a_ChunkX) ||
- (m_CacheData[m_CacheOrder[i]].m_ChunkZ != a_ChunkZ)
- )
- {
- continue;
- }
- // Found it in the cache
- int Idx = m_CacheOrder[i];
-
- // Move to front:
- for (int j = i; j > 0; j--)
- {
- m_CacheOrder[j] = m_CacheOrder[j - 1];
- }
- m_CacheOrder[0] = Idx;
-
- // Use the cached data:
- memcpy(a_BiomeMap, m_CacheData[Idx].m_BiomeMap, sizeof(a_BiomeMap));
-
- m_NumHits++;
- m_TotalChain += i;
- return;
- } // for i - cache
-
- // Not in the cache:
- m_NumMisses++;
- m_BioGenToCache->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap);
-
- // Insert it as the first item in the MRU order:
- int Idx = m_CacheOrder[m_CacheSize - 1];
- for (int i = m_CacheSize - 1; i > 0; i--)
- {
- m_CacheOrder[i] = m_CacheOrder[i - 1];
- } // for i - m_CacheOrder[]
- m_CacheOrder[0] = Idx;
- memcpy(m_CacheData[Idx].m_BiomeMap, a_BiomeMap, sizeof(a_BiomeMap));
- m_CacheData[Idx].m_ChunkX = a_ChunkX;
- m_CacheData[Idx].m_ChunkZ = a_ChunkZ;
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cBiomeGenList:
-
-void cBiomeGenList::InitializeBiomes(const AString & a_Biomes)
-{
- AStringVector Split = StringSplit(a_Biomes, ",");
-
- // Convert each string in the list into biome:
- for (AStringVector::const_iterator itr = Split.begin(); itr != Split.end(); ++itr)
- {
- EMCSBiome Biome = StringToBiome(*itr);
- if (Biome != -1)
- {
- m_Biomes.push_back(Biome);
- }
- } // for itr - Split[]
- if (!m_Biomes.empty())
- {
- m_BiomesCount = (int)m_Biomes.size();
- return;
- }
-
- // There were no biomes, add default biomes:
- static EMCSBiome Biomes[] =
- {
- biOcean,
- biPlains,
- biDesert,
- biExtremeHills,
- biForest,
- biTaiga,
- biSwampland,
- biRiver,
- biFrozenOcean,
- biFrozenRiver,
- biIcePlains,
- biIceMountains,
- biMushroomIsland,
- biMushroomShore,
- biBeach,
- biDesertHills,
- biForestHills,
- biTaigaHills,
- biExtremeHillsEdge,
- biJungle,
- biJungleHills,
- } ;
- m_Biomes.reserve(ARRAYCOUNT(Biomes));
- for (int i = 0; i < ARRAYCOUNT(Biomes); i++)
- {
- m_Biomes.push_back(Biomes[i]);
- }
- m_BiomesCount = (int)m_Biomes.size();
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cBioGenCheckerboard:
-
-void cBioGenCheckerboard::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
-{
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- int Base = cChunkDef::Width * a_ChunkZ + z;
- for (int x = 0; x < cChunkDef::Width; x++)
- {
- int Add = cChunkDef::Width * a_ChunkX + x;
- a_BiomeMap[x + cChunkDef::Width * z] = m_Biomes[(Base / m_BiomeSize + Add / m_BiomeSize) % m_BiomesCount];
- }
- }
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cBioGenVoronoi :
-
-void cBioGenVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
-{
- int BaseZ = cChunkDef::Width * a_ChunkZ;
- int BaseX = cChunkDef::Width * a_ChunkX;
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- int AbsoluteZ = BaseZ + z;
- for (int x = 0; x < cChunkDef::Width; x++)
- {
- cChunkDef::SetBiome(a_BiomeMap, x, z, VoronoiBiome(BaseX + x, AbsoluteZ));
- } // for x
- } // for z
-}
-
-
-
-
-
-EMCSBiome cBioGenVoronoi::VoronoiBiome(int a_BlockX, int a_BlockZ)
-{
- int CellX = a_BlockX / m_CellSize;
- int CellZ = a_BlockZ / m_CellSize;
-
- // Note that Noise values need to be divided by 8 to gain a uniform modulo-2^n distribution
-
- // Get 5x5 neighboring cell seeds, compare distance to each. Return the biome in the minumim-distance cell
- double MinDist = m_CellSize * m_CellSize; // There has to be a cell closer than this
- EMCSBiome res = biPlains; // Will be overriden
- for (int x = CellX - 2; x <= CellX + 2; x++)
- {
- int BaseX = x * m_CellSize;
- for (int z = CellZ - 2; z < CellZ + 2; z++)
- {
- int OffsetX = (m_Noise.IntNoise3DInt(x, 16 * x + 32 * z, z) / 8) % m_CellSize;
- int OffsetZ = (m_Noise.IntNoise3DInt(x, 32 * x - 16 * z, z) / 8) % m_CellSize;
- int SeedX = BaseX + OffsetX;
- int SeedZ = z * m_CellSize + OffsetZ;
-
- double Dist = sqrt((double)((SeedX - a_BlockX) * (SeedX - a_BlockX) + (SeedZ - a_BlockZ) * (SeedZ - a_BlockZ)));
- if (Dist < MinDist)
- {
- MinDist = Dist;
- res = m_Biomes[(m_Noise.IntNoise3DInt(x, x - z + 1000, z) / 8) % m_BiomesCount];
- }
- } // for z
- } // for x
-
- return res;
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cBioGenDistortedVoronoi:
-
-void cBioGenDistortedVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
-{
- int BaseZ = cChunkDef::Width * a_ChunkZ;
- int BaseX = cChunkDef::Width * a_ChunkX;
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- int AbsoluteZ = BaseZ + z;
- for (int x = 0; x < cChunkDef::Width; x++)
- {
- int DistX, DistZ;
- Distort(BaseX + x, AbsoluteZ, DistX, DistZ);
- cChunkDef::SetBiome(a_BiomeMap, x, z, VoronoiBiome(DistX, DistZ));
- } // for x
- } // for z
-}
-
-
-
-
-
-void cBioGenDistortedVoronoi::Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ)
-{
- double NoiseX = m_Noise.CubicNoise3D((float)a_BlockX / m_CellSize, (float)a_BlockZ / m_CellSize, 1000);
- NoiseX += 0.5 * m_Noise.CubicNoise3D(2 * (float)a_BlockX / m_CellSize, 2 * (float)a_BlockZ / m_CellSize, 2000);
- NoiseX += 0.08 * m_Noise.CubicNoise3D(16 * (float)a_BlockX / m_CellSize, 16 * (float)a_BlockZ / m_CellSize, 3000);
- double NoiseZ = m_Noise.CubicNoise3D((float)a_BlockX / m_CellSize, (float)a_BlockZ / m_CellSize, 4000);
- NoiseZ += 0.5 * m_Noise.CubicNoise3D(2 * (float)a_BlockX / m_CellSize, 2 * (float)a_BlockZ / m_CellSize, 5000);
- NoiseZ += 0.08 * m_Noise.CubicNoise3D(16 * (float)a_BlockX / m_CellSize, 16 * (float)a_BlockZ / m_CellSize, 6000);
-
- a_DistortedX = a_BlockX + (int)(m_CellSize * 0.5 * NoiseX);
- a_DistortedZ = a_BlockZ + (int)(m_CellSize * 0.5 * NoiseZ);
-}
-
-
-
-
-
+ +// BioGen.cpp + +// Implements the various biome generators + +#include "Globals.h" +#include "BioGen.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cBioGenConstant: + +void cBioGenConstant::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) +{ + for (int i = 0; i < ARRAYCOUNT(a_BiomeMap); i++) + { + a_BiomeMap[i] = m_Biome; + } +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cBioGenCache: + +cBioGenCache::cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize) : + m_BioGenToCache(a_BioGenToCache), + m_CacheSize(a_CacheSize), + m_CacheOrder(new int[a_CacheSize]), + m_CacheData(new sCacheData[a_CacheSize]), + m_NumHits(0), + m_NumMisses(0), + m_TotalChain(0) +{ + for (int i = 0; i < m_CacheSize; i++) + { + m_CacheOrder[i] = i; + m_CacheData[i].m_ChunkX = 0x7fffffff; + m_CacheData[i].m_ChunkZ = 0x7fffffff; + } +} + + + + + +cBioGenCache::~cBioGenCache() +{ + delete m_CacheData; + delete m_CacheOrder; + delete m_BioGenToCache; +} + + + + + +void cBioGenCache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) +{ + if (((m_NumHits + m_NumMisses) % 1024) == 10) + { + LOGD("BioGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses)); + LOGD("BioGenCache: Avg cache chain length: %.2f", (float)m_TotalChain / m_NumHits); + } + + for (int i = 0; i < m_CacheSize; i++) + { + if ( + (m_CacheData[m_CacheOrder[i]].m_ChunkX != a_ChunkX) || + (m_CacheData[m_CacheOrder[i]].m_ChunkZ != a_ChunkZ) + ) + { + continue; + } + // Found it in the cache + int Idx = m_CacheOrder[i]; + + // Move to front: + for (int j = i; j > 0; j--) + { + m_CacheOrder[j] = m_CacheOrder[j - 1]; + } + m_CacheOrder[0] = Idx; + + // Use the cached data: + memcpy(a_BiomeMap, m_CacheData[Idx].m_BiomeMap, sizeof(a_BiomeMap)); + + m_NumHits++; + m_TotalChain += i; + return; + } // for i - cache + + // Not in the cache: + m_NumMisses++; + m_BioGenToCache->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); + + // Insert it as the first item in the MRU order: + int Idx = m_CacheOrder[m_CacheSize - 1]; + for (int i = m_CacheSize - 1; i > 0; i--) + { + m_CacheOrder[i] = m_CacheOrder[i - 1]; + } // for i - m_CacheOrder[] + m_CacheOrder[0] = Idx; + memcpy(m_CacheData[Idx].m_BiomeMap, a_BiomeMap, sizeof(a_BiomeMap)); + m_CacheData[Idx].m_ChunkX = a_ChunkX; + m_CacheData[Idx].m_ChunkZ = a_ChunkZ; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cBiomeGenList: + +void cBiomeGenList::InitializeBiomes(const AString & a_Biomes) +{ + AStringVector Split = StringSplit(a_Biomes, ","); + + // Convert each string in the list into biome: + for (AStringVector::const_iterator itr = Split.begin(); itr != Split.end(); ++itr) + { + EMCSBiome Biome = StringToBiome(*itr); + if (Biome != -1) + { + m_Biomes.push_back(Biome); + } + } // for itr - Split[] + if (!m_Biomes.empty()) + { + m_BiomesCount = (int)m_Biomes.size(); + return; + } + + // There were no biomes, add default biomes: + static EMCSBiome Biomes[] = + { + biOcean, + biPlains, + biDesert, + biExtremeHills, + biForest, + biTaiga, + biSwampland, + biRiver, + biFrozenOcean, + biFrozenRiver, + biIcePlains, + biIceMountains, + biMushroomIsland, + biMushroomShore, + biBeach, + biDesertHills, + biForestHills, + biTaigaHills, + biExtremeHillsEdge, + biJungle, + biJungleHills, + } ; + m_Biomes.reserve(ARRAYCOUNT(Biomes)); + for (int i = 0; i < ARRAYCOUNT(Biomes); i++) + { + m_Biomes.push_back(Biomes[i]); + } + m_BiomesCount = (int)m_Biomes.size(); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cBioGenCheckerboard: + +void cBioGenCheckerboard::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) +{ + for (int z = 0; z < cChunkDef::Width; z++) + { + int Base = cChunkDef::Width * a_ChunkZ + z; + for (int x = 0; x < cChunkDef::Width; x++) + { + int Add = cChunkDef::Width * a_ChunkX + x; + a_BiomeMap[x + cChunkDef::Width * z] = m_Biomes[(Base / m_BiomeSize + Add / m_BiomeSize) % m_BiomesCount]; + } + } +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cBioGenVoronoi : + +void cBioGenVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) +{ + int BaseZ = cChunkDef::Width * a_ChunkZ; + int BaseX = cChunkDef::Width * a_ChunkX; + for (int z = 0; z < cChunkDef::Width; z++) + { + int AbsoluteZ = BaseZ + z; + for (int x = 0; x < cChunkDef::Width; x++) + { + cChunkDef::SetBiome(a_BiomeMap, x, z, VoronoiBiome(BaseX + x, AbsoluteZ)); + } // for x + } // for z +} + + + + + +EMCSBiome cBioGenVoronoi::VoronoiBiome(int a_BlockX, int a_BlockZ) +{ + int CellX = a_BlockX / m_CellSize; + int CellZ = a_BlockZ / m_CellSize; + + // Note that Noise values need to be divided by 8 to gain a uniform modulo-2^n distribution + + // Get 5x5 neighboring cell seeds, compare distance to each. Return the biome in the minumim-distance cell + double MinDist = m_CellSize * m_CellSize; // There has to be a cell closer than this + EMCSBiome res = biPlains; // Will be overriden + for (int x = CellX - 2; x <= CellX + 2; x++) + { + int BaseX = x * m_CellSize; + for (int z = CellZ - 2; z < CellZ + 2; z++) + { + int OffsetX = (m_Noise.IntNoise3DInt(x, 16 * x + 32 * z, z) / 8) % m_CellSize; + int OffsetZ = (m_Noise.IntNoise3DInt(x, 32 * x - 16 * z, z) / 8) % m_CellSize; + int SeedX = BaseX + OffsetX; + int SeedZ = z * m_CellSize + OffsetZ; + + double Dist = sqrt((double)((SeedX - a_BlockX) * (SeedX - a_BlockX) + (SeedZ - a_BlockZ) * (SeedZ - a_BlockZ))); + if (Dist < MinDist) + { + MinDist = Dist; + res = m_Biomes[(m_Noise.IntNoise3DInt(x, x - z + 1000, z) / 8) % m_BiomesCount]; + } + } // for z + } // for x + + return res; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cBioGenDistortedVoronoi: + +void cBioGenDistortedVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) +{ + int BaseZ = cChunkDef::Width * a_ChunkZ; + int BaseX = cChunkDef::Width * a_ChunkX; + for (int z = 0; z < cChunkDef::Width; z++) + { + int AbsoluteZ = BaseZ + z; + for (int x = 0; x < cChunkDef::Width; x++) + { + int DistX, DistZ; + Distort(BaseX + x, AbsoluteZ, DistX, DistZ); + cChunkDef::SetBiome(a_BiomeMap, x, z, VoronoiBiome(DistX, DistZ)); + } // for x + } // for z +} + + + + + +void cBioGenDistortedVoronoi::Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ) +{ + double NoiseX = m_Noise.CubicNoise3D((float)a_BlockX / m_CellSize, (float)a_BlockZ / m_CellSize, 1000); + NoiseX += 0.5 * m_Noise.CubicNoise3D(2 * (float)a_BlockX / m_CellSize, 2 * (float)a_BlockZ / m_CellSize, 2000); + NoiseX += 0.08 * m_Noise.CubicNoise3D(16 * (float)a_BlockX / m_CellSize, 16 * (float)a_BlockZ / m_CellSize, 3000); + double NoiseZ = m_Noise.CubicNoise3D((float)a_BlockX / m_CellSize, (float)a_BlockZ / m_CellSize, 4000); + NoiseZ += 0.5 * m_Noise.CubicNoise3D(2 * (float)a_BlockX / m_CellSize, 2 * (float)a_BlockZ / m_CellSize, 5000); + NoiseZ += 0.08 * m_Noise.CubicNoise3D(16 * (float)a_BlockX / m_CellSize, 16 * (float)a_BlockZ / m_CellSize, 6000); + + a_DistortedX = a_BlockX + (int)(m_CellSize * 0.5 * NoiseX); + a_DistortedZ = a_BlockZ + (int)(m_CellSize * 0.5 * NoiseZ); +} + + + + + diff --git a/source/BioGen.h b/source/BioGen.h index 9a119ef2e..8aaaeff4a 100644 --- a/source/BioGen.h +++ b/source/BioGen.h @@ -1,171 +1,171 @@ -
-// BioGen.h
-
-/*
-Interfaces to the various biome generators:
- - cBioGenConstant
- - cBioGenCheckerboard
- - cBioGenDistortedVoronoi
-*/
-
-
-
-
-
-#pragma once
-
-#include "cChunkGenerator.h"
-#include "cNoise.h"
-
-
-
-
-
-class cBioGenConstant :
- public cBiomeGen
-{
-public:
- cBioGenConstant(EMCSBiome a_Biome) : m_Biome(a_Biome) {}
-
-protected:
-
- EMCSBiome m_Biome;
-
- // cBiomeGen override:
- virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
-} ;
-
-
-
-
-
-/// A simple cache that stores N most recently generated chunks' biomes; N being settable upon creation
-class cBioGenCache :
- public cBiomeGen
-{
-public:
- cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize); // Takes ownership of a_BioGenToCache
- ~cBioGenCache();
-
-protected:
-
- cBiomeGen * m_BioGenToCache;
-
- struct sCacheData
- {
- int m_ChunkX;
- int m_ChunkZ;
- cChunkDef::BiomeMap m_BiomeMap;
- } ;
-
- // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data
- int m_CacheSize;
- int * m_CacheOrder; // MRU-ized order, indices into m_CacheData array
- sCacheData * m_CacheData; // m_CacheData[m_CacheOrder[0]] is the most recently used
-
- // Cache statistics
- int m_NumHits;
- int m_NumMisses;
- int m_TotalChain; // Number of cache items walked to get to a hit (only added for hits)
-
- virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
-} ;
-
-
-
-
-
-/// Base class for generators that use a list of available biomes. This class takes care of the list.
-class cBiomeGenList :
- public cBiomeGen
-{
-protected:
- cBiomeGenList(const AString & a_Biomes)
- {
- InitializeBiomes(a_Biomes);
- }
-
- // List of biomes that the generator is allowed to generate:
- typedef std::vector<EMCSBiome> EMCSBiomes;
- EMCSBiomes m_Biomes;
- int m_BiomesCount; // Pulled out of m_Biomes for faster access
-
- void InitializeBiomes(const AString & a_Biomes);
-
-} ;
-
-
-
-
-
-class cBioGenCheckerboard :
- public cBiomeGenList
-{
-public:
- cBioGenCheckerboard(int a_BiomeSize, const AString & a_Biomes) :
- cBiomeGenList(a_Biomes),
- m_BiomeSize((a_BiomeSize < 8) ? 8 : a_BiomeSize)
- {
- }
-
-protected:
-
- int m_BiomeSize;
-
- // cBiomeGen override:
- virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
-} ;
-
-
-
-
-
-class cBioGenVoronoi :
- public cBiomeGenList
-{
-public:
- cBioGenVoronoi(int a_Seed, int a_CellSize, const AString & a_Biomes) :
- cBiomeGenList(a_Biomes),
- m_CellSize((a_CellSize > 4) ? a_CellSize : 4),
- m_Noise(a_Seed)
- {
- }
-
-protected:
-
- int m_CellSize;
-
- cNoise m_Noise;
-
- // cBiomeGen override:
- virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
-
- EMCSBiome VoronoiBiome(int a_BlockX, int a_BlockZ);
-} ;
-
-
-
-
-
-class cBioGenDistortedVoronoi :
- public cBioGenVoronoi
-{
-public:
- cBioGenDistortedVoronoi(int a_Seed, int a_CellSize, const AString & a_Biomes) :
- cBioGenVoronoi(a_Seed, a_CellSize, a_Biomes)
- {
- }
-
-protected:
-
- // cBiomeGen override:
- virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
-
- /// Distorts the coords using a Perlin-like noise
- void Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ);
-} ;
-
-
-
-
-
+ +// BioGen.h + +/* +Interfaces to the various biome generators: + - cBioGenConstant + - cBioGenCheckerboard + - cBioGenDistortedVoronoi +*/ + + + + + +#pragma once + +#include "cChunkGenerator.h" +#include "cNoise.h" + + + + + +class cBioGenConstant : + public cBiomeGen +{ +public: + cBioGenConstant(EMCSBiome a_Biome) : m_Biome(a_Biome) {} + +protected: + + EMCSBiome m_Biome; + + // cBiomeGen override: + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; +} ; + + + + + +/// A simple cache that stores N most recently generated chunks' biomes; N being settable upon creation +class cBioGenCache : + public cBiomeGen +{ +public: + cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize); // Takes ownership of a_BioGenToCache + ~cBioGenCache(); + +protected: + + cBiomeGen * m_BioGenToCache; + + struct sCacheData + { + int m_ChunkX; + int m_ChunkZ; + cChunkDef::BiomeMap m_BiomeMap; + } ; + + // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data + int m_CacheSize; + int * m_CacheOrder; // MRU-ized order, indices into m_CacheData array + sCacheData * m_CacheData; // m_CacheData[m_CacheOrder[0]] is the most recently used + + // Cache statistics + int m_NumHits; + int m_NumMisses; + int m_TotalChain; // Number of cache items walked to get to a hit (only added for hits) + + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; +} ; + + + + + +/// Base class for generators that use a list of available biomes. This class takes care of the list. +class cBiomeGenList : + public cBiomeGen +{ +protected: + cBiomeGenList(const AString & a_Biomes) + { + InitializeBiomes(a_Biomes); + } + + // List of biomes that the generator is allowed to generate: + typedef std::vector<EMCSBiome> EMCSBiomes; + EMCSBiomes m_Biomes; + int m_BiomesCount; // Pulled out of m_Biomes for faster access + + void InitializeBiomes(const AString & a_Biomes); + +} ; + + + + + +class cBioGenCheckerboard : + public cBiomeGenList +{ +public: + cBioGenCheckerboard(int a_BiomeSize, const AString & a_Biomes) : + cBiomeGenList(a_Biomes), + m_BiomeSize((a_BiomeSize < 8) ? 8 : a_BiomeSize) + { + } + +protected: + + int m_BiomeSize; + + // cBiomeGen override: + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; +} ; + + + + + +class cBioGenVoronoi : + public cBiomeGenList +{ +public: + cBioGenVoronoi(int a_Seed, int a_CellSize, const AString & a_Biomes) : + cBiomeGenList(a_Biomes), + m_CellSize((a_CellSize > 4) ? a_CellSize : 4), + m_Noise(a_Seed) + { + } + +protected: + + int m_CellSize; + + cNoise m_Noise; + + // cBiomeGen override: + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; + + EMCSBiome VoronoiBiome(int a_BlockX, int a_BlockZ); +} ; + + + + + +class cBioGenDistortedVoronoi : + public cBioGenVoronoi +{ +public: + cBioGenDistortedVoronoi(int a_Seed, int a_CellSize, const AString & a_Biomes) : + cBioGenVoronoi(a_Seed, a_CellSize, a_Biomes) + { + } + +protected: + + // cBiomeGen override: + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; + + /// Distorts the coords using a Perlin-like noise + void Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ); +} ; + + + + + diff --git a/source/BlockID.cpp b/source/BlockID.cpp index 7588fee77..269bc2f3c 100644 --- a/source/BlockID.cpp +++ b/source/BlockID.cpp @@ -1,325 +1,325 @@ -
-// BlockID.cpp
-
-// Implements the helper functions for converting Block ID string to int etc.
-
-#include "Globals.h"
-#include "BlockID.h"
-#include "../iniFile/iniFile.h"
-#include "cItem.h"
-
-
-
-
-
-NIBBLETYPE g_BlockLightValue[256];
-NIBBLETYPE g_BlockSpreadLightFalloff[256];
-bool g_BlockTransparent[256];
-bool g_BlockOneHitDig[256];
-bool g_BlockPistonBreakable[256];
-bool g_BlockIsSnowable[256];
-
-
-
-
-
-class cBlockIDMap
-{
-public:
- cBlockIDMap(void) : m_Ini("items.ini")
- {
- m_Ini.ReadFile();
- }
-
- int Resolve(const AString & a_ItemName)
- {
- return m_Ini.GetValueI("Items", a_ItemName, -1);
- }
-
- AString ResolveString(const AString & a_ItemName)
- {
- return m_Ini.GetValue("Items", a_ItemName, "");
- }
-
-protected:
- cIniFile m_Ini;
-} ;
-
-
-
-
-
-static cBlockIDMap gsBlockIDMap;
-
-
-
-
-
-int BlockStringToType(const AString & a_BlockTypeString)
-{
- int res = atoi(a_BlockTypeString.c_str());
- if ((res != 0) || (a_BlockTypeString.compare("0") == 0))
- {
- // It was a valid number, return that
- return res;
- }
-
- return gsBlockIDMap.Resolve(TrimString(a_BlockTypeString));
-}
-
-
-
-
-bool StringToItem(const AString & a_ItemTypeString, cItem & a_Item)
-{
- AString Resolved = TrimString(gsBlockIDMap.ResolveString(TrimString(a_ItemTypeString)));
- AString txt = (!Resolved.empty()) ? Resolved : a_ItemTypeString;
- AStringVector Split = StringSplit(txt, ":");
- if (Split.size() == 1)
- {
- Split = StringSplit(txt, "^");
- }
- if (Split.empty())
- {
- return false;
- }
- a_Item.m_ItemID = (ENUM_ITEM_ID)atoi(Split[0].c_str());
- if ((a_Item.m_ItemID == 0) && (Split[0] != "0"))
- {
- // Parsing the number failed
- return false;
- }
- if (Split.size() > 1)
- {
- a_Item.m_ItemHealth = atoi(Split[1].c_str());
- if ((a_Item.m_ItemHealth == 0) && (Split[1] != "0"))
- {
- // Parsing the number failed
- return false;
- }
- }
- return true;
-}
-
-
-
-
-
-EMCSBiome StringToBiome(const AString & a_BiomeString)
-{
- // If it is a number, return it:
- int res = atoi(a_BiomeString.c_str());
- if ((res != 0) || (a_BiomeString.compare("0") == 0))
- {
- // It was a valid number
- return (EMCSBiome)res;
- }
-
- // Convert using the built-in map:
- static struct {
- EMCSBiome m_Biome;
- const char * m_String;
- } BiomeMap[] =
- {
- {biOcean, "Ocean"} ,
- {biPlains, "Plains"},
- {biDesert, "Desert"},
- {biExtremeHills, "ExtremeHills"},
- {biForest, "Forest"},
- {biTaiga, "Taiga"},
- {biSwampland, "Swampland"},
- {biRiver, "River"},
- {biHell, "Hell"},
- {biHell, "Nether"},
- {biSky, "Sky"},
- {biFrozenOcean, "FrozenOcean"},
- {biFrozenRiver, "FrozenRiver"},
- {biIcePlains, "IcePlains"},
- {biIcePlains, "Tundra"},
- {biIceMountains, "IceMountains"},
- {biMushroomIsland, "MushroomIsland"},
- {biMushroomShore, "MushroomShore"},
- {biBeach, "Beach"},
- {biDesertHills, "DesertHills"},
- {biForestHills, "ForestHills"},
- {biTaigaHills, "TaigaHills"},
- {biExtremeHillsEdge, "ExtremeHillsEdge"},
- {biJungle, "Jungle"},
- {biJungleHills, "JungleHills"},
- } ;
-
- for (int i = 0; i < ARRAYCOUNT(BiomeMap); i++)
- {
- if (NoCaseCompare(BiomeMap[i].m_String, a_BiomeString) == 0)
- {
- return BiomeMap[i].m_Biome;
- }
- } // for i - BiomeMap[]
- return (EMCSBiome)-1;
-}
-
-
-
-
-
-// This is actually just some code that needs to run at program startup, so it is wrapped into a global var's constructor:
-class cBlockPropertiesInitializer
-{
-public:
- cBlockPropertiesInitializer(void)
- {
- memset( g_BlockLightValue, 0x00, sizeof( g_BlockLightValue ) );
- memset( g_BlockSpreadLightFalloff, 0x0f, sizeof( g_BlockSpreadLightFalloff ) ); // 0x0f means total falloff
- memset( g_BlockTransparent, 0x00, sizeof( g_BlockTransparent ) );
- memset( g_BlockOneHitDig, 0x00, sizeof( g_BlockOneHitDig ) );
- memset( g_BlockPistonBreakable, 0x00, sizeof( g_BlockPistonBreakable ) );
- memset( g_BlockIsSnowable, 0xff, sizeof( g_BlockIsSnowable)); // Set all blocks' snowable to true
-
- // Emissive blocks
- g_BlockLightValue[E_BLOCK_FIRE] = 15;
- g_BlockLightValue[E_BLOCK_GLOWSTONE] = 15;
- g_BlockLightValue[E_BLOCK_JACK_O_LANTERN] = 15;
- g_BlockLightValue[E_BLOCK_LAVA] = 15;
- g_BlockLightValue[E_BLOCK_STATIONARY_LAVA] = 15;
- g_BlockLightValue[E_BLOCK_END_PORTAL] = 15;
- g_BlockLightValue[E_BLOCK_REDSTONE_LAMP_ON] = 15;
- g_BlockLightValue[E_BLOCK_TORCH] = 14;
- g_BlockLightValue[E_BLOCK_BURNING_FURNACE] = 13;
- g_BlockLightValue[E_BLOCK_NETHER_PORTAL] = 11;
- g_BlockLightValue[E_BLOCK_REDSTONE_ORE_GLOWING] = 9;
- g_BlockLightValue[E_BLOCK_REDSTONE_REPEATER_ON] = 9;
- g_BlockLightValue[E_BLOCK_REDSTONE_TORCH_ON] = 7;
- g_BlockLightValue[E_BLOCK_BREWING_STAND] = 1;
- g_BlockLightValue[E_BLOCK_BROWN_MUSHROOM] = 1;
- g_BlockLightValue[E_BLOCK_DRAGON_EGG] = 1;
-
- // Spread blocks
- g_BlockSpreadLightFalloff[E_BLOCK_AIR] = 1;
- g_BlockSpreadLightFalloff[E_BLOCK_CHEST] = 1;
- g_BlockSpreadLightFalloff[E_BLOCK_CROPS] = 1;
- g_BlockSpreadLightFalloff[E_BLOCK_FIRE] = 1;
- g_BlockSpreadLightFalloff[E_BLOCK_GLASS] = 1;
- g_BlockSpreadLightFalloff[E_BLOCK_GLOWSTONE] = 1;
- g_BlockSpreadLightFalloff[E_BLOCK_LEAVES] = 1;
- g_BlockSpreadLightFalloff[E_BLOCK_SIGN_POST] = 1;
- g_BlockSpreadLightFalloff[E_BLOCK_TORCH] = 1;
- g_BlockSpreadLightFalloff[E_BLOCK_VINES] = 1;
- g_BlockSpreadLightFalloff[E_BLOCK_WALLSIGN] = 1;
- // Light in water and lava dissapears faster:
- g_BlockSpreadLightFalloff[E_BLOCK_LAVA] = 2;
- g_BlockSpreadLightFalloff[E_BLOCK_STATIONARY_LAVA] = 2;
- g_BlockSpreadLightFalloff[E_BLOCK_STATIONARY_WATER] = 2;
- g_BlockSpreadLightFalloff[E_BLOCK_WATER] = 2;
-
- // Transparent blocks
- g_BlockTransparent[E_BLOCK_AIR] = true;
- g_BlockTransparent[E_BLOCK_BROWN_MUSHROOM] = true;
- g_BlockTransparent[E_BLOCK_CHEST] = true;
- g_BlockTransparent[E_BLOCK_CROPS] = true;
- g_BlockTransparent[E_BLOCK_FIRE] = true;
- g_BlockTransparent[E_BLOCK_GLASS] = true;
- g_BlockTransparent[E_BLOCK_ICE] = true;
- g_BlockTransparent[E_BLOCK_RED_MUSHROOM] = true;
- g_BlockTransparent[E_BLOCK_RED_ROSE] = true;
- g_BlockTransparent[E_BLOCK_SIGN_POST] = true;
- g_BlockTransparent[E_BLOCK_SNOW] = true;
- g_BlockTransparent[E_BLOCK_TALL_GRASS] = true;
- g_BlockTransparent[E_BLOCK_TORCH] = true;
- g_BlockTransparent[E_BLOCK_VINES] = true;
- g_BlockTransparent[E_BLOCK_WALLSIGN] = true;
- g_BlockTransparent[E_BLOCK_YELLOW_FLOWER] = true;
-
- // TODO: Any other transparent blocks?
-
- // One hit break blocks
- g_BlockOneHitDig[E_BLOCK_BROWN_MUSHROOM] = true;
- g_BlockOneHitDig[E_BLOCK_CROPS] = true;
- g_BlockOneHitDig[E_BLOCK_FIRE] = true;
- g_BlockOneHitDig[E_BLOCK_LOCKED_CHEST] = true;
- g_BlockOneHitDig[E_BLOCK_REDSTONE_REPEATER_OFF] = true;
- g_BlockOneHitDig[E_BLOCK_REDSTONE_REPEATER_ON] = true;
- g_BlockOneHitDig[E_BLOCK_REDSTONE_TORCH_OFF] = true;
- g_BlockOneHitDig[E_BLOCK_REDSTONE_TORCH_ON] = true;
- g_BlockOneHitDig[E_BLOCK_REDSTONE_WIRE] = true;
- g_BlockOneHitDig[E_BLOCK_REDSTONE_WIRE] = true;
- g_BlockOneHitDig[E_BLOCK_RED_MUSHROOM] = true;
- g_BlockOneHitDig[E_BLOCK_RED_ROSE] = true;
- g_BlockOneHitDig[E_BLOCK_REEDS] = true;
- g_BlockOneHitDig[E_BLOCK_SAPLING] = true;
- g_BlockOneHitDig[E_BLOCK_TNT] = true;
- g_BlockOneHitDig[E_BLOCK_TALL_GRASS] = true;
- g_BlockOneHitDig[E_BLOCK_TORCH] = true;
- g_BlockOneHitDig[E_BLOCK_YELLOW_FLOWER] = true;
-
- // Blocks that breaks when pushed by piston
- g_BlockPistonBreakable[E_BLOCK_AIR] = true;
- g_BlockPistonBreakable[E_BLOCK_BED] = true;
- g_BlockPistonBreakable[E_BLOCK_BROWN_MUSHROOM] = true;
- g_BlockPistonBreakable[E_BLOCK_COBWEB] = true;
- g_BlockPistonBreakable[E_BLOCK_CROPS] = true;
- g_BlockPistonBreakable[E_BLOCK_DEAD_BUSH] = true;
- g_BlockPistonBreakable[E_BLOCK_FIRE] = true;
- g_BlockPistonBreakable[E_BLOCK_IRON_DOOR] = true;
- g_BlockPistonBreakable[E_BLOCK_JACK_O_LANTERN] = true;
- g_BlockPistonBreakable[E_BLOCK_LADDER] = true;
- g_BlockPistonBreakable[E_BLOCK_LAVA] = false;
- g_BlockPistonBreakable[E_BLOCK_LEVER] = true;
- g_BlockPistonBreakable[E_BLOCK_MELON] = true;
- g_BlockPistonBreakable[E_BLOCK_MELON_STEM] = true;
- g_BlockPistonBreakable[E_BLOCK_PUMPKIN] = true;
- g_BlockPistonBreakable[E_BLOCK_PUMPKIN_STEM] = true;
- g_BlockPistonBreakable[E_BLOCK_REDSTONE_TORCH_OFF] = true;
- g_BlockPistonBreakable[E_BLOCK_REDSTONE_TORCH_ON] = true;
- g_BlockPistonBreakable[E_BLOCK_REDSTONE_WIRE] = true;
- g_BlockPistonBreakable[E_BLOCK_RED_MUSHROOM] = true;
- g_BlockPistonBreakable[E_BLOCK_RED_ROSE] = true;
- g_BlockPistonBreakable[E_BLOCK_REEDS] = true;
- g_BlockPistonBreakable[E_BLOCK_SNOW] = true;
- g_BlockPistonBreakable[E_BLOCK_STATIONARY_LAVA] = false;
- g_BlockPistonBreakable[E_BLOCK_STATIONARY_WATER] = false; //This gave pistons the ability to drop water :D
- g_BlockPistonBreakable[E_BLOCK_STONE_BUTTON] = true;
- g_BlockPistonBreakable[E_BLOCK_STONE_PRESSURE_PLATE] = true;
- g_BlockPistonBreakable[E_BLOCK_TALL_GRASS] = true;
- g_BlockPistonBreakable[E_BLOCK_TORCH] = true;
- g_BlockPistonBreakable[E_BLOCK_VINES] = true;
- g_BlockPistonBreakable[E_BLOCK_WATER] = false;
- g_BlockPistonBreakable[E_BLOCK_WOODEN_DOOR] = true;
- g_BlockPistonBreakable[E_BLOCK_WOODEN_PRESSURE_PLATE] = true;
- g_BlockPistonBreakable[E_BLOCK_YELLOW_FLOWER] = true;
-
- // Blocks that can be snowed over:
- g_BlockIsSnowable[E_BLOCK_BROWN_MUSHROOM] = false;
- g_BlockIsSnowable[E_BLOCK_CACTUS] = false;
- g_BlockIsSnowable[E_BLOCK_CHEST] = false;
- g_BlockIsSnowable[E_BLOCK_CROPS] = false;
- g_BlockIsSnowable[E_BLOCK_FIRE] = false;
- g_BlockIsSnowable[E_BLOCK_FIRE] = false;
- g_BlockIsSnowable[E_BLOCK_GLASS] = false;
- g_BlockIsSnowable[E_BLOCK_ICE] = false;
- g_BlockIsSnowable[E_BLOCK_LAVA] = false;
- g_BlockIsSnowable[E_BLOCK_LOCKED_CHEST] = false;
- g_BlockIsSnowable[E_BLOCK_REDSTONE_REPEATER_OFF] = false;
- g_BlockIsSnowable[E_BLOCK_REDSTONE_REPEATER_ON] = false;
- g_BlockIsSnowable[E_BLOCK_REDSTONE_TORCH_OFF] = false;
- g_BlockIsSnowable[E_BLOCK_REDSTONE_TORCH_ON] = false;
- g_BlockIsSnowable[E_BLOCK_REDSTONE_WIRE] = false;
- g_BlockIsSnowable[E_BLOCK_RED_MUSHROOM] = false;
- g_BlockIsSnowable[E_BLOCK_RED_ROSE] = false;
- g_BlockIsSnowable[E_BLOCK_REEDS] = false;
- g_BlockIsSnowable[E_BLOCK_SAPLING] = false;
- g_BlockIsSnowable[E_BLOCK_SIGN_POST] = false;
- g_BlockIsSnowable[E_BLOCK_SNOW] = false;
- g_BlockIsSnowable[E_BLOCK_STATIONARY_LAVA] = false;
- g_BlockIsSnowable[E_BLOCK_STATIONARY_WATER] = false;
- g_BlockIsSnowable[E_BLOCK_TALL_GRASS] = false;
- g_BlockIsSnowable[E_BLOCK_TNT] = false;
- g_BlockIsSnowable[E_BLOCK_TORCH] = false;
- g_BlockIsSnowable[E_BLOCK_WALLSIGN] = false;
- g_BlockIsSnowable[E_BLOCK_WATER] = false;
- g_BlockIsSnowable[E_BLOCK_YELLOW_FLOWER] = false;
- }
-} BlockPropertiesInitializer;
-
-
-
-
+ +// BlockID.cpp + +// Implements the helper functions for converting Block ID string to int etc. + +#include "Globals.h" +#include "BlockID.h" +#include "../iniFile/iniFile.h" +#include "cItem.h" + + + + + +NIBBLETYPE g_BlockLightValue[256]; +NIBBLETYPE g_BlockSpreadLightFalloff[256]; +bool g_BlockTransparent[256]; +bool g_BlockOneHitDig[256]; +bool g_BlockPistonBreakable[256]; +bool g_BlockIsSnowable[256]; + + + + + +class cBlockIDMap +{ +public: + cBlockIDMap(void) : m_Ini("items.ini") + { + m_Ini.ReadFile(); + } + + int Resolve(const AString & a_ItemName) + { + return m_Ini.GetValueI("Items", a_ItemName, -1); + } + + AString ResolveString(const AString & a_ItemName) + { + return m_Ini.GetValue("Items", a_ItemName, ""); + } + +protected: + cIniFile m_Ini; +} ; + + + + + +static cBlockIDMap gsBlockIDMap; + + + + + +int BlockStringToType(const AString & a_BlockTypeString) +{ + int res = atoi(a_BlockTypeString.c_str()); + if ((res != 0) || (a_BlockTypeString.compare("0") == 0)) + { + // It was a valid number, return that + return res; + } + + return gsBlockIDMap.Resolve(TrimString(a_BlockTypeString)); +} + + + + +bool StringToItem(const AString & a_ItemTypeString, cItem & a_Item) +{ + AString Resolved = TrimString(gsBlockIDMap.ResolveString(TrimString(a_ItemTypeString))); + AString txt = (!Resolved.empty()) ? Resolved : a_ItemTypeString; + AStringVector Split = StringSplit(txt, ":"); + if (Split.size() == 1) + { + Split = StringSplit(txt, "^"); + } + if (Split.empty()) + { + return false; + } + a_Item.m_ItemID = (ENUM_ITEM_ID)atoi(Split[0].c_str()); + if ((a_Item.m_ItemID == 0) && (Split[0] != "0")) + { + // Parsing the number failed + return false; + } + if (Split.size() > 1) + { + a_Item.m_ItemHealth = atoi(Split[1].c_str()); + if ((a_Item.m_ItemHealth == 0) && (Split[1] != "0")) + { + // Parsing the number failed + return false; + } + } + return true; +} + + + + + +EMCSBiome StringToBiome(const AString & a_BiomeString) +{ + // If it is a number, return it: + int res = atoi(a_BiomeString.c_str()); + if ((res != 0) || (a_BiomeString.compare("0") == 0)) + { + // It was a valid number + return (EMCSBiome)res; + } + + // Convert using the built-in map: + static struct { + EMCSBiome m_Biome; + const char * m_String; + } BiomeMap[] = + { + {biOcean, "Ocean"} , + {biPlains, "Plains"}, + {biDesert, "Desert"}, + {biExtremeHills, "ExtremeHills"}, + {biForest, "Forest"}, + {biTaiga, "Taiga"}, + {biSwampland, "Swampland"}, + {biRiver, "River"}, + {biHell, "Hell"}, + {biHell, "Nether"}, + {biSky, "Sky"}, + {biFrozenOcean, "FrozenOcean"}, + {biFrozenRiver, "FrozenRiver"}, + {biIcePlains, "IcePlains"}, + {biIcePlains, "Tundra"}, + {biIceMountains, "IceMountains"}, + {biMushroomIsland, "MushroomIsland"}, + {biMushroomShore, "MushroomShore"}, + {biBeach, "Beach"}, + {biDesertHills, "DesertHills"}, + {biForestHills, "ForestHills"}, + {biTaigaHills, "TaigaHills"}, + {biExtremeHillsEdge, "ExtremeHillsEdge"}, + {biJungle, "Jungle"}, + {biJungleHills, "JungleHills"}, + } ; + + for (int i = 0; i < ARRAYCOUNT(BiomeMap); i++) + { + if (NoCaseCompare(BiomeMap[i].m_String, a_BiomeString) == 0) + { + return BiomeMap[i].m_Biome; + } + } // for i - BiomeMap[] + return (EMCSBiome)-1; +} + + + + + +// This is actually just some code that needs to run at program startup, so it is wrapped into a global var's constructor: +class cBlockPropertiesInitializer +{ +public: + cBlockPropertiesInitializer(void) + { + memset( g_BlockLightValue, 0x00, sizeof( g_BlockLightValue ) ); + memset( g_BlockSpreadLightFalloff, 0x0f, sizeof( g_BlockSpreadLightFalloff ) ); // 0x0f means total falloff + memset( g_BlockTransparent, 0x00, sizeof( g_BlockTransparent ) ); + memset( g_BlockOneHitDig, 0x00, sizeof( g_BlockOneHitDig ) ); + memset( g_BlockPistonBreakable, 0x00, sizeof( g_BlockPistonBreakable ) ); + memset( g_BlockIsSnowable, 0xff, sizeof( g_BlockIsSnowable)); // Set all blocks' snowable to true + + // Emissive blocks + g_BlockLightValue[E_BLOCK_FIRE] = 15; + g_BlockLightValue[E_BLOCK_GLOWSTONE] = 15; + g_BlockLightValue[E_BLOCK_JACK_O_LANTERN] = 15; + g_BlockLightValue[E_BLOCK_LAVA] = 15; + g_BlockLightValue[E_BLOCK_STATIONARY_LAVA] = 15; + g_BlockLightValue[E_BLOCK_END_PORTAL] = 15; + g_BlockLightValue[E_BLOCK_REDSTONE_LAMP_ON] = 15; + g_BlockLightValue[E_BLOCK_TORCH] = 14; + g_BlockLightValue[E_BLOCK_BURNING_FURNACE] = 13; + g_BlockLightValue[E_BLOCK_NETHER_PORTAL] = 11; + g_BlockLightValue[E_BLOCK_REDSTONE_ORE_GLOWING] = 9; + g_BlockLightValue[E_BLOCK_REDSTONE_REPEATER_ON] = 9; + g_BlockLightValue[E_BLOCK_REDSTONE_TORCH_ON] = 7; + g_BlockLightValue[E_BLOCK_BREWING_STAND] = 1; + g_BlockLightValue[E_BLOCK_BROWN_MUSHROOM] = 1; + g_BlockLightValue[E_BLOCK_DRAGON_EGG] = 1; + + // Spread blocks + g_BlockSpreadLightFalloff[E_BLOCK_AIR] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_CHEST] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_CROPS] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_FIRE] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_GLASS] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_GLOWSTONE] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_LEAVES] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_SIGN_POST] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_TORCH] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_VINES] = 1; + g_BlockSpreadLightFalloff[E_BLOCK_WALLSIGN] = 1; + // Light in water and lava dissapears faster: + g_BlockSpreadLightFalloff[E_BLOCK_LAVA] = 2; + g_BlockSpreadLightFalloff[E_BLOCK_STATIONARY_LAVA] = 2; + g_BlockSpreadLightFalloff[E_BLOCK_STATIONARY_WATER] = 2; + g_BlockSpreadLightFalloff[E_BLOCK_WATER] = 2; + + // Transparent blocks + g_BlockTransparent[E_BLOCK_AIR] = true; + g_BlockTransparent[E_BLOCK_BROWN_MUSHROOM] = true; + g_BlockTransparent[E_BLOCK_CHEST] = true; + g_BlockTransparent[E_BLOCK_CROPS] = true; + g_BlockTransparent[E_BLOCK_FIRE] = true; + g_BlockTransparent[E_BLOCK_GLASS] = true; + g_BlockTransparent[E_BLOCK_ICE] = true; + g_BlockTransparent[E_BLOCK_RED_MUSHROOM] = true; + g_BlockTransparent[E_BLOCK_RED_ROSE] = true; + g_BlockTransparent[E_BLOCK_SIGN_POST] = true; + g_BlockTransparent[E_BLOCK_SNOW] = true; + g_BlockTransparent[E_BLOCK_TALL_GRASS] = true; + g_BlockTransparent[E_BLOCK_TORCH] = true; + g_BlockTransparent[E_BLOCK_VINES] = true; + g_BlockTransparent[E_BLOCK_WALLSIGN] = true; + g_BlockTransparent[E_BLOCK_YELLOW_FLOWER] = true; + + // TODO: Any other transparent blocks? + + // One hit break blocks + g_BlockOneHitDig[E_BLOCK_BROWN_MUSHROOM] = true; + g_BlockOneHitDig[E_BLOCK_CROPS] = true; + g_BlockOneHitDig[E_BLOCK_FIRE] = true; + g_BlockOneHitDig[E_BLOCK_LOCKED_CHEST] = true; + g_BlockOneHitDig[E_BLOCK_REDSTONE_REPEATER_OFF] = true; + g_BlockOneHitDig[E_BLOCK_REDSTONE_REPEATER_ON] = true; + g_BlockOneHitDig[E_BLOCK_REDSTONE_TORCH_OFF] = true; + g_BlockOneHitDig[E_BLOCK_REDSTONE_TORCH_ON] = true; + g_BlockOneHitDig[E_BLOCK_REDSTONE_WIRE] = true; + g_BlockOneHitDig[E_BLOCK_REDSTONE_WIRE] = true; + g_BlockOneHitDig[E_BLOCK_RED_MUSHROOM] = true; + g_BlockOneHitDig[E_BLOCK_RED_ROSE] = true; + g_BlockOneHitDig[E_BLOCK_REEDS] = true; + g_BlockOneHitDig[E_BLOCK_SAPLING] = true; + g_BlockOneHitDig[E_BLOCK_TNT] = true; + g_BlockOneHitDig[E_BLOCK_TALL_GRASS] = true; + g_BlockOneHitDig[E_BLOCK_TORCH] = true; + g_BlockOneHitDig[E_BLOCK_YELLOW_FLOWER] = true; + + // Blocks that breaks when pushed by piston + g_BlockPistonBreakable[E_BLOCK_AIR] = true; + g_BlockPistonBreakable[E_BLOCK_BED] = true; + g_BlockPistonBreakable[E_BLOCK_BROWN_MUSHROOM] = true; + g_BlockPistonBreakable[E_BLOCK_COBWEB] = true; + g_BlockPistonBreakable[E_BLOCK_CROPS] = true; + g_BlockPistonBreakable[E_BLOCK_DEAD_BUSH] = true; + g_BlockPistonBreakable[E_BLOCK_FIRE] = true; + g_BlockPistonBreakable[E_BLOCK_IRON_DOOR] = true; + g_BlockPistonBreakable[E_BLOCK_JACK_O_LANTERN] = true; + g_BlockPistonBreakable[E_BLOCK_LADDER] = true; + g_BlockPistonBreakable[E_BLOCK_LAVA] = false; + g_BlockPistonBreakable[E_BLOCK_LEVER] = true; + g_BlockPistonBreakable[E_BLOCK_MELON] = true; + g_BlockPistonBreakable[E_BLOCK_MELON_STEM] = true; + g_BlockPistonBreakable[E_BLOCK_PUMPKIN] = true; + g_BlockPistonBreakable[E_BLOCK_PUMPKIN_STEM] = true; + g_BlockPistonBreakable[E_BLOCK_REDSTONE_TORCH_OFF] = true; + g_BlockPistonBreakable[E_BLOCK_REDSTONE_TORCH_ON] = true; + g_BlockPistonBreakable[E_BLOCK_REDSTONE_WIRE] = true; + g_BlockPistonBreakable[E_BLOCK_RED_MUSHROOM] = true; + g_BlockPistonBreakable[E_BLOCK_RED_ROSE] = true; + g_BlockPistonBreakable[E_BLOCK_REEDS] = true; + g_BlockPistonBreakable[E_BLOCK_SNOW] = true; + g_BlockPistonBreakable[E_BLOCK_STATIONARY_LAVA] = false; + g_BlockPistonBreakable[E_BLOCK_STATIONARY_WATER] = false; //This gave pistons the ability to drop water :D + g_BlockPistonBreakable[E_BLOCK_STONE_BUTTON] = true; + g_BlockPistonBreakable[E_BLOCK_STONE_PRESSURE_PLATE] = true; + g_BlockPistonBreakable[E_BLOCK_TALL_GRASS] = true; + g_BlockPistonBreakable[E_BLOCK_TORCH] = true; + g_BlockPistonBreakable[E_BLOCK_VINES] = true; + g_BlockPistonBreakable[E_BLOCK_WATER] = false; + g_BlockPistonBreakable[E_BLOCK_WOODEN_DOOR] = true; + g_BlockPistonBreakable[E_BLOCK_WOODEN_PRESSURE_PLATE] = true; + g_BlockPistonBreakable[E_BLOCK_YELLOW_FLOWER] = true; + + // Blocks that can be snowed over: + g_BlockIsSnowable[E_BLOCK_BROWN_MUSHROOM] = false; + g_BlockIsSnowable[E_BLOCK_CACTUS] = false; + g_BlockIsSnowable[E_BLOCK_CHEST] = false; + g_BlockIsSnowable[E_BLOCK_CROPS] = false; + g_BlockIsSnowable[E_BLOCK_FIRE] = false; + g_BlockIsSnowable[E_BLOCK_FIRE] = false; + g_BlockIsSnowable[E_BLOCK_GLASS] = false; + g_BlockIsSnowable[E_BLOCK_ICE] = false; + g_BlockIsSnowable[E_BLOCK_LAVA] = false; + g_BlockIsSnowable[E_BLOCK_LOCKED_CHEST] = false; + g_BlockIsSnowable[E_BLOCK_REDSTONE_REPEATER_OFF] = false; + g_BlockIsSnowable[E_BLOCK_REDSTONE_REPEATER_ON] = false; + g_BlockIsSnowable[E_BLOCK_REDSTONE_TORCH_OFF] = false; + g_BlockIsSnowable[E_BLOCK_REDSTONE_TORCH_ON] = false; + g_BlockIsSnowable[E_BLOCK_REDSTONE_WIRE] = false; + g_BlockIsSnowable[E_BLOCK_RED_MUSHROOM] = false; + g_BlockIsSnowable[E_BLOCK_RED_ROSE] = false; + g_BlockIsSnowable[E_BLOCK_REEDS] = false; + g_BlockIsSnowable[E_BLOCK_SAPLING] = false; + g_BlockIsSnowable[E_BLOCK_SIGN_POST] = false; + g_BlockIsSnowable[E_BLOCK_SNOW] = false; + g_BlockIsSnowable[E_BLOCK_STATIONARY_LAVA] = false; + g_BlockIsSnowable[E_BLOCK_STATIONARY_WATER] = false; + g_BlockIsSnowable[E_BLOCK_TALL_GRASS] = false; + g_BlockIsSnowable[E_BLOCK_TNT] = false; + g_BlockIsSnowable[E_BLOCK_TORCH] = false; + g_BlockIsSnowable[E_BLOCK_WALLSIGN] = false; + g_BlockIsSnowable[E_BLOCK_WATER] = false; + g_BlockIsSnowable[E_BLOCK_YELLOW_FLOWER] = false; + } +} BlockPropertiesInitializer; + + + + diff --git a/source/BlockID.h b/source/BlockID.h index 3e0b261cf..7ec2f9279 100644 --- a/source/BlockID.h +++ b/source/BlockID.h @@ -1,641 +1,641 @@ -#pragma once
-
-//tolua_begin
-enum ENUM_BLOCK_ID
-{
- E_BLOCK_AIR = 0,
- E_BLOCK_STONE = 1,
- E_BLOCK_GRASS = 2,
- E_BLOCK_DIRT = 3,
- E_BLOCK_COBBLESTONE = 4,
- E_BLOCK_PLANKS = 5,
- E_BLOCK_WOOD = E_BLOCK_PLANKS,
- E_BLOCK_SAPLING = 6,
- E_BLOCK_BEDROCK = 7,
- E_BLOCK_WATER = 8,
- E_BLOCK_STATIONARY_WATER = 9,
- E_BLOCK_LAVA = 10,
- E_BLOCK_STATIONARY_LAVA = 11,
- E_BLOCK_SAND = 12,
- E_BLOCK_GRAVEL = 13,
- E_BLOCK_GOLD_ORE = 14,
- E_BLOCK_IRON_ORE = 15,
- E_BLOCK_COAL_ORE = 16,
- E_BLOCK_LOG = 17,
- E_BLOCK_LEAVES = 18,
- E_BLOCK_SPONGE = 19,
- E_BLOCK_GLASS = 20,
- E_BLOCK_LAPIS_ORE = 21,
- E_BLOCK_LAPIS_BLOCK = 22,
- E_BLOCK_DISPENSER = 23,
- E_BLOCK_SANDSTONE = 24,
- E_BLOCK_NOTE_BLOCK = 25,
- E_BLOCK_BED = 26,
- E_BLOCK_POWERED_RAIL = 27,
- E_BLOCK_DETECTOR_RAIL = 28,
- E_BLOCK_STICKY_PISTON = 29,
- E_BLOCK_COBWEB = 30,
- E_BLOCK_TALL_GRASS = 31,
- E_BLOCK_DEAD_BUSH = 32,
- E_BLOCK_PISTON = 33,
- E_BLOCK_PISTON_EXTENSION = 34,
- E_BLOCK_WHITE_CLOTH = 35, // Deprecated, use E_BLOCK_WOOL instead
- E_BLOCK_WOOL = 35,
- E_BLOCK_PISTON_MOVED_BLOCK = 36,
- E_BLOCK_YELLOW_FLOWER = 37,
- E_BLOCK_RED_ROSE = 38,
- E_BLOCK_BROWN_MUSHROOM = 39,
- E_BLOCK_RED_MUSHROOM = 40,
- E_BLOCK_GOLD_BLOCK = 41,
- E_BLOCK_IRON_BLOCK = 42,
- E_BLOCK_DOUBLE_STONE_SLAB = 43,
- E_BLOCK_DOUBLE_STEP = 43, /// OBSOLETE, use E_BLOCK_DOUBLE_STONE_SLAB instead
- E_BLOCK_STONE_SLAB = 44,
- E_BLOCK_STEP = 44, /// OBSOLETE, use E_BLOCK_STONE_SLAB instead
- E_BLOCK_BRICK = 45,
- E_BLOCK_TNT = 46,
- E_BLOCK_BOOKCASE = 47,
- E_BLOCK_MOSSY_COBBLESTONE = 48,
- E_BLOCK_OBSIDIAN = 49,
- E_BLOCK_TORCH = 50,
- E_BLOCK_FIRE = 51,
- E_BLOCK_MOB_SPAWNER = 52,
- E_BLOCK_WOODEN_STAIRS = 53,
- E_BLOCK_CHEST = 54,
- E_BLOCK_REDSTONE_WIRE = 55,
- E_BLOCK_DIAMOND_ORE = 56,
- E_BLOCK_DIAMOND_BLOCK = 57,
- E_BLOCK_CRAFTING_TABLE = 58,
- E_BLOCK_WORKBENCH = 58,
- E_BLOCK_CROPS = 59,
- E_BLOCK_SOIL = 60, // Deprecated, use E_BLOCK_FARMLAND instead
- E_BLOCK_FARMLAND = 60,
- E_BLOCK_FURNACE = 61,
- E_BLOCK_LIT_FURNACE = 62,
- E_BLOCK_BURNING_FURNACE = 62,
- E_BLOCK_SIGN_POST = 63,
- E_BLOCK_WOODEN_DOOR = 64,
- E_BLOCK_LADDER = 65,
- E_BLOCK_RAIL = 66,
- E_BLOCK_MINECART_TRACKS = 66,
- E_BLOCK_COBBLESTONE_STAIRS = 67,
- E_BLOCK_WALLSIGN = 68,
- E_BLOCK_LEVER = 69,
- E_BLOCK_STONE_PRESSURE_PLATE = 70,
- E_BLOCK_IRON_DOOR = 71,
- E_BLOCK_WOODEN_PRESSURE_PLATE = 72,
- E_BLOCK_REDSTONE_ORE = 73,
- E_BLOCK_REDSTONE_ORE_GLOWING = 74,
- E_BLOCK_REDSTONE_TORCH_OFF = 75,
- E_BLOCK_REDSTONE_TORCH_ON = 76,
- E_BLOCK_STONE_BUTTON = 77,
- E_BLOCK_SNOW = 78,
- E_BLOCK_ICE = 79,
- E_BLOCK_SNOW_BLOCK = 80,
- E_BLOCK_CACTUS = 81,
- E_BLOCK_CLAY = 82,
- E_BLOCK_SUGARCANE = 83,
- E_BLOCK_REEDS = 83,
- E_BLOCK_JUKEBOX = 84,
- E_BLOCK_FENCE = 85,
- E_BLOCK_PUMPKIN = 86,
- E_BLOCK_BLOODSTONE = 87, // Deprecated, use E_BLOCK_NETHERRACK
- E_BLOCK_NETHERRACK = 87,
- E_BLOCK_SOULSAND = 88,
- E_BLOCK_GLOWSTONE = 89,
- E_BLOCK_PORT = 90, // Deprecated, use E_BLOCK_NETHER_PORTAL instead
- E_BLOCK_NETHER_PORTAL = 90,
- E_BLOCK_JACK_O_LANTERN = 91,
- E_BLOCK_CAKE = 92,
- E_BLOCK_REDSTONE_REPEATER_OFF = 93,
- E_BLOCK_REDSTONE_REPEATER_ON = 94,
- E_BLOCK_LOCKED_CHEST = 95,
- E_BLOCK_TRAPDOOR = 96,
- E_BLOCK_SILVERFISH_EGG = 97,
- E_BLOCK_STONE_BRICKS = 98,
- E_BLOCK_HUGE_BROWN_MUSHROOM = 99,
- E_BLOCK_HUGE_RED_MUSHROOM = 100,
- E_BLOCK_IRON_BAR = 101,
- E_BLOCK_GLASS_PLANE = 102,
- E_BLOCK_MELON = 103,
- E_BLOCK_PUMPKIN_STEM = 104,
- E_BLOCK_MELON_STEM = 105,
- E_BLOCK_VINES = 106,
- E_BLOCK_FENCE_GATE = 107,
- E_BLOCK_BRICK_STAIRS = 108,
- E_BLOCK_STONE_BRICK_STAIRS = 109,
- E_BLOCK_MYCELIUM = 110,
- E_BLOCK_LILY_PAD = 111,
- E_BLOCK_NETHER_BRICK = 112,
- E_BLOCK_NETHER_BRICK_FENCE = 113,
- E_BLOCK_NETHER_BRICK_STAIRS = 114,
- E_BLOCK_NETHER_WART = 115,
- E_BLOCK_ENCHANTMENT_TABLE = 116,
- E_BLOCK_BREWING_STAND = 117,
- E_BLOCK_CAULDRON = 118,
- E_BLOCK_END_PORTAL = 119,
- E_BLOCK_END_PORTAL_FRAME = 120,
- E_BLOCK_END_STONE = 121,
- E_BLOCK_DRAGON_EGG = 122,
- E_BLOCK_REDSTONE_LAMP_OFF = 123,
- E_BLOCK_REDSTONE_LAMP_ON = 124,
- E_BLOCK_DOUBLE_WOODEN_SLAB = 125,
- E_BLOCK_WOODEN_SLAB = 126,
- E_BLOCK_COCA_PLANT = 127,
- E_BLOCK_SANDSTONE_STAIRS = 128,
- E_BLOCK_EMERALD_ORE = 129,
- E_BLOCK_ENDER_CHEST = 130,
- E_BLOCK_TRIPWIRE_HOOK = 131,
- E_BLOCK_TRIPWIRE = 132,
- E_BLOCK_EMERALD_BLOCK = 133,
- E_BLOCK_ = 121,
-};
-//tolua_end
-
-//tolua_begin
-enum ENUM_ITEM_ID
-{
- E_ITEM_EMPTY = -1,
- E_ITEM_STONE = 1,
- E_ITEM_GRASS = 2,
- E_ITEM_DIRT = 3,
- E_ITEM_COBBLESTONE = 4,
- E_ITEM_PLANKS = 5,
- E_ITEM_WOOD = 5, // obsolete, use E_ITEM_PLANKS instead
- E_ITEM_SAPLING = 6,
- E_ITEM_BEDROCK = 7,
- E_ITEM_WATER = 8,
- E_ITEM_STATIONARY_WATER = 9,
- E_ITEM_LAVA = 10,
- E_ITEM_STATIONARY_LAVA = 11,
- E_ITEM_SAND = 12,
- E_ITEM_GRAVEL = 13,
- E_ITEM_GOLD_ORE = 14,
- E_ITEM_IRON_ORE = 15,
- E_ITEM_COAL_ORE = 16,
- E_ITEM_LOG = 17,
- E_ITEM_LEAVES = 18,
- E_ITEM_SPONGE = 19,
- E_ITEM_GLASS = 20,
- E_ITEM_LAPIS_ORE = 21,
- E_ITEM_LAPIS_BLOCK = 22,
- E_ITEM_DISPENSER = 23,
- E_ITEM_SANDSTONE = 24,
- E_ITEM_NOTE_ITEM = 25,
-
- E_ITEM_POWERED_RAIL = 27,
- E_ITEM_DETECTOR_RAIL = 28,
- E_ITEM_STICKY_PISTON = 29,
- E_ITEM_COBWEB = 30,
- E_ITEM_TALL_GRASS = 31,
- E_ITEM_DEAD_BRUSH = 32,
- E_ITEM_PISTON = 33,
- E_ITEM_PISTON_EXTENSION = 34,
- E_ITEM_WHITE_CLOTH = 35,
- E_ITEM_PISTON_MOVED_BLOCK = 36,
- E_ITEM_YELLOW_FLOWER = 37,
- E_ITEM_RED_ROSE = 38,
- E_ITEM_BROWN_MUSHROOM = 39,
- E_ITEM_RED_MUSHROOM = 40,
- E_ITEM_GOLD_BLOCK = 41,
- E_ITEM_IRON_BLOCK = 42,
- E_ITEM_DOUBLE_STONE_SLAB = 43,
- E_ITEM_DOUBLE_STEP = 43, /// OBSOLETE, use E_ITEM_DOUBLE_STONE_SLAB
- E_ITEM_STONE_SLAB = 44,
- E_ITEM_STEP = 44, /// OBSOLETE, use E_ITEM_STONE_SLAB
- E_ITEM_BRICK = 45,
- E_ITEM_TNT = 46,
- E_ITEM_BOOKCASE = 47,
- E_ITEM_MOSSY_COBBLESTONE = 48,
- E_ITEM_OBSIDIAN = 49,
- E_ITEM_TORCH = 50,
- E_ITEM_FIRE = 51,
- E_ITEM_MOB_SPAWNER = 52,
- E_ITEM_WOODEN_STAIRS = 53,
- E_ITEM_CHEST = 54,
- E_ITEM_REDSTONE_WIRE = 55,
- E_ITEM_DIAMOND_ORE = 56,
- E_ITEM_DIAMOND_BLOCK = 57,
- E_ITEM_WORKBENCH = 58,
- E_ITEM_CROPS = 59,
- E_ITEM_SOIL = 60,
- E_ITEM_FURNACE = 61,
- E_ITEM_BURNING_FURNACE = 62,
- E_ITEM_SIGN_POST = 63,
-
- E_ITEM_LADDER = 65,
- E_ITEM_MINECART_TRACKS = 66,
- E_ITEM_COBBLESTONE_STAIRS = 67,
- E_ITEM_WALLSIGN = 68,
- E_ITEM_LEVER = 69,
- E_ITEM_STONE_PRESSURE_PLATE = 70,
-
- E_ITEM_WOODEN_PRESSURE_PLATE = 72,
- E_ITEM_REDSTONE_ORE = 73,
- E_ITEM_REDSTONE_ORE_GLOWING = 74,
- E_ITEM_REDSTONE_TORCH_ON = 75,
- E_ITEM_REDSTONE_TORCH_OFF = 76,
- E_ITEM_STONE_BUTTON = 77,
- E_ITEM_SNOW = 78,
- E_ITEM_ICE = 79,
- E_ITEM_SNOW_BLOCK = 80,
- E_ITEM_CACTUS = 81,
-
- E_ITEM_REEDS = 83,
- E_ITEM_JUKEBOX = 84,
- E_ITEM_FENCE = 85,
- E_ITEM_PUMPKIN = 86,
- E_ITEM_BLOODSTONE = 87,
- E_ITEM_SOULSAND = 88,
- E_ITEM_GLOWSTONE = 89,
- E_ITEM_PORT = 90,
- E_ITEM_JACK_O_LANTERN = 91,
-
- E_ITEM_REDSTONE_REPEATER_OFF = 93,
- E_ITEM_REDSTONE_REPEATER_ON = 94,
- E_ITEM_LOCKED_CHEST = 95,
- E_ITEM_TRAPDOOR = 96,
- E_ITEM_SILVERFISH_EGG = 97,
- E_ITEM_STONE_BRICKS = 98,
- E_ITEM_HUGE_BROWN_MUSHROOM = 99,
- E_ITEM_HUGE_RED_MUSHROOM = 100,
- E_ITEM_IRON_BAR = 101,
- E_ITEM_GLASS_PLANE = 102,
- E_ITEM_MELON = 103,
- E_ITEM_PUMPKIN_STEM = 104,
- E_ITEM_MELON_STEM = 105,
- E_ITEM_VINES = 106,
- E_ITEM_FENCE_GATE = 107,
- E_ITEM_BRICK_STAIRS = 108,
- E_ITEM_STONE_BRICK_STAIRS = 109,
- E_ITEM_MYCELIUM = 110,
- E_ITEM_LILY_PAD = 111,
- E_ITEM_NETHER_BRICK = 112,
- E_ITEM_NETHER_BRICK_FENCE = 113,
- E_ITEM_NETHER_BRICK_STAIRS = 114,
-
- E_ITEM_ENCHANTMENT_TABLE = 116,
-
- E_ITEM_END_PORTAL = 119,
- E_ITEM_END_PORTAL_FRAME = 120,
- E_ITEM_END_STONE = 121,
-
- E_ITEM_DOUBLE_WOODEN_SLAB = 125,
- E_ITEM_WOODEN_SLAB = 126,
- E_ITEM_COCA_PLANT = 127,
- E_ITEM_SANDSTONE_STAIRS = 128,
- E_ITEM_EMERALD_ORE = 129,
- E_ITEM_ENDER_CHEST = 130,
- E_ITEM_TRIPWIRE_HOOK = 131,
- E_ITEM_TRIPWIRE = 132,
- E_ITEM_EMERALD_BLOCK = 133,
-
- E_ITEM_IRON_SHOVEL = 256,
- E_ITEM_IRON_PICKAXE = 257,
- E_ITEM_IRON_AXE = 258,
- E_ITEM_FLINT_AND_STEEL = 259,
- E_ITEM_RED_APPLE = 260,
- E_ITEM_APPLE = 260, // OBSOLETE, use E_ITEM_RED_APPLE instead
- E_ITEM_BOW = 261,
- E_ITEM_ARROW = 262,
- E_ITEM_COAL = 263,
- E_ITEM_DIAMOND = 264,
- E_ITEM_IRON = 265,
- E_ITEM_GOLD = 266,
- E_ITEM_IRON_SWORD = 267,
- E_ITEM_WOODEN_SWORD = 268,
- E_ITEM_WOODEN_SHOVEL = 269,
- E_ITEM_WOODEN_PICKAXE = 270,
- E_ITEM_WOODEN_AXE = 271,
- E_ITEM_STONE_SWORD = 272,
- E_ITEM_STONE_SHOVEL = 273,
- E_ITEM_STONE_PICKAXE = 274,
- E_ITEM_STONE_AXE = 275,
- E_ITEM_DIAMOND_SWORD = 276,
- E_ITEM_DIAMOND_SHOVEL = 277,
- E_ITEM_DIAMOND_PICKAXE = 278,
- E_ITEM_DIAMOND_AXE = 279,
- E_ITEM_STICK = 280,
- E_ITEM_BOWL = 281,
- E_ITEM_MUSHROOM_SOUP = 282,
- E_ITEM_GOLD_SWORD = 283,
- E_ITEM_GOLD_SHOVEL = 284,
- E_ITEM_GOLD_PICKAXE = 285,
- E_ITEM_GOLD_AXE = 286,
- E_ITEM_STRING = 287,
- E_ITEM_FEATHER = 288,
- E_ITEM_GUNPOWDER = 289,
- E_ITEM_WOODEN_HOE = 290,
- E_ITEM_STONE_HOE = 291,
- E_ITEM_IRON_HOE = 292,
- E_ITEM_DIAMOND_HOE = 293,
- E_ITEM_GOLD_HOE = 294,
- E_ITEM_SEEDS = 295,
- E_ITEM_WHEAT = 296,
- E_ITEM_BREAD = 297,
- E_ITEM_LEATHER_CAP = 298,
- E_ITEM_LEATHER_TUNIC = 299,
- E_ITEM_LEATHER_PANTS = 300,
- E_ITEM_LEATHER_BOOTS = 301,
- E_ITEM_CHAIN_HELMET = 302,
- E_ITEM_CHAIN_CHESTPLATE = 303,
- E_ITEM_CHAIN_LEGGINGS = 304,
- E_ITEM_CHAIN_BOOTS = 305,
- E_ITEM_IRON_HELMET = 306,
- E_ITEM_IRON_CHESTPLATE = 307,
- E_ITEM_IRON_LEGGINGS = 308,
- E_ITEM_IRON_BOOTS = 309,
- E_ITEM_DIAMOND_HELMET = 310,
- E_ITEM_DIAMOND_CHESTPLATE = 311,
- E_ITEM_DIAMOND_LEGGINGS = 312,
- E_ITEM_DIAMOND_BOOTS = 313,
- E_ITEM_GOLD_HELMET = 314,
- E_ITEM_GOLD_CHESTPLATE = 315,
- E_ITEM_GOLD_LEGGINGS = 316,
- E_ITEM_GOLD_BOOTS = 317,
- E_ITEM_FLINT = 318,
- E_ITEM_RAW_MEAT = 319,
- E_ITEM_COOKED_MEAT = 320,
- E_ITEM_PAINTINGS = 321,
- E_ITEM_GOLDEN_APPLE = 322,
- E_ITEM_SIGN = 323,
- E_ITEM_WOODEN_DOOR = 324,
- E_ITEM_BUCKET = 325,
- E_ITEM_WATER_BUCKET = 326,
- E_ITEM_LAVA_BUCKET = 327,
- E_ITEM_MINECART = 328,
- E_ITEM_SADDLE = 329,
- E_ITEM_IRON_DOOR = 330,
- E_ITEM_REDSTONE_DUST = 331,
- E_ITEM_SNOWBALL = 332,
- E_ITEM_BOAT = 333,
- E_ITEM_LEATHER = 334,
- E_ITEM_MILK = 335,
- E_ITEM_CLAY_BRICK = 336,
- E_ITEM_CLAY = 337,
- E_ITEM_SUGARCANE = 338,
- E_ITEM_SUGAR_CANE = 338,
- E_ITEM_PAPER = 339,
- E_ITEM_BOOK = 340,
- E_ITEM_SLIMEBALL = 341,
- E_ITEM_CHEST_MINECART = 342,
- E_ITEM_FURNACE_MINECART = 343,
- E_ITEM_EGG = 344,
- E_ITEM_COMPASS = 345,
- E_ITEM_FISHING_ROD = 346,
- E_ITEM_CLOCK = 347,
- E_ITEM_GLOWSTONE_DUST = 348,
- E_ITEM_RAW_FISH = 349,
- E_ITEM_COOKED_FISH = 350,
- E_ITEM_DYE = 351,
- E_ITEM_BONE = 352,
- E_ITEM_SUGAR = 353,
- E_ITEM_CAKE = 354,
- E_ITEM_BED = 355,
- E_ITEM_REDSTONE_REPEATER = 356,
- E_ITEM_COOKIE = 357,
- E_ITEM_MAP = 358,
- E_ITEM_SHEARS = 359,
- E_ITEM_MELON_SLICE = 360,
- E_ITEM_PUMPKIN_SEEDS = 361,
- E_ITEM_MELON_SEEDS = 362,
- E_ITEM_RAW_BEEF = 363,
- E_ITEM_STEAK = 364,
- E_ITEM_RAW_CHICKEN = 365,
- E_ITEM_COOKED_CHICKEN = 366,
- E_ITEM_ROTTEN_FLESH = 367,
- E_ITEM_ENDER_PEARL = 368,
- E_ITEM_BLAZE_ROD = 369,
- E_ITEM_GHAST_TEAR = 370,
- E_ITEM_GOLD_NUGGET = 371,
- E_ITEM_NETHER_WART = 372,
- E_ITEM_POTIONS = 373,
- E_ITEM_GLASS_BOTTLE = 374,
- E_ITEM_SPIDER_EYE = 375,
- E_ITEM_FERMENTED_SPIDER_EYE = 376,
- E_ITEM_BLAZE_POWDER = 377,
- E_ITEM_MAGMA_CREAM = 378,
- E_ITEM_BREWING_STAND = 379,
- E_ITEM_CAULDRON = 380,
- E_ITEM_EYE_OF_ENDER = 381,
- E_ITEM_GLISTERING_MELON = 382,
-
- E_ITEM_SPAWN_EGG = 383,
- E_ITEM_BOTTLE_O_ENCHANTING = 384,
- E_ITEM_FIRE_CHARGE = 385,
- E_ITEM_BOOK_AND_QUILL = 386,
- E_ITEM_WRITTEN_BOOK = 387,
- E_ITEM_EMERALD = 388,
-
- E_ITEM_13_DISC = 2256,
- E_ITEM_CAT_DISC = 2257,
- E_ITEM_BLOCKS_DISC = 2258,
- E_ITEM_CHIRP_DISC = 2259,
- E_ITEM_FAR_DISC = 2260,
- E_ITEM_MALL_DISC = 2261,
- E_ITEM_MELLOHI_DISC = 2262,
- E_ITEM_STAL_DISC = 2263,
- E_ITEM_STRAD_DISC = 2264,
- E_ITEM_WARD_DISC = 2265,
- E_ITEM_11_DISC = 2266,
-};
-
-
-
-
-
-enum
-{
- // E_BLOCK_PLANKS metas:
- E_META_PLANKS_APPLE = 0,
- E_META_PLANKS_CONIFER = 1,
- E_META_PLANKS_BIRCH = 2,
- E_META_PLANKS_JUNGLE = 3,
-
- // E_BLOCK_LOG metas:
- E_META_LOG_APPLE = 0,
- E_META_LOG_CONIFER = 1,
- E_META_LOG_BIRCH = 2,
- E_META_LOG_JUNGLE = 3,
-
- // E_BLOCK_LEAVES metas:
- E_META_LEAVES_APPLE = 0,
- E_META_LEAVES_CONIFER = 1,
- E_META_LEAVES_BIRCH = 2,
- E_META_LEAVES_JUNGLE = 3,
-
- // E_BLOCK_SAPLING metas (lowest 3 bits):
- E_META_SAPLING_APPLE = 0,
- E_META_SAPLING_CONIFER = 1,
- E_META_SAPLING_BIRCH = 2,
- E_META_SAPLING_JUNGLE = 3,
-
- // E_BLOCK_TALL_GRASS metas:
- E_META_TALL_GRASS_DEAD_SHRUB = 0,
- E_META_TALL_GRASS_GRASS = 1,
- E_META_TALL_GRASS_FERN = 2,
-
- // E_BLOCK_SANDSTONE metas:
- E_META_SANDSTONE_NORMAL = 0,
- E_META_SANDSTONE_ORNAMENT = 1,
- E_META_SANDSTONE_SMOOTH = 2,
-
- // E_BLOCK_WOOL metas:
- E_META_WOOL_WHITE = 0,
- E_META_WOOL_ORANGE = 1,
- E_META_WOOL_MAGENTA = 2,
- E_META_WOOL_LIGHTBLUE = 3,
- E_META_WOOL_YELLOW = 4,
- E_META_WOOL_LIGHTGREEN = 5,
- E_META_WOOL_PINK = 6,
- E_META_WOOL_GRAY = 7,
- E_META_WOOL_LIGHTGRAY = 8,
- E_META_WOOL_CYAN = 9,
- E_META_WOOL_PURPLE = 10,
- E_META_WOOL_BLUE = 11,
- E_META_WOOL_BROWN = 12,
- E_META_WOOL_GREEN = 13,
- E_META_WOOL_RED = 14,
- E_META_WOOL_BLACK = 15,
-
- // E_BLOCK_DOUBLE_STEP metas:
- E_META_DOUBLE_STEP_STONE = 0,
- E_META_DOUBLE_STEP_SANDSTONE = 1,
- E_META_DOUBLE_STEP_WOODEN = 2,
- E_META_DOUBLE_STEP_COBBLESTONE = 3,
- E_META_DOUBLE_STEP_BRICK = 4,
- E_META_DOUBLE_STEP_STONE_BRICK = 5,
- E_META_DOUBLE_STEP_STONE_SECRET = 6,
-
- // E_BLOCK_STEP metas:
- E_META_STEP_STONE = 0,
- E_META_STEP_SANDSTONE = 1,
- E_META_STEP_PLANKS = 2,
- E_META_STEP_COBBLESTONE = 3,
- E_META_STEP_BRICK = 4,
- E_META_STEP_STONE_BRICK = 5,
- E_META_STEP_STONE_SECRET = 6,
-
- // E_BLOCK_SILVERFISH_EGG metas:
- E_META_SILVERFISH_EGG_STONE = 0,
- E_META_SILVERFISH_EGG_COBBLESTONE = 1,
- E_META_SILVERFISH_EGG_STONE_BRICK = 2,
-
- // E_BLOCK_STONE_BRICKS metas:
- E_META_STONE_BRICK_NORMAL = 0,
- E_META_STONE_BRICK_MOSSY = 1,
- E_META_STONE_BRICK_CRACKED = 2,
- E_META_STONE_BRICK_ORNAMENT = 3,
-
- // E_BLOCK_WOODEN_DOUBLE_STEP metas:
- E_BLOCK_WOODEN_DOUBLE_STEP_APPLE = 0,
- E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER = 1,
- E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH = 2,
- E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE = 3,
-
- // E_BLOCK_WOODEN_STEP metas:
- E_BLOCK_WOODEN_STEP_APPLE = 0,
- E_BLOCK_WOODEN_STEP_CONIFER = 1,
- E_BLOCK_WOODEN_STEP_BIRCH = 2,
- E_BLOCK_WOODEN_STEP_JUNGLE = 3,
-} ;
-
-
-
-
-
-
-
-enum
-{
- // E_ITEM_COAL metas:
- E_META_COAL_NORMAL = 0,
- E_META_COAL_CHARCOAL = 1,
-
- // E_ITEM_GOLDEN_APPLE metas:
- E_META_GOLDEN_APPLE_NORMAL = 0,
- E_META_GOLDEN_APPLE_ENCHANTED = 1,
-
- // E_ITEM_DYE metas:
- E_META_DYE_BLACK = 0,
- E_META_DYE_RED = 1,
- E_META_DYE_GREEN = 2,
- E_META_DYE_BROWN = 3,
- E_META_DYE_BLUE = 4,
- E_META_DYE_PURPLE = 5,
- E_META_DYE_CYAN = 6,
- E_META_DYE_LIGHTGRAY = 7,
- E_META_DYE_GRAY = 8,
- E_META_DYE_PINK = 9,
- E_META_DYE_LIGHTGREEN = 10,
- E_META_DYE_YELLOW = 11,
- E_META_DYE_LIGHTBLUE = 12,
- E_META_DYE_MAGENTA = 13,
- E_META_DYE_ORANGE = 14,
- E_META_DYE_WHITE = 15,
-
- // E_ITEM_SPAWN_EGG spawn EntityIDs:
- // hostile:
- E_META_SPAWN_EGG_CREEPER = 50,
- E_META_SPAWN_EGG_SKELETON = 51,
- E_META_SPAWN_EGG_SPIDER = 52,
- E_META_SPAWN_EGG_ZOMBIE = 54,
- E_META_SPAWN_EGG_SLIME = 55,
- E_META_SPAWN_EGG_GHAST = 56,
- E_META_SPAWN_EGG_ZOMBIE_PIGMAN = 57,
- E_META_SPAWN_EGG_ENDERMAN = 58,
- E_META_SPAWN_EGG_CAVE_SPIDER = 59,
- E_META_SPAWN_EGG_SILVERFISH = 60,
- E_META_SPAWN_EGG_BLAZE = 61,
- E_META_SPAWN_EGG_MAGMA_CUBE = 62,
- E_META_SPAWN_EGG_GIANT = 53,
- E_META_SPAWN_EGG_ENDER_DRAGON = 63,
- E_META_SPAWN_EGG_PIG = 90,
- E_META_SPAWN_EGG_SHEEP = 91,
- E_META_SPAWN_EGG_COW = 92,
- E_META_SPAWN_EGG_CHICKEN = 93,
- E_META_SPAWN_EGG_SQUID = 94,
- E_META_SPAWN_EGG_WOLF = 95,
- E_META_SPAWN_EGG_MOOSHROOM = 96,
- E_META_SPAWN_EGG_OCELOT = 98,
- E_META_SPAWN_EGG_VILLAGER = 120,
- E_META_SPAWN_EGG_SNOW_GOLEM = 97,
- E_META_SPAWN_EGG_IRON_GOLEM = 99,
-} ;
-//tolua_end
-
-
-
-
-// fwd: cItem.h:
-class cItem;
-
-
-
-
-
-/// Translates a blocktype string into blocktype. Takes either a number or an items.ini alias as input. Returns -1 on failure.
-extern int BlockStringToType(const AString & a_BlockTypeString); // tolua_export
-
-/// Translates an itemtype string into an item. Takes either a number, number^number, number:number or an items.ini alias as input. Returns true if successful.
-extern bool StringToItem(const AString & a_ItemTypeString, cItem & a_Item); // tolua_export
-
-/// Translates a biome string to biome enum. Takes either a number or a biome alias (built-in). Returns -1 on failure.
-extern EMCSBiome StringToBiome(const AString & a_BiomeString);
-
-
-
-
-
-// Block properties:
-extern NIBBLETYPE g_BlockLightValue[256];
-extern NIBBLETYPE g_BlockSpreadLightFalloff[256];
-extern bool g_BlockTransparent[256];
-extern bool g_BlockOneHitDig[256];
-extern bool g_BlockPistonBreakable[256];
-extern bool g_BlockIsSnowable[256];
-
-
-
-
-
+#pragma once + +//tolua_begin +enum ENUM_BLOCK_ID +{ + E_BLOCK_AIR = 0, + E_BLOCK_STONE = 1, + E_BLOCK_GRASS = 2, + E_BLOCK_DIRT = 3, + E_BLOCK_COBBLESTONE = 4, + E_BLOCK_PLANKS = 5, + E_BLOCK_WOOD = E_BLOCK_PLANKS, + E_BLOCK_SAPLING = 6, + E_BLOCK_BEDROCK = 7, + E_BLOCK_WATER = 8, + E_BLOCK_STATIONARY_WATER = 9, + E_BLOCK_LAVA = 10, + E_BLOCK_STATIONARY_LAVA = 11, + E_BLOCK_SAND = 12, + E_BLOCK_GRAVEL = 13, + E_BLOCK_GOLD_ORE = 14, + E_BLOCK_IRON_ORE = 15, + E_BLOCK_COAL_ORE = 16, + E_BLOCK_LOG = 17, + E_BLOCK_LEAVES = 18, + E_BLOCK_SPONGE = 19, + E_BLOCK_GLASS = 20, + E_BLOCK_LAPIS_ORE = 21, + E_BLOCK_LAPIS_BLOCK = 22, + E_BLOCK_DISPENSER = 23, + E_BLOCK_SANDSTONE = 24, + E_BLOCK_NOTE_BLOCK = 25, + E_BLOCK_BED = 26, + E_BLOCK_POWERED_RAIL = 27, + E_BLOCK_DETECTOR_RAIL = 28, + E_BLOCK_STICKY_PISTON = 29, + E_BLOCK_COBWEB = 30, + E_BLOCK_TALL_GRASS = 31, + E_BLOCK_DEAD_BUSH = 32, + E_BLOCK_PISTON = 33, + E_BLOCK_PISTON_EXTENSION = 34, + E_BLOCK_WHITE_CLOTH = 35, // Deprecated, use E_BLOCK_WOOL instead + E_BLOCK_WOOL = 35, + E_BLOCK_PISTON_MOVED_BLOCK = 36, + E_BLOCK_YELLOW_FLOWER = 37, + E_BLOCK_RED_ROSE = 38, + E_BLOCK_BROWN_MUSHROOM = 39, + E_BLOCK_RED_MUSHROOM = 40, + E_BLOCK_GOLD_BLOCK = 41, + E_BLOCK_IRON_BLOCK = 42, + E_BLOCK_DOUBLE_STONE_SLAB = 43, + E_BLOCK_DOUBLE_STEP = 43, /// OBSOLETE, use E_BLOCK_DOUBLE_STONE_SLAB instead + E_BLOCK_STONE_SLAB = 44, + E_BLOCK_STEP = 44, /// OBSOLETE, use E_BLOCK_STONE_SLAB instead + E_BLOCK_BRICK = 45, + E_BLOCK_TNT = 46, + E_BLOCK_BOOKCASE = 47, + E_BLOCK_MOSSY_COBBLESTONE = 48, + E_BLOCK_OBSIDIAN = 49, + E_BLOCK_TORCH = 50, + E_BLOCK_FIRE = 51, + E_BLOCK_MOB_SPAWNER = 52, + E_BLOCK_WOODEN_STAIRS = 53, + E_BLOCK_CHEST = 54, + E_BLOCK_REDSTONE_WIRE = 55, + E_BLOCK_DIAMOND_ORE = 56, + E_BLOCK_DIAMOND_BLOCK = 57, + E_BLOCK_CRAFTING_TABLE = 58, + E_BLOCK_WORKBENCH = 58, + E_BLOCK_CROPS = 59, + E_BLOCK_SOIL = 60, // Deprecated, use E_BLOCK_FARMLAND instead + E_BLOCK_FARMLAND = 60, + E_BLOCK_FURNACE = 61, + E_BLOCK_LIT_FURNACE = 62, + E_BLOCK_BURNING_FURNACE = 62, + E_BLOCK_SIGN_POST = 63, + E_BLOCK_WOODEN_DOOR = 64, + E_BLOCK_LADDER = 65, + E_BLOCK_RAIL = 66, + E_BLOCK_MINECART_TRACKS = 66, + E_BLOCK_COBBLESTONE_STAIRS = 67, + E_BLOCK_WALLSIGN = 68, + E_BLOCK_LEVER = 69, + E_BLOCK_STONE_PRESSURE_PLATE = 70, + E_BLOCK_IRON_DOOR = 71, + E_BLOCK_WOODEN_PRESSURE_PLATE = 72, + E_BLOCK_REDSTONE_ORE = 73, + E_BLOCK_REDSTONE_ORE_GLOWING = 74, + E_BLOCK_REDSTONE_TORCH_OFF = 75, + E_BLOCK_REDSTONE_TORCH_ON = 76, + E_BLOCK_STONE_BUTTON = 77, + E_BLOCK_SNOW = 78, + E_BLOCK_ICE = 79, + E_BLOCK_SNOW_BLOCK = 80, + E_BLOCK_CACTUS = 81, + E_BLOCK_CLAY = 82, + E_BLOCK_SUGARCANE = 83, + E_BLOCK_REEDS = 83, + E_BLOCK_JUKEBOX = 84, + E_BLOCK_FENCE = 85, + E_BLOCK_PUMPKIN = 86, + E_BLOCK_BLOODSTONE = 87, // Deprecated, use E_BLOCK_NETHERRACK + E_BLOCK_NETHERRACK = 87, + E_BLOCK_SOULSAND = 88, + E_BLOCK_GLOWSTONE = 89, + E_BLOCK_PORT = 90, // Deprecated, use E_BLOCK_NETHER_PORTAL instead + E_BLOCK_NETHER_PORTAL = 90, + E_BLOCK_JACK_O_LANTERN = 91, + E_BLOCK_CAKE = 92, + E_BLOCK_REDSTONE_REPEATER_OFF = 93, + E_BLOCK_REDSTONE_REPEATER_ON = 94, + E_BLOCK_LOCKED_CHEST = 95, + E_BLOCK_TRAPDOOR = 96, + E_BLOCK_SILVERFISH_EGG = 97, + E_BLOCK_STONE_BRICKS = 98, + E_BLOCK_HUGE_BROWN_MUSHROOM = 99, + E_BLOCK_HUGE_RED_MUSHROOM = 100, + E_BLOCK_IRON_BAR = 101, + E_BLOCK_GLASS_PLANE = 102, + E_BLOCK_MELON = 103, + E_BLOCK_PUMPKIN_STEM = 104, + E_BLOCK_MELON_STEM = 105, + E_BLOCK_VINES = 106, + E_BLOCK_FENCE_GATE = 107, + E_BLOCK_BRICK_STAIRS = 108, + E_BLOCK_STONE_BRICK_STAIRS = 109, + E_BLOCK_MYCELIUM = 110, + E_BLOCK_LILY_PAD = 111, + E_BLOCK_NETHER_BRICK = 112, + E_BLOCK_NETHER_BRICK_FENCE = 113, + E_BLOCK_NETHER_BRICK_STAIRS = 114, + E_BLOCK_NETHER_WART = 115, + E_BLOCK_ENCHANTMENT_TABLE = 116, + E_BLOCK_BREWING_STAND = 117, + E_BLOCK_CAULDRON = 118, + E_BLOCK_END_PORTAL = 119, + E_BLOCK_END_PORTAL_FRAME = 120, + E_BLOCK_END_STONE = 121, + E_BLOCK_DRAGON_EGG = 122, + E_BLOCK_REDSTONE_LAMP_OFF = 123, + E_BLOCK_REDSTONE_LAMP_ON = 124, + E_BLOCK_DOUBLE_WOODEN_SLAB = 125, + E_BLOCK_WOODEN_SLAB = 126, + E_BLOCK_COCA_PLANT = 127, + E_BLOCK_SANDSTONE_STAIRS = 128, + E_BLOCK_EMERALD_ORE = 129, + E_BLOCK_ENDER_CHEST = 130, + E_BLOCK_TRIPWIRE_HOOK = 131, + E_BLOCK_TRIPWIRE = 132, + E_BLOCK_EMERALD_BLOCK = 133, + E_BLOCK_ = 121, +}; +//tolua_end + +//tolua_begin +enum ENUM_ITEM_ID +{ + E_ITEM_EMPTY = -1, + E_ITEM_STONE = 1, + E_ITEM_GRASS = 2, + E_ITEM_DIRT = 3, + E_ITEM_COBBLESTONE = 4, + E_ITEM_PLANKS = 5, + E_ITEM_WOOD = 5, // obsolete, use E_ITEM_PLANKS instead + E_ITEM_SAPLING = 6, + E_ITEM_BEDROCK = 7, + E_ITEM_WATER = 8, + E_ITEM_STATIONARY_WATER = 9, + E_ITEM_LAVA = 10, + E_ITEM_STATIONARY_LAVA = 11, + E_ITEM_SAND = 12, + E_ITEM_GRAVEL = 13, + E_ITEM_GOLD_ORE = 14, + E_ITEM_IRON_ORE = 15, + E_ITEM_COAL_ORE = 16, + E_ITEM_LOG = 17, + E_ITEM_LEAVES = 18, + E_ITEM_SPONGE = 19, + E_ITEM_GLASS = 20, + E_ITEM_LAPIS_ORE = 21, + E_ITEM_LAPIS_BLOCK = 22, + E_ITEM_DISPENSER = 23, + E_ITEM_SANDSTONE = 24, + E_ITEM_NOTE_ITEM = 25, + + E_ITEM_POWERED_RAIL = 27, + E_ITEM_DETECTOR_RAIL = 28, + E_ITEM_STICKY_PISTON = 29, + E_ITEM_COBWEB = 30, + E_ITEM_TALL_GRASS = 31, + E_ITEM_DEAD_BRUSH = 32, + E_ITEM_PISTON = 33, + E_ITEM_PISTON_EXTENSION = 34, + E_ITEM_WHITE_CLOTH = 35, + E_ITEM_PISTON_MOVED_BLOCK = 36, + E_ITEM_YELLOW_FLOWER = 37, + E_ITEM_RED_ROSE = 38, + E_ITEM_BROWN_MUSHROOM = 39, + E_ITEM_RED_MUSHROOM = 40, + E_ITEM_GOLD_BLOCK = 41, + E_ITEM_IRON_BLOCK = 42, + E_ITEM_DOUBLE_STONE_SLAB = 43, + E_ITEM_DOUBLE_STEP = 43, /// OBSOLETE, use E_ITEM_DOUBLE_STONE_SLAB + E_ITEM_STONE_SLAB = 44, + E_ITEM_STEP = 44, /// OBSOLETE, use E_ITEM_STONE_SLAB + E_ITEM_BRICK = 45, + E_ITEM_TNT = 46, + E_ITEM_BOOKCASE = 47, + E_ITEM_MOSSY_COBBLESTONE = 48, + E_ITEM_OBSIDIAN = 49, + E_ITEM_TORCH = 50, + E_ITEM_FIRE = 51, + E_ITEM_MOB_SPAWNER = 52, + E_ITEM_WOODEN_STAIRS = 53, + E_ITEM_CHEST = 54, + E_ITEM_REDSTONE_WIRE = 55, + E_ITEM_DIAMOND_ORE = 56, + E_ITEM_DIAMOND_BLOCK = 57, + E_ITEM_WORKBENCH = 58, + E_ITEM_CROPS = 59, + E_ITEM_SOIL = 60, + E_ITEM_FURNACE = 61, + E_ITEM_BURNING_FURNACE = 62, + E_ITEM_SIGN_POST = 63, + + E_ITEM_LADDER = 65, + E_ITEM_MINECART_TRACKS = 66, + E_ITEM_COBBLESTONE_STAIRS = 67, + E_ITEM_WALLSIGN = 68, + E_ITEM_LEVER = 69, + E_ITEM_STONE_PRESSURE_PLATE = 70, + + E_ITEM_WOODEN_PRESSURE_PLATE = 72, + E_ITEM_REDSTONE_ORE = 73, + E_ITEM_REDSTONE_ORE_GLOWING = 74, + E_ITEM_REDSTONE_TORCH_ON = 75, + E_ITEM_REDSTONE_TORCH_OFF = 76, + E_ITEM_STONE_BUTTON = 77, + E_ITEM_SNOW = 78, + E_ITEM_ICE = 79, + E_ITEM_SNOW_BLOCK = 80, + E_ITEM_CACTUS = 81, + + E_ITEM_REEDS = 83, + E_ITEM_JUKEBOX = 84, + E_ITEM_FENCE = 85, + E_ITEM_PUMPKIN = 86, + E_ITEM_BLOODSTONE = 87, + E_ITEM_SOULSAND = 88, + E_ITEM_GLOWSTONE = 89, + E_ITEM_PORT = 90, + E_ITEM_JACK_O_LANTERN = 91, + + E_ITEM_REDSTONE_REPEATER_OFF = 93, + E_ITEM_REDSTONE_REPEATER_ON = 94, + E_ITEM_LOCKED_CHEST = 95, + E_ITEM_TRAPDOOR = 96, + E_ITEM_SILVERFISH_EGG = 97, + E_ITEM_STONE_BRICKS = 98, + E_ITEM_HUGE_BROWN_MUSHROOM = 99, + E_ITEM_HUGE_RED_MUSHROOM = 100, + E_ITEM_IRON_BAR = 101, + E_ITEM_GLASS_PLANE = 102, + E_ITEM_MELON = 103, + E_ITEM_PUMPKIN_STEM = 104, + E_ITEM_MELON_STEM = 105, + E_ITEM_VINES = 106, + E_ITEM_FENCE_GATE = 107, + E_ITEM_BRICK_STAIRS = 108, + E_ITEM_STONE_BRICK_STAIRS = 109, + E_ITEM_MYCELIUM = 110, + E_ITEM_LILY_PAD = 111, + E_ITEM_NETHER_BRICK = 112, + E_ITEM_NETHER_BRICK_FENCE = 113, + E_ITEM_NETHER_BRICK_STAIRS = 114, + + E_ITEM_ENCHANTMENT_TABLE = 116, + + E_ITEM_END_PORTAL = 119, + E_ITEM_END_PORTAL_FRAME = 120, + E_ITEM_END_STONE = 121, + + E_ITEM_DOUBLE_WOODEN_SLAB = 125, + E_ITEM_WOODEN_SLAB = 126, + E_ITEM_COCA_PLANT = 127, + E_ITEM_SANDSTONE_STAIRS = 128, + E_ITEM_EMERALD_ORE = 129, + E_ITEM_ENDER_CHEST = 130, + E_ITEM_TRIPWIRE_HOOK = 131, + E_ITEM_TRIPWIRE = 132, + E_ITEM_EMERALD_BLOCK = 133, + + E_ITEM_IRON_SHOVEL = 256, + E_ITEM_IRON_PICKAXE = 257, + E_ITEM_IRON_AXE = 258, + E_ITEM_FLINT_AND_STEEL = 259, + E_ITEM_RED_APPLE = 260, + E_ITEM_APPLE = 260, // OBSOLETE, use E_ITEM_RED_APPLE instead + E_ITEM_BOW = 261, + E_ITEM_ARROW = 262, + E_ITEM_COAL = 263, + E_ITEM_DIAMOND = 264, + E_ITEM_IRON = 265, + E_ITEM_GOLD = 266, + E_ITEM_IRON_SWORD = 267, + E_ITEM_WOODEN_SWORD = 268, + E_ITEM_WOODEN_SHOVEL = 269, + E_ITEM_WOODEN_PICKAXE = 270, + E_ITEM_WOODEN_AXE = 271, + E_ITEM_STONE_SWORD = 272, + E_ITEM_STONE_SHOVEL = 273, + E_ITEM_STONE_PICKAXE = 274, + E_ITEM_STONE_AXE = 275, + E_ITEM_DIAMOND_SWORD = 276, + E_ITEM_DIAMOND_SHOVEL = 277, + E_ITEM_DIAMOND_PICKAXE = 278, + E_ITEM_DIAMOND_AXE = 279, + E_ITEM_STICK = 280, + E_ITEM_BOWL = 281, + E_ITEM_MUSHROOM_SOUP = 282, + E_ITEM_GOLD_SWORD = 283, + E_ITEM_GOLD_SHOVEL = 284, + E_ITEM_GOLD_PICKAXE = 285, + E_ITEM_GOLD_AXE = 286, + E_ITEM_STRING = 287, + E_ITEM_FEATHER = 288, + E_ITEM_GUNPOWDER = 289, + E_ITEM_WOODEN_HOE = 290, + E_ITEM_STONE_HOE = 291, + E_ITEM_IRON_HOE = 292, + E_ITEM_DIAMOND_HOE = 293, + E_ITEM_GOLD_HOE = 294, + E_ITEM_SEEDS = 295, + E_ITEM_WHEAT = 296, + E_ITEM_BREAD = 297, + E_ITEM_LEATHER_CAP = 298, + E_ITEM_LEATHER_TUNIC = 299, + E_ITEM_LEATHER_PANTS = 300, + E_ITEM_LEATHER_BOOTS = 301, + E_ITEM_CHAIN_HELMET = 302, + E_ITEM_CHAIN_CHESTPLATE = 303, + E_ITEM_CHAIN_LEGGINGS = 304, + E_ITEM_CHAIN_BOOTS = 305, + E_ITEM_IRON_HELMET = 306, + E_ITEM_IRON_CHESTPLATE = 307, + E_ITEM_IRON_LEGGINGS = 308, + E_ITEM_IRON_BOOTS = 309, + E_ITEM_DIAMOND_HELMET = 310, + E_ITEM_DIAMOND_CHESTPLATE = 311, + E_ITEM_DIAMOND_LEGGINGS = 312, + E_ITEM_DIAMOND_BOOTS = 313, + E_ITEM_GOLD_HELMET = 314, + E_ITEM_GOLD_CHESTPLATE = 315, + E_ITEM_GOLD_LEGGINGS = 316, + E_ITEM_GOLD_BOOTS = 317, + E_ITEM_FLINT = 318, + E_ITEM_RAW_MEAT = 319, + E_ITEM_COOKED_MEAT = 320, + E_ITEM_PAINTINGS = 321, + E_ITEM_GOLDEN_APPLE = 322, + E_ITEM_SIGN = 323, + E_ITEM_WOODEN_DOOR = 324, + E_ITEM_BUCKET = 325, + E_ITEM_WATER_BUCKET = 326, + E_ITEM_LAVA_BUCKET = 327, + E_ITEM_MINECART = 328, + E_ITEM_SADDLE = 329, + E_ITEM_IRON_DOOR = 330, + E_ITEM_REDSTONE_DUST = 331, + E_ITEM_SNOWBALL = 332, + E_ITEM_BOAT = 333, + E_ITEM_LEATHER = 334, + E_ITEM_MILK = 335, + E_ITEM_CLAY_BRICK = 336, + E_ITEM_CLAY = 337, + E_ITEM_SUGARCANE = 338, + E_ITEM_SUGAR_CANE = 338, + E_ITEM_PAPER = 339, + E_ITEM_BOOK = 340, + E_ITEM_SLIMEBALL = 341, + E_ITEM_CHEST_MINECART = 342, + E_ITEM_FURNACE_MINECART = 343, + E_ITEM_EGG = 344, + E_ITEM_COMPASS = 345, + E_ITEM_FISHING_ROD = 346, + E_ITEM_CLOCK = 347, + E_ITEM_GLOWSTONE_DUST = 348, + E_ITEM_RAW_FISH = 349, + E_ITEM_COOKED_FISH = 350, + E_ITEM_DYE = 351, + E_ITEM_BONE = 352, + E_ITEM_SUGAR = 353, + E_ITEM_CAKE = 354, + E_ITEM_BED = 355, + E_ITEM_REDSTONE_REPEATER = 356, + E_ITEM_COOKIE = 357, + E_ITEM_MAP = 358, + E_ITEM_SHEARS = 359, + E_ITEM_MELON_SLICE = 360, + E_ITEM_PUMPKIN_SEEDS = 361, + E_ITEM_MELON_SEEDS = 362, + E_ITEM_RAW_BEEF = 363, + E_ITEM_STEAK = 364, + E_ITEM_RAW_CHICKEN = 365, + E_ITEM_COOKED_CHICKEN = 366, + E_ITEM_ROTTEN_FLESH = 367, + E_ITEM_ENDER_PEARL = 368, + E_ITEM_BLAZE_ROD = 369, + E_ITEM_GHAST_TEAR = 370, + E_ITEM_GOLD_NUGGET = 371, + E_ITEM_NETHER_WART = 372, + E_ITEM_POTIONS = 373, + E_ITEM_GLASS_BOTTLE = 374, + E_ITEM_SPIDER_EYE = 375, + E_ITEM_FERMENTED_SPIDER_EYE = 376, + E_ITEM_BLAZE_POWDER = 377, + E_ITEM_MAGMA_CREAM = 378, + E_ITEM_BREWING_STAND = 379, + E_ITEM_CAULDRON = 380, + E_ITEM_EYE_OF_ENDER = 381, + E_ITEM_GLISTERING_MELON = 382, + + E_ITEM_SPAWN_EGG = 383, + E_ITEM_BOTTLE_O_ENCHANTING = 384, + E_ITEM_FIRE_CHARGE = 385, + E_ITEM_BOOK_AND_QUILL = 386, + E_ITEM_WRITTEN_BOOK = 387, + E_ITEM_EMERALD = 388, + + E_ITEM_13_DISC = 2256, + E_ITEM_CAT_DISC = 2257, + E_ITEM_BLOCKS_DISC = 2258, + E_ITEM_CHIRP_DISC = 2259, + E_ITEM_FAR_DISC = 2260, + E_ITEM_MALL_DISC = 2261, + E_ITEM_MELLOHI_DISC = 2262, + E_ITEM_STAL_DISC = 2263, + E_ITEM_STRAD_DISC = 2264, + E_ITEM_WARD_DISC = 2265, + E_ITEM_11_DISC = 2266, +}; + + + + + +enum +{ + // E_BLOCK_PLANKS metas: + E_META_PLANKS_APPLE = 0, + E_META_PLANKS_CONIFER = 1, + E_META_PLANKS_BIRCH = 2, + E_META_PLANKS_JUNGLE = 3, + + // E_BLOCK_LOG metas: + E_META_LOG_APPLE = 0, + E_META_LOG_CONIFER = 1, + E_META_LOG_BIRCH = 2, + E_META_LOG_JUNGLE = 3, + + // E_BLOCK_LEAVES metas: + E_META_LEAVES_APPLE = 0, + E_META_LEAVES_CONIFER = 1, + E_META_LEAVES_BIRCH = 2, + E_META_LEAVES_JUNGLE = 3, + + // E_BLOCK_SAPLING metas (lowest 3 bits): + E_META_SAPLING_APPLE = 0, + E_META_SAPLING_CONIFER = 1, + E_META_SAPLING_BIRCH = 2, + E_META_SAPLING_JUNGLE = 3, + + // E_BLOCK_TALL_GRASS metas: + E_META_TALL_GRASS_DEAD_SHRUB = 0, + E_META_TALL_GRASS_GRASS = 1, + E_META_TALL_GRASS_FERN = 2, + + // E_BLOCK_SANDSTONE metas: + E_META_SANDSTONE_NORMAL = 0, + E_META_SANDSTONE_ORNAMENT = 1, + E_META_SANDSTONE_SMOOTH = 2, + + // E_BLOCK_WOOL metas: + E_META_WOOL_WHITE = 0, + E_META_WOOL_ORANGE = 1, + E_META_WOOL_MAGENTA = 2, + E_META_WOOL_LIGHTBLUE = 3, + E_META_WOOL_YELLOW = 4, + E_META_WOOL_LIGHTGREEN = 5, + E_META_WOOL_PINK = 6, + E_META_WOOL_GRAY = 7, + E_META_WOOL_LIGHTGRAY = 8, + E_META_WOOL_CYAN = 9, + E_META_WOOL_PURPLE = 10, + E_META_WOOL_BLUE = 11, + E_META_WOOL_BROWN = 12, + E_META_WOOL_GREEN = 13, + E_META_WOOL_RED = 14, + E_META_WOOL_BLACK = 15, + + // E_BLOCK_DOUBLE_STEP metas: + E_META_DOUBLE_STEP_STONE = 0, + E_META_DOUBLE_STEP_SANDSTONE = 1, + E_META_DOUBLE_STEP_WOODEN = 2, + E_META_DOUBLE_STEP_COBBLESTONE = 3, + E_META_DOUBLE_STEP_BRICK = 4, + E_META_DOUBLE_STEP_STONE_BRICK = 5, + E_META_DOUBLE_STEP_STONE_SECRET = 6, + + // E_BLOCK_STEP metas: + E_META_STEP_STONE = 0, + E_META_STEP_SANDSTONE = 1, + E_META_STEP_PLANKS = 2, + E_META_STEP_COBBLESTONE = 3, + E_META_STEP_BRICK = 4, + E_META_STEP_STONE_BRICK = 5, + E_META_STEP_STONE_SECRET = 6, + + // E_BLOCK_SILVERFISH_EGG metas: + E_META_SILVERFISH_EGG_STONE = 0, + E_META_SILVERFISH_EGG_COBBLESTONE = 1, + E_META_SILVERFISH_EGG_STONE_BRICK = 2, + + // E_BLOCK_STONE_BRICKS metas: + E_META_STONE_BRICK_NORMAL = 0, + E_META_STONE_BRICK_MOSSY = 1, + E_META_STONE_BRICK_CRACKED = 2, + E_META_STONE_BRICK_ORNAMENT = 3, + + // E_BLOCK_WOODEN_DOUBLE_STEP metas: + E_BLOCK_WOODEN_DOUBLE_STEP_APPLE = 0, + E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER = 1, + E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH = 2, + E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE = 3, + + // E_BLOCK_WOODEN_STEP metas: + E_BLOCK_WOODEN_STEP_APPLE = 0, + E_BLOCK_WOODEN_STEP_CONIFER = 1, + E_BLOCK_WOODEN_STEP_BIRCH = 2, + E_BLOCK_WOODEN_STEP_JUNGLE = 3, +} ; + + + + + + + +enum +{ + // E_ITEM_COAL metas: + E_META_COAL_NORMAL = 0, + E_META_COAL_CHARCOAL = 1, + + // E_ITEM_GOLDEN_APPLE metas: + E_META_GOLDEN_APPLE_NORMAL = 0, + E_META_GOLDEN_APPLE_ENCHANTED = 1, + + // E_ITEM_DYE metas: + E_META_DYE_BLACK = 0, + E_META_DYE_RED = 1, + E_META_DYE_GREEN = 2, + E_META_DYE_BROWN = 3, + E_META_DYE_BLUE = 4, + E_META_DYE_PURPLE = 5, + E_META_DYE_CYAN = 6, + E_META_DYE_LIGHTGRAY = 7, + E_META_DYE_GRAY = 8, + E_META_DYE_PINK = 9, + E_META_DYE_LIGHTGREEN = 10, + E_META_DYE_YELLOW = 11, + E_META_DYE_LIGHTBLUE = 12, + E_META_DYE_MAGENTA = 13, + E_META_DYE_ORANGE = 14, + E_META_DYE_WHITE = 15, + + // E_ITEM_SPAWN_EGG spawn EntityIDs: + // hostile: + E_META_SPAWN_EGG_CREEPER = 50, + E_META_SPAWN_EGG_SKELETON = 51, + E_META_SPAWN_EGG_SPIDER = 52, + E_META_SPAWN_EGG_ZOMBIE = 54, + E_META_SPAWN_EGG_SLIME = 55, + E_META_SPAWN_EGG_GHAST = 56, + E_META_SPAWN_EGG_ZOMBIE_PIGMAN = 57, + E_META_SPAWN_EGG_ENDERMAN = 58, + E_META_SPAWN_EGG_CAVE_SPIDER = 59, + E_META_SPAWN_EGG_SILVERFISH = 60, + E_META_SPAWN_EGG_BLAZE = 61, + E_META_SPAWN_EGG_MAGMA_CUBE = 62, + E_META_SPAWN_EGG_GIANT = 53, + E_META_SPAWN_EGG_ENDER_DRAGON = 63, + E_META_SPAWN_EGG_PIG = 90, + E_META_SPAWN_EGG_SHEEP = 91, + E_META_SPAWN_EGG_COW = 92, + E_META_SPAWN_EGG_CHICKEN = 93, + E_META_SPAWN_EGG_SQUID = 94, + E_META_SPAWN_EGG_WOLF = 95, + E_META_SPAWN_EGG_MOOSHROOM = 96, + E_META_SPAWN_EGG_OCELOT = 98, + E_META_SPAWN_EGG_VILLAGER = 120, + E_META_SPAWN_EGG_SNOW_GOLEM = 97, + E_META_SPAWN_EGG_IRON_GOLEM = 99, +} ; +//tolua_end + + + + +// fwd: cItem.h: +class cItem; + + + + + +/// Translates a blocktype string into blocktype. Takes either a number or an items.ini alias as input. Returns -1 on failure. +extern int BlockStringToType(const AString & a_BlockTypeString); // tolua_export + +/// Translates an itemtype string into an item. Takes either a number, number^number, number:number or an items.ini alias as input. Returns true if successful. +extern bool StringToItem(const AString & a_ItemTypeString, cItem & a_Item); // tolua_export + +/// Translates a biome string to biome enum. Takes either a number or a biome alias (built-in). Returns -1 on failure. +extern EMCSBiome StringToBiome(const AString & a_BiomeString); + + + + + +// Block properties: +extern NIBBLETYPE g_BlockLightValue[256]; +extern NIBBLETYPE g_BlockSpreadLightFalloff[256]; +extern bool g_BlockTransparent[256]; +extern bool g_BlockOneHitDig[256]; +extern bool g_BlockPistonBreakable[256]; +extern bool g_BlockIsSnowable[256]; + + + + + diff --git a/source/ChunkDef.h b/source/ChunkDef.h index 5bafde4af..2aaaa5288 100644 --- a/source/ChunkDef.h +++ b/source/ChunkDef.h @@ -1,492 +1,492 @@ -
-// ChunkDef.h
-
-// Interfaces to helper types for chunk definitions. Most modules want to include this instead of cChunk.h
-
-
-
-
-
-#pragma once
-
-#include "Vector3i.h"
-
-
-
-
-
-/** This is really only a placeholder to be used in places where we need to "make up" a chunk's Y coord.
-It will help us when the new chunk format comes out and we need to patch everything up for compatibility.
-*/
-#define ZERO_CHUNK_Y 0
-
-// Used to smoothly convert to new axis ordering. One will be removed when deemed stable.
-#define AXIS_ORDER_YZX 1 // Original (1.1-)
-#define AXIS_ORDER_XZY 2 // New (1.2+)
-#define AXIS_ORDER AXIS_ORDER_XZY
-
-
-
-
-
-// fwd
-class cBlockEntity;
-class cEntity;
-class cClientHandle;
-class cBlockEntity;
-
-typedef std::list<cEntity *> cEntityList;
-typedef std::list<cBlockEntity *> cBlockEntityList;
-
-
-
-
-/// The datatype used by blockdata
-typedef char BLOCKTYPE;
-
-/// The datatype used by nibbledata (meta, light, skylight)
-typedef unsigned char NIBBLETYPE;
-
-/// The type used by the heightmap
-typedef unsigned char HEIGHTTYPE;
-
-
-
-
-
-/** Biome IDs
-The first batch corresponds to the clientside biomes, used by MineCraft.
-BiomeIDs over 255 are used by MCServer internally and are translated to MC biomes before sending them to client
-*/
-enum EMCSBiome
-{
- biOcean = 0,
- biPlains = 1,
- biDesert = 2,
- biExtremeHills = 3,
- biForest = 4,
- biTaiga = 5,
- biSwampland = 6,
- biRiver = 7,
- biHell = 8, // same as Nether
- biNether = 8,
- biSky = 9,
- biFrozenOcean = 10,
- biFrozenRiver = 11,
- biIcePlains = 12,
- biTundra = 12, // same as Ice Plains
- biIceMountains = 13,
- biMushroomIsland = 14,
- biMushroomShore = 15,
- biBeach = 16,
- biDesertHills = 17,
- biForestHills = 18,
- biTaigaHills = 19,
- biExtremeHillsEdge = 20,
- biJungle = 21,
- biJungleHills = 22,
-
- // Automatically capture the maximum biome value into biMaxBiome:
- biNumBiomes, // True number of biomes, since they are zero-based
- biMaxBiome = biNumBiomes - 1, // The maximum biome value
-} ;
-
-
-
-
-
-/// Constants used throughout the code, useful typedefs and utility functions
-class cChunkDef
-{
-public:
- static const int Width = 16;
- static const int Height = 256;
- static const int NumBlocks = Width * Height * Width;
- static const int BlockDataSize = NumBlocks * 2 + (NumBlocks / 2); // 2.5 * numblocks
-
- // Offsets to individual components in the joined blockdata array
- static const int MetaOffset = NumBlocks;
- static const int LightOffset = MetaOffset + NumBlocks / 2;
- static const int SkyLightOffset = LightOffset + NumBlocks / 2;
-
- static const unsigned int INDEX_OUT_OF_RANGE = 0xffffffff;
-
- /// The type used for any heightmap operations and storage; idx = x + Width * z
- typedef HEIGHTTYPE HeightMap[Width * Width];
-
- /** The type used for any biomemap operations and storage inside MCServer,
- using MCServer biomes (need not correspond to client representation!)
- idx = x + Width * z // Need to verify this with the protocol spec, currently unknown!
- */
- typedef EMCSBiome BiomeMap[Width * Width];
-
- /// The type used for block type operations and storage, AXIS_ORDER ordering
- typedef BLOCKTYPE BlockTypes[NumBlocks];
-
- /// The type used for block data in nibble format, AXIS_ORDER ordering
- typedef NIBBLETYPE BlockNibbles[NumBlocks / 2];
-
-
- /// Converts absolute block coords into relative (chunk + block) coords:
- inline static void AbsoluteToRelative(/* in-out */ int & a_X, int & a_Y, int & a_Z, /* out */ int & a_ChunkX, int & a_ChunkZ )
- {
- BlockToChunk(a_X, a_Y, a_Z, a_ChunkX, a_ChunkZ);
-
- a_X = a_X - a_ChunkX * Width;
- a_Z = a_Z - a_ChunkZ * Width;
- }
-
-
- /// Converts absolute block coords to chunk coords:
- inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkZ )
- {
- (void)a_Y;
- a_ChunkX = a_X / Width;
- if ((a_X < 0) && (a_X % Width != 0))
- {
- a_ChunkX--;
- }
- a_ChunkZ = a_Z / cChunkDef::Width;
- if ((a_Z < 0) && (a_Z % Width != 0))
- {
- a_ChunkZ--;
- }
- }
-
-
- inline static unsigned int MakeIndex(int x, int y, int z )
- {
- if( x < cChunkDef::Width && x > -1 && y < cChunkDef::Height && y > -1 && z < cChunkDef::Width && z > -1 )
- {
- return MakeIndexNoCheck(x, y, z);
- }
- return INDEX_OUT_OF_RANGE;
- }
-
-
- inline static unsigned int MakeIndexNoCheck(int x, int y, int z)
- {
- #if AXIS_ORDER == AXIS_ORDER_XZY
- // For some reason, NOT using the Horner schema is faster. Weird.
- return x + (z * cChunkDef::Width) + (y * cChunkDef::Width * cChunkDef::Width); // 1.2 is XZY
- #elif AXIS_ORDER == AXIS_ORDER_YZX
- return y + (z * cChunkDef::Width) + (x * cChunkDef::Height * cChunkDef::Width); // 1.1 is YZX
- #endif
- }
-
-
- inline static Vector3i IndexToCoordinate( unsigned int index )
- {
- #if AXIS_ORDER == AXIS_ORDER_XZY
- return Vector3i( // 1.2
- index % cChunkDef::Width, // X
- index / (cChunkDef::Width * cChunkDef::Width), // Y
- (index / cChunkDef::Width) % cChunkDef::Width // Z
- );
- #elif AXIS_ORDER == AXIS_ORDER_YZX
- return Vector3i( // 1.1
- index / (cChunkDef::Height * cChunkDef::Width), // X
- index % cChunkDef::Height, // Y
- (index / cChunkDef::Height) % cChunkDef::Width // Z
- );
- #endif
- }
-
-
- inline static void SetBlock(BLOCKTYPE * a_BlockTypes, int a_X, int a_Y, int a_Z, BLOCKTYPE a_Type)
- {
- ASSERT((a_X >= 0) && (a_X < Width));
- ASSERT((a_Y >= 0) && (a_Y < Height));
- ASSERT((a_Z >= 0) && (a_Z < Width));
- a_BlockTypes[MakeIndexNoCheck(a_X, a_Y, a_Z)] = a_Type;
- }
-
-
- inline static BLOCKTYPE GetBlock(BLOCKTYPE * a_BlockTypes, int a_X, int a_Y, int a_Z)
- {
- ASSERT((a_X >= 0) && (a_X < Width));
- ASSERT((a_Y >= 0) && (a_Y < Height));
- ASSERT((a_Z >= 0) && (a_Z < Width));
- return a_BlockTypes[MakeIndexNoCheck(a_X, a_Y, a_Z)];
- }
-
-
- inline static int GetHeight(const HeightMap & a_HeightMap, int a_X, int a_Z)
- {
- return a_HeightMap[a_X + Width * a_Z];
- }
-
-
- inline static void SetHeight(HeightMap & a_HeightMap, int a_X, int a_Z, unsigned char a_Height)
- {
- a_HeightMap[a_X + Width * a_Z] = a_Height;
- }
-
-
- inline static EMCSBiome GetBiome(const BiomeMap & a_BiomeMap, int a_X, int a_Z)
- {
- return a_BiomeMap[a_X + Width * a_Z];
- }
-
-
- inline static void SetBiome(BiomeMap & a_BiomeMap, int a_X, int a_Z, EMCSBiome a_Biome)
- {
- a_BiomeMap[a_X + Width * a_Z] = a_Biome;
- }
-
-
- static NIBBLETYPE GetNibble(NIBBLETYPE * a_Buffer, int a_BlockIdx)
- {
- if ((a_BlockIdx > -1) && (a_BlockIdx < cChunkDef::NumBlocks))
- {
- return (a_Buffer[a_BlockIdx / 2] >> ((a_BlockIdx & 1) * 4)) & 0x0f;
- }
- return 0;
- }
-
-
- static NIBBLETYPE GetNibble(NIBBLETYPE * a_Buffer, int x, int y, int z)
- {
- if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1))
- {
- int Index = MakeIndexNoCheck(x, y, z);
- return (a_Buffer[Index / 2] >> ((Index & 1) * 4)) & 0x0f;
- }
- return 0;
- }
-
-
- static void SetNibble(NIBBLETYPE * a_Buffer, int a_BlockIdx, NIBBLETYPE a_Nibble)
- {
- if ((a_BlockIdx > -1) && (a_BlockIdx < cChunkDef::NumBlocks))
- {
- a_Buffer[a_BlockIdx / 2] = (
- (a_Buffer[a_BlockIdx / 2] & (0xf0 >> ((a_BlockIdx & 1) * 4))) | // The untouched nibble
- ((a_Nibble & 0x0f) << ((a_BlockIdx & 1) * 4)) // The nibble being set
- );
- }
- }
-
-
- static void SetNibble(NIBBLETYPE * a_Buffer, int x, int y, int z, NIBBLETYPE a_Nibble)
- {
- if ((x < cChunkDef::Width) && (x > -1) && (y < cChunkDef::Height) && (y > -1) && (z < cChunkDef::Width) && (z > -1))
- {
- int Index = MakeIndexNoCheck(x, y, z);
- a_Buffer[Index / 2] = (
- (a_Buffer[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble
- ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set
- );
- }
- }
-
-
- inline static char GetNibble(NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos )
- {
- return GetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z );
- }
-
-
- inline static void SetNibble(NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos, char a_Value )
- {
- SetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_Value );
- }
-
-} ;
-
-
-
-
-
-/** Interface class used for getting data out of a chunk using the GetAllData() function.
-Implementation must use the pointers immediately and NOT store any of them for later use
-The virtual methods are called in the same order as they're declared here.
-*/
-class cChunkDataCallback abstract
-{
-public:
- /// Called once to provide heightmap data
- virtual void HeightMap(const cChunkDef::HeightMap * a_HeightMap) {};
-
- /// Called once to provide biome data
- virtual void BiomeData (const cChunkDef::BiomeMap * a_BiomeMap) {};
-
- /// Called once to export block types
- virtual void BlockTypes (const BLOCKTYPE * a_Type) {};
-
- /// Called once to export block meta
- virtual void BlockMeta (const NIBBLETYPE * a_Meta) {};
-
- /// Called once to let know if the chunk lighting is valid. Return value is used to control if BlockLight() and BlockSkyLight() are called next
- virtual bool LightIsValid(bool a_IsLightValid) {return true; };
-
- /// Called once to export block light
- virtual void BlockLight (const NIBBLETYPE * a_Meta) {};
-
- /// Called once to export sky light
- virtual void BlockSkyLight(const NIBBLETYPE * a_Meta) {};
-
- /// Called for each entity in the chunk
- virtual void Entity(cEntity * a_Entity) {};
-
- /// Called for each blockentity in the chunk
- virtual void BlockEntity(cBlockEntity * a_Entity) {};
-} ;
-
-
-
-
-
-/** A simple implementation of the cChunkDataCallback interface that collects all block data into a single buffer
-*/
-class cChunkDataCollector :
- public cChunkDataCallback
-{
-public:
-
- // Must be char instead of BLOCKTYPE or NIBBLETYPE, because it houses both.
- char m_BlockData[cChunkDef::BlockDataSize];
-
-protected:
-
- virtual void BlockTypes(const BLOCKTYPE * a_BlockTypes) override
- {
- memcpy(m_BlockData, a_BlockTypes, sizeof(cChunkDef::BlockTypes));
- }
-
-
- virtual void BlockMeta(const NIBBLETYPE * a_BlockMeta) override
- {
- memcpy(m_BlockData + cChunkDef::NumBlocks, a_BlockMeta, cChunkDef::NumBlocks / 2);
- }
-
-
- virtual void BlockLight(const NIBBLETYPE * a_BlockLight) override
- {
- memcpy(m_BlockData + 3 * cChunkDef::NumBlocks / 2, a_BlockLight, cChunkDef::NumBlocks / 2);
- }
-
-
- virtual void BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) override
- {
- memcpy(m_BlockData + 2 * cChunkDef::NumBlocks, a_BlockSkyLight, cChunkDef::NumBlocks / 2);
- }
-} ;
-
-
-
-
-
-/** A simple implementation of the cChunkDataCallback interface that collects all block data into a separate buffers
-*/
-class cChunkDataSeparateCollector :
- public cChunkDataCallback
-{
-public:
-
- cChunkDef::BlockTypes m_BlockTypes;
- cChunkDef::BlockNibbles m_BlockMetas;
- cChunkDef::BlockNibbles m_BlockLight;
- cChunkDef::BlockNibbles m_BlockSkyLight;
-
-protected:
-
- virtual void BlockTypes(const BLOCKTYPE * a_BlockTypes) override
- {
- memcpy(m_BlockTypes, a_BlockTypes, sizeof(m_BlockTypes));
- }
-
-
- virtual void BlockMeta(const NIBBLETYPE * a_BlockMeta) override
- {
- memcpy(m_BlockMetas, a_BlockMeta, sizeof(m_BlockMetas));
- }
-
-
- virtual void BlockLight(const NIBBLETYPE * a_BlockLight) override
- {
- memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight));
- }
-
-
- virtual void BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) override
- {
- memcpy(m_BlockSkyLight, a_BlockSkyLight, sizeof(m_BlockSkyLight));
- }
-} ;
-
-
-
-
-
-/** Interface class used for comparing clients of two chunks.
-Used primarily for entity moving while both chunks are locked.
-*/
-class cClientDiffCallback
-{
-public:
- /// Called for clients that are in Chunk1 and not in Chunk2,
- virtual void Removed(cClientHandle * a_Client) = 0;
-
- /// Called for clients that are in Chunk2 and not in Chunk1.
- virtual void Added(cClientHandle * a_Client) = 0;
-} ;
-
-
-
-
-
-struct sSetBlock
-{
- int x, y, z;
- int ChunkX, ChunkZ;
- BLOCKTYPE BlockType;
- NIBBLETYPE BlockMeta;
-
- sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ); // absolute block position
- sSetBlock(int a_ChunkX, int a_ChunkZ, int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) :
- ChunkX(a_ChunkX), ChunkZ(a_ChunkZ),
- x(a_X), y(a_Y), z(a_Z),
- BlockType(a_BlockType),
- BlockMeta(a_BlockMeta)
- {}
-};
-
-typedef std::list<sSetBlock> sSetBlockList;
-typedef std::vector<sSetBlock> sSetBlockVector;
-
-
-
-
-
-class cChunkCoords
-{
-public:
- int m_ChunkX;
- int m_ChunkY;
- int m_ChunkZ;
-
- cChunkCoords(int a_ChunkX, int a_ChunkY, int a_ChunkZ) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ) {}
-
- bool operator == (const cChunkCoords & a_Other) const
- {
- return ((m_ChunkX == a_Other.m_ChunkX) && (m_ChunkY == a_Other.m_ChunkY) && (m_ChunkZ == a_Other.m_ChunkZ));
- }
-} ;
-
-typedef std::list<cChunkCoords> cChunkCoordsList;
-
-
-
-
-
-/// Interface class used as a callback for operations that involve chunk coords
-class cChunkCoordCallback
-{
-public:
- virtual void Call(int a_ChunkX, int a_ChunkZ) = 0;
-} ;
-
-
-
-
+ +// ChunkDef.h + +// Interfaces to helper types for chunk definitions. Most modules want to include this instead of cChunk.h + + + + + +#pragma once + +#include "Vector3i.h" + + + + + +/** This is really only a placeholder to be used in places where we need to "make up" a chunk's Y coord. +It will help us when the new chunk format comes out and we need to patch everything up for compatibility. +*/ +#define ZERO_CHUNK_Y 0 + +// Used to smoothly convert to new axis ordering. One will be removed when deemed stable. +#define AXIS_ORDER_YZX 1 // Original (1.1-) +#define AXIS_ORDER_XZY 2 // New (1.2+) +#define AXIS_ORDER AXIS_ORDER_XZY + + + + + +// fwd +class cBlockEntity; +class cEntity; +class cClientHandle; +class cBlockEntity; + +typedef std::list<cEntity *> cEntityList; +typedef std::list<cBlockEntity *> cBlockEntityList; + + + + +/// The datatype used by blockdata +typedef char BLOCKTYPE; + +/// The datatype used by nibbledata (meta, light, skylight) +typedef unsigned char NIBBLETYPE; + +/// The type used by the heightmap +typedef unsigned char HEIGHTTYPE; + + + + + +/** Biome IDs +The first batch corresponds to the clientside biomes, used by MineCraft. +BiomeIDs over 255 are used by MCServer internally and are translated to MC biomes before sending them to client +*/ +enum EMCSBiome +{ + biOcean = 0, + biPlains = 1, + biDesert = 2, + biExtremeHills = 3, + biForest = 4, + biTaiga = 5, + biSwampland = 6, + biRiver = 7, + biHell = 8, // same as Nether + biNether = 8, + biSky = 9, + biFrozenOcean = 10, + biFrozenRiver = 11, + biIcePlains = 12, + biTundra = 12, // same as Ice Plains + biIceMountains = 13, + biMushroomIsland = 14, + biMushroomShore = 15, + biBeach = 16, + biDesertHills = 17, + biForestHills = 18, + biTaigaHills = 19, + biExtremeHillsEdge = 20, + biJungle = 21, + biJungleHills = 22, + + // Automatically capture the maximum biome value into biMaxBiome: + biNumBiomes, // True number of biomes, since they are zero-based + biMaxBiome = biNumBiomes - 1, // The maximum biome value +} ; + + + + + +/// Constants used throughout the code, useful typedefs and utility functions +class cChunkDef +{ +public: + static const int Width = 16; + static const int Height = 256; + static const int NumBlocks = Width * Height * Width; + static const int BlockDataSize = NumBlocks * 2 + (NumBlocks / 2); // 2.5 * numblocks + + // Offsets to individual components in the joined blockdata array + static const int MetaOffset = NumBlocks; + static const int LightOffset = MetaOffset + NumBlocks / 2; + static const int SkyLightOffset = LightOffset + NumBlocks / 2; + + static const unsigned int INDEX_OUT_OF_RANGE = 0xffffffff; + + /// The type used for any heightmap operations and storage; idx = x + Width * z + typedef HEIGHTTYPE HeightMap[Width * Width]; + + /** The type used for any biomemap operations and storage inside MCServer, + using MCServer biomes (need not correspond to client representation!) + idx = x + Width * z // Need to verify this with the protocol spec, currently unknown! + */ + typedef EMCSBiome BiomeMap[Width * Width]; + + /// The type used for block type operations and storage, AXIS_ORDER ordering + typedef BLOCKTYPE BlockTypes[NumBlocks]; + + /// The type used for block data in nibble format, AXIS_ORDER ordering + typedef NIBBLETYPE BlockNibbles[NumBlocks / 2]; + + + /// Converts absolute block coords into relative (chunk + block) coords: + inline static void AbsoluteToRelative(/* in-out */ int & a_X, int & a_Y, int & a_Z, /* out */ int & a_ChunkX, int & a_ChunkZ ) + { + BlockToChunk(a_X, a_Y, a_Z, a_ChunkX, a_ChunkZ); + + a_X = a_X - a_ChunkX * Width; + a_Z = a_Z - a_ChunkZ * Width; + } + + + /// Converts absolute block coords to chunk coords: + inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkZ ) + { + (void)a_Y; + a_ChunkX = a_X / Width; + if ((a_X < 0) && (a_X % Width != 0)) + { + a_ChunkX--; + } + a_ChunkZ = a_Z / cChunkDef::Width; + if ((a_Z < 0) && (a_Z % Width != 0)) + { + a_ChunkZ--; + } + } + + + inline static unsigned int MakeIndex(int x, int y, int z ) + { + if( x < cChunkDef::Width && x > -1 && y < cChunkDef::Height && y > -1 && z < cChunkDef::Width && z > -1 ) + { + return MakeIndexNoCheck(x, y, z); + } + return INDEX_OUT_OF_RANGE; + } + + + inline static unsigned int MakeIndexNoCheck(int x, int y, int z) + { + #if AXIS_ORDER == AXIS_ORDER_XZY + // For some reason, NOT using the Horner schema is faster. Weird. + return x + (z * cChunkDef::Width) + (y * cChunkDef::Width * cChunkDef::Width); // 1.2 is XZY + #elif AXIS_ORDER == AXIS_ORDER_YZX + return y + (z * cChunkDef::Width) + (x * cChunkDef::Height * cChunkDef::Width); // 1.1 is YZX + #endif + } + + + inline static Vector3i IndexToCoordinate( unsigned int index ) + { + #if AXIS_ORDER == AXIS_ORDER_XZY + return Vector3i( // 1.2 + index % cChunkDef::Width, // X + index / (cChunkDef::Width * cChunkDef::Width), // Y + (index / cChunkDef::Width) % cChunkDef::Width // Z + ); + #elif AXIS_ORDER == AXIS_ORDER_YZX + return Vector3i( // 1.1 + index / (cChunkDef::Height * cChunkDef::Width), // X + index % cChunkDef::Height, // Y + (index / cChunkDef::Height) % cChunkDef::Width // Z + ); + #endif + } + + + inline static void SetBlock(BLOCKTYPE * a_BlockTypes, int a_X, int a_Y, int a_Z, BLOCKTYPE a_Type) + { + ASSERT((a_X >= 0) && (a_X < Width)); + ASSERT((a_Y >= 0) && (a_Y < Height)); + ASSERT((a_Z >= 0) && (a_Z < Width)); + a_BlockTypes[MakeIndexNoCheck(a_X, a_Y, a_Z)] = a_Type; + } + + + inline static BLOCKTYPE GetBlock(BLOCKTYPE * a_BlockTypes, int a_X, int a_Y, int a_Z) + { + ASSERT((a_X >= 0) && (a_X < Width)); + ASSERT((a_Y >= 0) && (a_Y < Height)); + ASSERT((a_Z >= 0) && (a_Z < Width)); + return a_BlockTypes[MakeIndexNoCheck(a_X, a_Y, a_Z)]; + } + + + inline static int GetHeight(const HeightMap & a_HeightMap, int a_X, int a_Z) + { + return a_HeightMap[a_X + Width * a_Z]; + } + + + inline static void SetHeight(HeightMap & a_HeightMap, int a_X, int a_Z, unsigned char a_Height) + { + a_HeightMap[a_X + Width * a_Z] = a_Height; + } + + + inline static EMCSBiome GetBiome(const BiomeMap & a_BiomeMap, int a_X, int a_Z) + { + return a_BiomeMap[a_X + Width * a_Z]; + } + + + inline static void SetBiome(BiomeMap & a_BiomeMap, int a_X, int a_Z, EMCSBiome a_Biome) + { + a_BiomeMap[a_X + Width * a_Z] = a_Biome; + } + + + static NIBBLETYPE GetNibble(NIBBLETYPE * a_Buffer, int a_BlockIdx) + { + if ((a_BlockIdx > -1) && (a_BlockIdx < cChunkDef::NumBlocks)) + { + return (a_Buffer[a_BlockIdx / 2] >> ((a_BlockIdx & 1) * 4)) & 0x0f; + } + return 0; + } + + + static NIBBLETYPE GetNibble(NIBBLETYPE * a_Buffer, int x, int y, int z) + { + if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1)) + { + int Index = MakeIndexNoCheck(x, y, z); + return (a_Buffer[Index / 2] >> ((Index & 1) * 4)) & 0x0f; + } + return 0; + } + + + static void SetNibble(NIBBLETYPE * a_Buffer, int a_BlockIdx, NIBBLETYPE a_Nibble) + { + if ((a_BlockIdx > -1) && (a_BlockIdx < cChunkDef::NumBlocks)) + { + a_Buffer[a_BlockIdx / 2] = ( + (a_Buffer[a_BlockIdx / 2] & (0xf0 >> ((a_BlockIdx & 1) * 4))) | // The untouched nibble + ((a_Nibble & 0x0f) << ((a_BlockIdx & 1) * 4)) // The nibble being set + ); + } + } + + + static void SetNibble(NIBBLETYPE * a_Buffer, int x, int y, int z, NIBBLETYPE a_Nibble) + { + if ((x < cChunkDef::Width) && (x > -1) && (y < cChunkDef::Height) && (y > -1) && (z < cChunkDef::Width) && (z > -1)) + { + int Index = MakeIndexNoCheck(x, y, z); + a_Buffer[Index / 2] = ( + (a_Buffer[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble + ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set + ); + } + } + + + inline static char GetNibble(NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos ) + { + return GetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); + } + + + inline static void SetNibble(NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos, char a_Value ) + { + SetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_Value ); + } + +} ; + + + + + +/** Interface class used for getting data out of a chunk using the GetAllData() function. +Implementation must use the pointers immediately and NOT store any of them for later use +The virtual methods are called in the same order as they're declared here. +*/ +class cChunkDataCallback abstract +{ +public: + /// Called once to provide heightmap data + virtual void HeightMap(const cChunkDef::HeightMap * a_HeightMap) {}; + + /// Called once to provide biome data + virtual void BiomeData (const cChunkDef::BiomeMap * a_BiomeMap) {}; + + /// Called once to export block types + virtual void BlockTypes (const BLOCKTYPE * a_Type) {}; + + /// Called once to export block meta + virtual void BlockMeta (const NIBBLETYPE * a_Meta) {}; + + /// Called once to let know if the chunk lighting is valid. Return value is used to control if BlockLight() and BlockSkyLight() are called next + virtual bool LightIsValid(bool a_IsLightValid) {return true; }; + + /// Called once to export block light + virtual void BlockLight (const NIBBLETYPE * a_Meta) {}; + + /// Called once to export sky light + virtual void BlockSkyLight(const NIBBLETYPE * a_Meta) {}; + + /// Called for each entity in the chunk + virtual void Entity(cEntity * a_Entity) {}; + + /// Called for each blockentity in the chunk + virtual void BlockEntity(cBlockEntity * a_Entity) {}; +} ; + + + + + +/** A simple implementation of the cChunkDataCallback interface that collects all block data into a single buffer +*/ +class cChunkDataCollector : + public cChunkDataCallback +{ +public: + + // Must be char instead of BLOCKTYPE or NIBBLETYPE, because it houses both. + char m_BlockData[cChunkDef::BlockDataSize]; + +protected: + + virtual void BlockTypes(const BLOCKTYPE * a_BlockTypes) override + { + memcpy(m_BlockData, a_BlockTypes, sizeof(cChunkDef::BlockTypes)); + } + + + virtual void BlockMeta(const NIBBLETYPE * a_BlockMeta) override + { + memcpy(m_BlockData + cChunkDef::NumBlocks, a_BlockMeta, cChunkDef::NumBlocks / 2); + } + + + virtual void BlockLight(const NIBBLETYPE * a_BlockLight) override + { + memcpy(m_BlockData + 3 * cChunkDef::NumBlocks / 2, a_BlockLight, cChunkDef::NumBlocks / 2); + } + + + virtual void BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) override + { + memcpy(m_BlockData + 2 * cChunkDef::NumBlocks, a_BlockSkyLight, cChunkDef::NumBlocks / 2); + } +} ; + + + + + +/** A simple implementation of the cChunkDataCallback interface that collects all block data into a separate buffers +*/ +class cChunkDataSeparateCollector : + public cChunkDataCallback +{ +public: + + cChunkDef::BlockTypes m_BlockTypes; + cChunkDef::BlockNibbles m_BlockMetas; + cChunkDef::BlockNibbles m_BlockLight; + cChunkDef::BlockNibbles m_BlockSkyLight; + +protected: + + virtual void BlockTypes(const BLOCKTYPE * a_BlockTypes) override + { + memcpy(m_BlockTypes, a_BlockTypes, sizeof(m_BlockTypes)); + } + + + virtual void BlockMeta(const NIBBLETYPE * a_BlockMeta) override + { + memcpy(m_BlockMetas, a_BlockMeta, sizeof(m_BlockMetas)); + } + + + virtual void BlockLight(const NIBBLETYPE * a_BlockLight) override + { + memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight)); + } + + + virtual void BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) override + { + memcpy(m_BlockSkyLight, a_BlockSkyLight, sizeof(m_BlockSkyLight)); + } +} ; + + + + + +/** Interface class used for comparing clients of two chunks. +Used primarily for entity moving while both chunks are locked. +*/ +class cClientDiffCallback +{ +public: + /// Called for clients that are in Chunk1 and not in Chunk2, + virtual void Removed(cClientHandle * a_Client) = 0; + + /// Called for clients that are in Chunk2 and not in Chunk1. + virtual void Added(cClientHandle * a_Client) = 0; +} ; + + + + + +struct sSetBlock +{ + int x, y, z; + int ChunkX, ChunkZ; + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + + sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ); // absolute block position + sSetBlock(int a_ChunkX, int a_ChunkZ, int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) : + ChunkX(a_ChunkX), ChunkZ(a_ChunkZ), + x(a_X), y(a_Y), z(a_Z), + BlockType(a_BlockType), + BlockMeta(a_BlockMeta) + {} +}; + +typedef std::list<sSetBlock> sSetBlockList; +typedef std::vector<sSetBlock> sSetBlockVector; + + + + + +class cChunkCoords +{ +public: + int m_ChunkX; + int m_ChunkY; + int m_ChunkZ; + + cChunkCoords(int a_ChunkX, int a_ChunkY, int a_ChunkZ) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ) {} + + bool operator == (const cChunkCoords & a_Other) const + { + return ((m_ChunkX == a_Other.m_ChunkX) && (m_ChunkY == a_Other.m_ChunkY) && (m_ChunkZ == a_Other.m_ChunkZ)); + } +} ; + +typedef std::list<cChunkCoords> cChunkCoordsList; + + + + + +/// Interface class used as a callback for operations that involve chunk coords +class cChunkCoordCallback +{ +public: + virtual void Call(int a_ChunkX, int a_ChunkZ) = 0; +} ; + + + + diff --git a/source/ChunkSender.cpp b/source/ChunkSender.cpp index 8c65eece6..1f16a6b72 100644 --- a/source/ChunkSender.cpp +++ b/source/ChunkSender.cpp @@ -1,300 +1,300 @@ -
-// ChunkSender.cpp
-
-// Interfaces to the cChunkSender class representing the thread that waits for chunks becoming ready (loaded / generated) and sends them to clients
-
-
-
-
-
-#include "Globals.h"
-#include "ChunkSender.h"
-#include "cWorld.h"
-#include "packets/cPacket_MapChunk.h"
-#include "packets/cPacket_PreChunk.h"
-#include "cBlockEntity.h"
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cNotifyChunkSender:
-
-void cNotifyChunkSender::Call(int a_ChunkX, int a_ChunkZ)
-{
- m_ChunkSender->ChunkReady(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cChunkSender:
-
-cChunkSender::cChunkSender(void) :
- super("ChunkSender"),
- m_World(NULL),
- m_Notify(NULL)
-{
- m_Notify.SetChunkSender(this);
-}
-
-
-
-
-
-cChunkSender::~cChunkSender()
-{
- Stop();
-}
-
-
-
-
-
-bool cChunkSender::Start(cWorld * a_World)
-{
- m_World = a_World;
- return super::Start();
-}
-
-
-
-
-
-void cChunkSender::Stop(void)
-{
- m_ShouldTerminate = true;
- m_evtQueue.Set();
- Wait();
-}
-
-
-
-
-
-void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- // This is probably never gonna be called twice for the same chunk, and if it is, we don't mind, so we don't check
- {
- cCSLock Lock(m_CS);
- m_ChunksReady.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
- }
- m_evtQueue.Set();
-}
-
-
-
-
-
-void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
-{
- ASSERT(a_Client != NULL);
- {
- cCSLock Lock(m_CS);
- if (std::find(m_SendChunks.begin(), m_SendChunks.end(), sSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client)) != m_SendChunks.end())
- {
- // Already queued, bail out
- return;
- }
- m_SendChunks.push_back(sSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client));
- }
- m_evtQueue.Set();
-}
-
-
-
-
-
-void cChunkSender::RemoveClient(cClientHandle * a_Client)
-{
- {
- cCSLock Lock(m_CS);
- for (sSendChunkList::iterator itr = m_SendChunks.begin(); itr != m_SendChunks.end();)
- {
- if (itr->m_Client == a_Client)
- {
- itr = m_SendChunks.erase(itr);
- continue;
- }
- ++itr;
- } // for itr - m_SendChunks[]
- m_RemoveCount++;
- }
- m_evtQueue.Set();
- m_evtRemoved.Wait(); // Wait for removal confirmation
-}
-
-
-
-
-
-void cChunkSender::Execute(void)
-{
- while (!m_ShouldTerminate)
- {
- cCSLock Lock(m_CS);
- while (m_ChunksReady.empty() && m_SendChunks.empty())
- {
- int RemoveCount = m_RemoveCount;
- m_RemoveCount = 0;
- cCSUnlock Unlock(Lock);
- for (int i = 0; i < RemoveCount; i++)
- {
- m_evtRemoved.Set(); // Notify that the removed clients are safe to be deleted
- }
- m_evtQueue.Wait();
- if (m_ShouldTerminate)
- {
- return;
- }
- } // while (empty)
-
- if (!m_ChunksReady.empty())
- {
- // Take one from the queue:
- cChunkCoords Coords(m_ChunksReady.front());
- m_ChunksReady.pop_front();
- Lock.Unlock();
-
- SendChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, NULL);
- }
- else
- {
- // Take one from the queue:
- sSendChunk Chunk(m_SendChunks.front());
- m_SendChunks.pop_front();
- Lock.Unlock();
-
- SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkY, Chunk.m_ChunkZ, Chunk.m_Client);
- }
- Lock.Lock();
- int RemoveCount = m_RemoveCount;
- m_RemoveCount = 0;
- Lock.Unlock();
- for (int i = 0; i < RemoveCount; i++)
- {
- m_evtRemoved.Set(); // Notify that the removed clients are safe to be deleted
- }
- } // while (!mShouldTerminate)
-}
-
-
-
-
-
-void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
-{
- ASSERT(m_World != NULL);
-
- // Ask the client if it still wants the chunk:
- if (a_Client != NULL)
- {
- if (!a_Client->WantsSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ))
- {
- return;
- }
- }
-
- // If the chunk has no clients, no need to packetize it:
- if (!m_World->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ))
- {
- return;
- }
-
- // If the chunk is not valid, do nothing - whoever needs it has queued it for loading / generating
- if (!m_World->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ))
- {
- return;
- }
-
- // If the chunk is not lighted, queue it for relighting and get notified when it's ready:
- if (!m_World->IsChunkLighted(a_ChunkX, a_ChunkZ))
- {
- m_World->QueueLightChunk(a_ChunkX, a_ChunkZ, &m_Notify);
- return;
- }
-
- // Prepare MapChunk packets:
- if( !m_World->GetChunkData(a_ChunkX, a_ChunkY, a_ChunkZ, *this) )
- {
- return;
- }
- cPacket_PreChunk PreChunk(a_ChunkX, a_ChunkZ, true);
- cPacket_MapChunk MapChunk(a_ChunkX, a_ChunkY, a_ChunkZ, m_BlockData, m_BiomeMap);
-
- // Send:
- if (a_Client == NULL)
- {
- m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, PreChunk);
- m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, MapChunk);
- }
- else
- {
- a_Client->Send(PreChunk);
- a_Client->Send(MapChunk);
- }
-
- // Send entity creation packets:
- for (PacketList::iterator itr = m_Packets.begin(); itr != m_Packets.end(); ++itr)
- {
- if (a_Client == NULL)
- {
- m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, **itr);
- }
- else
- {
- a_Client->Send(**itr);
- }
- delete *itr;
- } // for itr - m_Packets[]
- m_Packets.clear();
-}
-
-
-
-
-
-void cChunkSender::BlockEntity(cBlockEntity * a_Entity)
-{
- cPacket * Packet = a_Entity->GetPacket();
- if (Packet != NULL)
- {
- m_Packets.push_back(Packet);
- }
-}
-
-
-
-
-void cChunkSender::Entity(cEntity * a_Entity)
-{
- // Nothing needed yet, perhaps in the future when we save entities into chunks we'd like to send them upon load, too ;)
-}
-
-
-
-
-
-void cChunkSender::BiomeData(const cChunkDef::BiomeMap * a_BiomeMap)
-{
- for (int i = 0; i < ARRAYCOUNT(m_BiomeMap); i++)
- {
- if ((*a_BiomeMap)[i] < 255)
- {
- // Normal MC biome, copy as-is:
- m_BiomeMap[i] = (unsigned char)((*a_BiomeMap)[i]);
- }
- else
- {
- // TODO: MCS-specific biome, need to map to some basic MC biome:
- ASSERT(!"Unimplemented MCS-specific biome");
- }
- } // for i - m_BiomeMap[]
-}
-
-
-
-
+ +// ChunkSender.cpp + +// Interfaces to the cChunkSender class representing the thread that waits for chunks becoming ready (loaded / generated) and sends them to clients + + + + + +#include "Globals.h" +#include "ChunkSender.h" +#include "cWorld.h" +#include "packets/cPacket_MapChunk.h" +#include "packets/cPacket_PreChunk.h" +#include "cBlockEntity.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cNotifyChunkSender: + +void cNotifyChunkSender::Call(int a_ChunkX, int a_ChunkZ) +{ + m_ChunkSender->ChunkReady(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cChunkSender: + +cChunkSender::cChunkSender(void) : + super("ChunkSender"), + m_World(NULL), + m_Notify(NULL) +{ + m_Notify.SetChunkSender(this); +} + + + + + +cChunkSender::~cChunkSender() +{ + Stop(); +} + + + + + +bool cChunkSender::Start(cWorld * a_World) +{ + m_World = a_World; + return super::Start(); +} + + + + + +void cChunkSender::Stop(void) +{ + m_ShouldTerminate = true; + m_evtQueue.Set(); + Wait(); +} + + + + + +void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + // This is probably never gonna be called twice for the same chunk, and if it is, we don't mind, so we don't check + { + cCSLock Lock(m_CS); + m_ChunksReady.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + } + m_evtQueue.Set(); +} + + + + + +void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +{ + ASSERT(a_Client != NULL); + { + cCSLock Lock(m_CS); + if (std::find(m_SendChunks.begin(), m_SendChunks.end(), sSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client)) != m_SendChunks.end()) + { + // Already queued, bail out + return; + } + m_SendChunks.push_back(sSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client)); + } + m_evtQueue.Set(); +} + + + + + +void cChunkSender::RemoveClient(cClientHandle * a_Client) +{ + { + cCSLock Lock(m_CS); + for (sSendChunkList::iterator itr = m_SendChunks.begin(); itr != m_SendChunks.end();) + { + if (itr->m_Client == a_Client) + { + itr = m_SendChunks.erase(itr); + continue; + } + ++itr; + } // for itr - m_SendChunks[] + m_RemoveCount++; + } + m_evtQueue.Set(); + m_evtRemoved.Wait(); // Wait for removal confirmation +} + + + + + +void cChunkSender::Execute(void) +{ + while (!m_ShouldTerminate) + { + cCSLock Lock(m_CS); + while (m_ChunksReady.empty() && m_SendChunks.empty()) + { + int RemoveCount = m_RemoveCount; + m_RemoveCount = 0; + cCSUnlock Unlock(Lock); + for (int i = 0; i < RemoveCount; i++) + { + m_evtRemoved.Set(); // Notify that the removed clients are safe to be deleted + } + m_evtQueue.Wait(); + if (m_ShouldTerminate) + { + return; + } + } // while (empty) + + if (!m_ChunksReady.empty()) + { + // Take one from the queue: + cChunkCoords Coords(m_ChunksReady.front()); + m_ChunksReady.pop_front(); + Lock.Unlock(); + + SendChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, NULL); + } + else + { + // Take one from the queue: + sSendChunk Chunk(m_SendChunks.front()); + m_SendChunks.pop_front(); + Lock.Unlock(); + + SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkY, Chunk.m_ChunkZ, Chunk.m_Client); + } + Lock.Lock(); + int RemoveCount = m_RemoveCount; + m_RemoveCount = 0; + Lock.Unlock(); + for (int i = 0; i < RemoveCount; i++) + { + m_evtRemoved.Set(); // Notify that the removed clients are safe to be deleted + } + } // while (!mShouldTerminate) +} + + + + + +void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +{ + ASSERT(m_World != NULL); + + // Ask the client if it still wants the chunk: + if (a_Client != NULL) + { + if (!a_Client->WantsSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ)) + { + return; + } + } + + // If the chunk has no clients, no need to packetize it: + if (!m_World->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ)) + { + return; + } + + // If the chunk is not valid, do nothing - whoever needs it has queued it for loading / generating + if (!m_World->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ)) + { + return; + } + + // If the chunk is not lighted, queue it for relighting and get notified when it's ready: + if (!m_World->IsChunkLighted(a_ChunkX, a_ChunkZ)) + { + m_World->QueueLightChunk(a_ChunkX, a_ChunkZ, &m_Notify); + return; + } + + // Prepare MapChunk packets: + if( !m_World->GetChunkData(a_ChunkX, a_ChunkY, a_ChunkZ, *this) ) + { + return; + } + cPacket_PreChunk PreChunk(a_ChunkX, a_ChunkZ, true); + cPacket_MapChunk MapChunk(a_ChunkX, a_ChunkY, a_ChunkZ, m_BlockData, m_BiomeMap); + + // Send: + if (a_Client == NULL) + { + m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, PreChunk); + m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, MapChunk); + } + else + { + a_Client->Send(PreChunk); + a_Client->Send(MapChunk); + } + + // Send entity creation packets: + for (PacketList::iterator itr = m_Packets.begin(); itr != m_Packets.end(); ++itr) + { + if (a_Client == NULL) + { + m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, **itr); + } + else + { + a_Client->Send(**itr); + } + delete *itr; + } // for itr - m_Packets[] + m_Packets.clear(); +} + + + + + +void cChunkSender::BlockEntity(cBlockEntity * a_Entity) +{ + cPacket * Packet = a_Entity->GetPacket(); + if (Packet != NULL) + { + m_Packets.push_back(Packet); + } +} + + + + +void cChunkSender::Entity(cEntity * a_Entity) +{ + // Nothing needed yet, perhaps in the future when we save entities into chunks we'd like to send them upon load, too ;) +} + + + + + +void cChunkSender::BiomeData(const cChunkDef::BiomeMap * a_BiomeMap) +{ + for (int i = 0; i < ARRAYCOUNT(m_BiomeMap); i++) + { + if ((*a_BiomeMap)[i] < 255) + { + // Normal MC biome, copy as-is: + m_BiomeMap[i] = (unsigned char)((*a_BiomeMap)[i]); + } + else + { + // TODO: MCS-specific biome, need to map to some basic MC biome: + ASSERT(!"Unimplemented MCS-specific biome"); + } + } // for i - m_BiomeMap[] +} + + + + diff --git a/source/ChunkSender.h b/source/ChunkSender.h index 196db1dfa..08d97cfca 100644 --- a/source/ChunkSender.h +++ b/source/ChunkSender.h @@ -1,153 +1,153 @@ -
-// ChunkSender.h
-
-// Interfaces to the cChunkSender class representing the thread that waits for chunks becoming ready (loaded / generated) and sends them to clients
-
-/*
-The whole thing is a thread that runs in a loop, waiting for either:
- "finished chunks" (ChunkReady()), or
- "chunks to send" (QueueSendChunkTo() )
-to come to a queue.
-And once they do, it requests the chunk data and sends it all away, either
- broadcasting (ChunkReady), or
- sends to a specific client (QueueSendChunkTo)
-Chunk data is queried using the cChunkDataCallback interface.
-It is cached inside the ChunkSender object during the query and then processed after the query ends.
-Note that the data needs to be compressed only *after* the query finishes,
-because the query callbacks run with ChunkMap's CS locked.
-
-A client may remove itself from all direct requests(QueueSendChunkTo()) by calling RemoveClient();
-this ensures that the client's Send() won't be called anymore by ChunkSender.
-Note that it may be called by world's BroadcastToChunk() if the client is still in the chunk.
-*/
-
-
-
-#pragma once
-
-#include "cIsThread.h"
-#include "ChunkDef.h"
-#include "packets/cPacket.h"
-
-
-
-
-
-class cWorld;
-class cClientHandle;
-
-
-
-
-
-// fwd:
-class cChunkSender;
-
-
-
-
-
-/// Callback that can be used to notify chunk sender upon another chunkcoord notification
-class cNotifyChunkSender :
- public cChunkCoordCallback
-{
- virtual void Call(int a_ChunkX, int a_ChunkZ) override;
-
- cChunkSender * m_ChunkSender;
-public:
- cNotifyChunkSender(cChunkSender * a_ChunkSender) : m_ChunkSender(a_ChunkSender) {}
-
- void SetChunkSender(cChunkSender * a_ChunkSender)
- {
- m_ChunkSender = a_ChunkSender;
- }
-} ;
-
-
-
-
-
-class cChunkSender:
- public cIsThread,
- public cChunkDataCollector
-{
- typedef cIsThread super;
-public:
- cChunkSender(void);
- ~cChunkSender();
-
- bool Start(cWorld * a_World);
-
- void Stop(void);
-
- /// Notifies that a chunk has become ready and it should be sent to all its clients
- void ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- /// Queues a chunk to be sent to a specific client
- void QueueSendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
-
- /// Removes the a_Client from all waiting chunk send operations
- void RemoveClient(cClientHandle * a_Client);
-
-protected:
-
- /// Used for sending chunks to specific clients
- struct sSendChunk
- {
- int m_ChunkX;
- int m_ChunkY;
- int m_ChunkZ;
- cClientHandle * m_Client;
-
- sSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) :
- m_ChunkX(a_ChunkX),
- m_ChunkY(a_ChunkY),
- m_ChunkZ(a_ChunkZ),
- m_Client(a_Client)
- {
- }
-
- bool operator ==(const sSendChunk & a_Other)
- {
- return (
- (a_Other.m_ChunkX == m_ChunkX) &&
- (a_Other.m_ChunkY == m_ChunkY) &&
- (a_Other.m_ChunkZ == m_ChunkZ) &&
- (a_Other.m_Client == m_Client)
- );
- }
- };
- typedef std::list<sSendChunk> sSendChunkList;
-
- cWorld * m_World;
-
- cCriticalSection m_CS;
- cChunkCoordsList m_ChunksReady;
- sSendChunkList m_SendChunks;
- cEvent m_evtQueue; // Set when anything is added to m_ChunksReady
- cEvent m_evtRemoved; // Set when removed clients are safe to be deleted
- int m_RemoveCount; // Number of threads waiting for a client removal (m_evtRemoved needs to be set this many times)
-
- cNotifyChunkSender m_Notify; // Used for chunks that don't have a valid lighting - they will be re-queued after lightcalc
-
- // Data about the chunk that is being sent:
- // NOTE that m_BlockData[] is inherited from the cChunkDataCollector
- unsigned char m_BiomeMap[cChunkDef::Width * cChunkDef::Width];
- PacketList m_Packets; // Accumulator for the entity-packets to send
-
- // cIsThread override:
- virtual void Execute(void) override;
-
- // cChunkDataCollector overrides:
- // (Note that they are called while the ChunkMap's CS is locked - don't do heavy calculations here!)
- virtual void BiomeData (const cChunkDef::BiomeMap * a_BiomeMap) override;
- virtual void Entity (cEntity * a_Entity) override;
- virtual void BlockEntity (cBlockEntity * a_Entity) override;
-
- /// Sends the specified chunk to a_Client, or to all chunk clients if a_Client == NULL
- void SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
-} ;
-
-
-
-
+ +// ChunkSender.h + +// Interfaces to the cChunkSender class representing the thread that waits for chunks becoming ready (loaded / generated) and sends them to clients + +/* +The whole thing is a thread that runs in a loop, waiting for either: + "finished chunks" (ChunkReady()), or + "chunks to send" (QueueSendChunkTo() ) +to come to a queue. +And once they do, it requests the chunk data and sends it all away, either + broadcasting (ChunkReady), or + sends to a specific client (QueueSendChunkTo) +Chunk data is queried using the cChunkDataCallback interface. +It is cached inside the ChunkSender object during the query and then processed after the query ends. +Note that the data needs to be compressed only *after* the query finishes, +because the query callbacks run with ChunkMap's CS locked. + +A client may remove itself from all direct requests(QueueSendChunkTo()) by calling RemoveClient(); +this ensures that the client's Send() won't be called anymore by ChunkSender. +Note that it may be called by world's BroadcastToChunk() if the client is still in the chunk. +*/ + + + +#pragma once + +#include "cIsThread.h" +#include "ChunkDef.h" +#include "packets/cPacket.h" + + + + + +class cWorld; +class cClientHandle; + + + + + +// fwd: +class cChunkSender; + + + + + +/// Callback that can be used to notify chunk sender upon another chunkcoord notification +class cNotifyChunkSender : + public cChunkCoordCallback +{ + virtual void Call(int a_ChunkX, int a_ChunkZ) override; + + cChunkSender * m_ChunkSender; +public: + cNotifyChunkSender(cChunkSender * a_ChunkSender) : m_ChunkSender(a_ChunkSender) {} + + void SetChunkSender(cChunkSender * a_ChunkSender) + { + m_ChunkSender = a_ChunkSender; + } +} ; + + + + + +class cChunkSender: + public cIsThread, + public cChunkDataCollector +{ + typedef cIsThread super; +public: + cChunkSender(void); + ~cChunkSender(); + + bool Start(cWorld * a_World); + + void Stop(void); + + /// Notifies that a chunk has become ready and it should be sent to all its clients + void ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Queues a chunk to be sent to a specific client + void QueueSendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); + + /// Removes the a_Client from all waiting chunk send operations + void RemoveClient(cClientHandle * a_Client); + +protected: + + /// Used for sending chunks to specific clients + struct sSendChunk + { + int m_ChunkX; + int m_ChunkY; + int m_ChunkZ; + cClientHandle * m_Client; + + sSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) : + m_ChunkX(a_ChunkX), + m_ChunkY(a_ChunkY), + m_ChunkZ(a_ChunkZ), + m_Client(a_Client) + { + } + + bool operator ==(const sSendChunk & a_Other) + { + return ( + (a_Other.m_ChunkX == m_ChunkX) && + (a_Other.m_ChunkY == m_ChunkY) && + (a_Other.m_ChunkZ == m_ChunkZ) && + (a_Other.m_Client == m_Client) + ); + } + }; + typedef std::list<sSendChunk> sSendChunkList; + + cWorld * m_World; + + cCriticalSection m_CS; + cChunkCoordsList m_ChunksReady; + sSendChunkList m_SendChunks; + cEvent m_evtQueue; // Set when anything is added to m_ChunksReady + cEvent m_evtRemoved; // Set when removed clients are safe to be deleted + int m_RemoveCount; // Number of threads waiting for a client removal (m_evtRemoved needs to be set this many times) + + cNotifyChunkSender m_Notify; // Used for chunks that don't have a valid lighting - they will be re-queued after lightcalc + + // Data about the chunk that is being sent: + // NOTE that m_BlockData[] is inherited from the cChunkDataCollector + unsigned char m_BiomeMap[cChunkDef::Width * cChunkDef::Width]; + PacketList m_Packets; // Accumulator for the entity-packets to send + + // cIsThread override: + virtual void Execute(void) override; + + // cChunkDataCollector overrides: + // (Note that they are called while the ChunkMap's CS is locked - don't do heavy calculations here!) + virtual void BiomeData (const cChunkDef::BiomeMap * a_BiomeMap) override; + virtual void Entity (cEntity * a_Entity) override; + virtual void BlockEntity (cBlockEntity * a_Entity) override; + + /// Sends the specified chunk to a_Client, or to all chunk clients if a_Client == NULL + void SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); +} ; + + + + diff --git a/source/CompoGen.cpp b/source/CompoGen.cpp index dfb0a40f8..e5f519611 100644 --- a/source/CompoGen.cpp +++ b/source/CompoGen.cpp @@ -1,427 +1,427 @@ -
-// CompoGen.cpp
-
-/* Implements the various terrain composition generators:
- - cCompoGenSameBlock
- - cCompoGenDebugBiomes
- - cCompoGenClassic
-*/
-
-#include "Globals.h"
-#include "CompoGen.h"
-#include "BlockID.h"
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cCompoGenSameBlock:
-
-void cCompoGenSameBlock::ComposeTerrain(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated
- cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated
- const cChunkDef::HeightMap & a_HeightMap, // The height map to fit
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entitites may be generated along with the terrain
- cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...)
-)
-{
- memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes));
- memset(a_BlockMeta, 0, sizeof(a_BlockMeta));
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- for (int x = 0; x < cChunkDef::Width; x++)
- {
- int Start;
- if (m_IsBedrocked)
- {
- a_BlockTypes[cChunkDef::MakeIndex(x, 0, z)] = E_BLOCK_BEDROCK;
- Start = 1;
- }
- else
- {
- Start = 0;
- }
- for (int y = a_HeightMap[x + cChunkDef::Width * z]; y >= Start; y--)
- {
- a_BlockTypes[cChunkDef::MakeIndex(x, y, z)] = m_BlockType;
- } // for y
- } // for z
- } // for x
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cCompoGenDebugBiomes:
-
-void cCompoGenDebugBiomes::ComposeTerrain(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated
- cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated
- const cChunkDef::HeightMap & a_HeightMap, // The height map to fit
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entitites may be generated along with the terrain
- cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...)
-)
-{
- static BLOCKTYPE Blocks[] =
- {
- E_BLOCK_STONE,
- E_BLOCK_COBBLESTONE,
- E_BLOCK_LOG,
- E_BLOCK_PLANKS,
- E_BLOCK_SANDSTONE,
- E_BLOCK_WHITE_CLOTH,
- E_BLOCK_COAL_ORE,
- E_BLOCK_IRON_ORE,
- E_BLOCK_GOLD_ORE,
- E_BLOCK_DIAMOND_ORE,
- E_BLOCK_LAPIS_ORE,
- E_BLOCK_REDSTONE_ORE,
- E_BLOCK_IRON_BLOCK,
- E_BLOCK_GOLD_BLOCK,
- E_BLOCK_DIAMOND_BLOCK,
- E_BLOCK_LAPIS_BLOCK,
- E_BLOCK_BRICK,
- E_BLOCK_MOSSY_COBBLESTONE,
- E_BLOCK_OBSIDIAN,
- E_BLOCK_NETHERRACK,
- E_BLOCK_SOULSAND,
- E_BLOCK_NETHER_BRICK,
- E_BLOCK_BEDROCK,
- } ;
-
- memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes));
- memset(a_BlockMeta, 0, sizeof(a_BlockMeta));
-
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- for (int x = 0; x < cChunkDef::Width; x++)
- {
- BLOCKTYPE BlockType = Blocks[cChunkDef::GetBiome(a_BiomeMap, x, z) % ARRAYCOUNT(Blocks)];
- for (int y = a_HeightMap[x + cChunkDef::Width * z]; y >= 0; y--)
- {
- cChunkDef::SetBlock(a_BlockTypes, x, y, z, BlockType);
- } // for y
- } // for z
- } // for x
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cCompoGenClassic:
-
-cCompoGenClassic::cCompoGenClassic(
- int a_SeaLevel, int a_BeachHeight, int a_BeachDepth,
- BLOCKTYPE a_BlockTop, BLOCKTYPE a_BlockMiddle, BLOCKTYPE a_BlockBottom,
- BLOCKTYPE a_BlockBeach, BLOCKTYPE a_BlockBeachBottom, BLOCKTYPE a_BlockSea
-) :
- m_SeaLevel(a_SeaLevel),
- m_BeachHeight(a_BeachHeight),
- m_BeachDepth(a_BeachDepth),
- m_BlockTop(a_BlockTop),
- m_BlockMiddle(a_BlockMiddle),
- m_BlockBottom(a_BlockBottom),
- m_BlockBeach(a_BlockBeach),
- m_BlockBeachBottom(a_BlockBeachBottom),
- m_BlockSea(a_BlockSea)
-{
-}
-
-
-
-
-
-void cCompoGenClassic::ComposeTerrain(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated
- cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated
- const cChunkDef::HeightMap & a_HeightMap, // The height map to fit
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entitites may be generated along with the terrain
- cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...)
-)
-{
- /* The classic composition means:
- - 1 layer of grass, 3 of dirt and the rest stone, if the height > sealevel + beachheight
- - 3 sand and a 1 sandstone, rest stone if between sealevel and sealevel + beachheight
- - water from waterlevel to height, then 3 sand, 1 sandstone, the rest stone, if water depth < beachdepth
- - water from waterlevel, then 3 dirt, the rest stone otherwise
- - bedrock at the bottom
- */
-
- memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes));
- memset(a_BlockMeta, 0, sizeof(a_BlockMeta));
-
- // The patterns to use for different situations, must be same length!
- static const BLOCKTYPE PatternGround[] = {m_BlockTop, m_BlockMiddle, m_BlockMiddle, m_BlockMiddle} ;
- static const BLOCKTYPE PatternBeach[] = {m_BlockBeach, m_BlockBeach, m_BlockBeach, m_BlockBeachBottom} ;
- static const BLOCKTYPE PatternOcean[] = {m_BlockMiddle, m_BlockMiddle, m_BlockMiddle, m_BlockBottom} ;
- static int PatternLength = ARRAYCOUNT(PatternGround);
- ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternBeach));
- ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternOcean));
-
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- for (int x = 0; x < cChunkDef::Width; x++)
- {
- int Height = cChunkDef::GetHeight(a_HeightMap, x, z);
- const BLOCKTYPE * Pattern;
- if (Height > m_SeaLevel + m_BeachHeight)
- {
- Pattern = PatternGround;
- }
- else if (Height > m_SeaLevel - m_BeachDepth)
- {
- Pattern = PatternBeach;
- }
- else
- {
- Pattern = PatternOcean;
- }
-
- // Fill water from sealevel down to height (if any):
- for (int y = m_SeaLevel; y >= Height; --y)
- {
- cChunkDef::SetBlock(a_BlockTypes, x, y, z, m_BlockSea);
- }
-
- // Fill from height till the bottom:
- for (int y = Height; y >= 1; y--)
- {
- cChunkDef::SetBlock(a_BlockTypes, x, y, z, (Height - y < PatternLength) ? Pattern[Height - y] : m_BlockBottom);
- }
-
- // The last layer is always bedrock:
- cChunkDef::SetBlock(a_BlockTypes, x, 0, z, E_BLOCK_BEDROCK);
- } // for x
- } // for z
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cCompoGenBiomal:
-
-void cCompoGenBiomal::ComposeTerrain(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated
- cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated
- const cChunkDef::HeightMap & a_HeightMap, // The height map to fit
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entitites may be generated along with the terrain
- cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...)
-)
-{
- memset(a_BlockTypes, 0, sizeof(a_BlockTypes));
- memset(a_BlockMeta, 0, sizeof(a_BlockMeta));
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- for (int x = 0; x < cChunkDef::Width; x++)
- {
- int Height = cChunkDef::GetHeight(a_HeightMap, x, z);
- if (Height > m_SeaLevel)
- {
- switch (cChunkDef::GetBiome(a_BiomeMap, x, z))
- {
- case biOcean:
- case biPlains:
- case biExtremeHills:
- case biForest:
- case biTaiga:
- case biSwampland:
- case biRiver:
- case biFrozenOcean:
- case biFrozenRiver:
- case biIcePlains:
- case biIceMountains:
- case biForestHills:
- case biTaigaHills:
- case biExtremeHillsEdge:
- case biJungle:
- case biJungleHills:
- {
- FillColumnGrass(x, z, Height, a_BlockTypes);
- break;
- }
- case biDesertHills:
- case biDesert:
- case biBeach:
- {
- FillColumnSand(x, z, Height, a_BlockTypes);
- break;
- }
- case biMushroomIsland:
- case biMushroomShore:
- {
- FillColumnMycelium(x, z, Height, a_BlockTypes);
- break;
- }
- default:
- {
- // TODO
- ASSERT(!"CompoGenBiomal: Biome not implemented yet!");
- break;
- }
- }
- }
- else
- {
- switch (cChunkDef::GetBiome(a_BiomeMap, x, z))
- {
- case biDesert:
- case biBeach:
- {
- // Fill with water, sand, sandstone and stone
- FillColumnWaterSand(x, z, Height, a_BlockTypes);
- break;
- }
- default:
- {
- // Fill with water, sand/dirt/clay mix and stone
- FillColumnWaterMix(a_ChunkX, a_ChunkZ, x, z, Height, a_BlockTypes);
- break;
- }
- } // switch (biome)
- } // else (under water)
- cChunkDef::SetBlock(a_BlockTypes, x, 0, z, E_BLOCK_BEDROCK);
- } // for x
- } // for z
-}
-
-
-
-
-
-void cCompoGenBiomal::FillColumnGrass(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes)
-{
- BLOCKTYPE Pattern[] =
- {
- E_BLOCK_GRASS,
- E_BLOCK_DIRT,
- E_BLOCK_DIRT,
- E_BLOCK_DIRT,
- } ;
- FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern));
-
- for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--)
- {
- cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE);
- }
-}
-
-
-
-
-
-void cCompoGenBiomal::FillColumnSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes)
-{
- BLOCKTYPE Pattern[] =
- {
- E_BLOCK_SAND,
- E_BLOCK_SAND,
- E_BLOCK_SAND,
- E_BLOCK_SANDSTONE,
- } ;
- FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern));
-
- for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--)
- {
- cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE);
- }
-}
-
-
-
-
-
-
-void cCompoGenBiomal::FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes)
-{
- BLOCKTYPE Pattern[] =
- {
- E_BLOCK_MYCELIUM,
- E_BLOCK_DIRT,
- E_BLOCK_DIRT,
- E_BLOCK_DIRT,
- } ;
- FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern));
-
- for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--)
- {
- cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE);
- }
-}
-
-
-
-
-
-void cCompoGenBiomal::FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes)
-{
- FillColumnSand(a_RelX, a_RelZ, a_Height, a_BlockTypes);
- for (int y = a_Height + 1; y <= m_SeaLevel + 1; y++)
- {
- cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_WATER);
- }
-}
-
-
-
-
-
-void cCompoGenBiomal::FillColumnWaterMix(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes)
-{
- if (m_Noise.CubicNoise2D(0.5f * (cChunkDef::Width * a_ChunkX + a_RelX), 0.5f * (cChunkDef::Width * a_ChunkZ + a_RelZ)) < 0)
- {
- FillColumnWaterSand(a_RelX, a_RelZ, a_Height, a_BlockTypes);
- }
- else
- {
- // Dirt
- BLOCKTYPE Pattern[] =
- {
- E_BLOCK_DIRT,
- E_BLOCK_DIRT,
- E_BLOCK_DIRT,
- E_BLOCK_DIRT,
- } ;
- FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern));
-
- for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--)
- {
- cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE);
- }
- for (int y = a_Height + 1; y <= m_SeaLevel + 1; y++)
- {
- cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_WATER);
- }
- }
-}
-
-
-
-
-
-
-void cCompoGenBiomal::FillColumnPattern(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes, const BLOCKTYPE * a_Pattern, int a_PatternSize)
-{
- for (int y = a_Height, idx = 0; (y >= 0) && (idx < a_PatternSize); y--, idx++)
- {
- cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, a_Pattern[idx]);
- }
-}
-
-
-
-
+ +// CompoGen.cpp + +/* Implements the various terrain composition generators: + - cCompoGenSameBlock + - cCompoGenDebugBiomes + - cCompoGenClassic +*/ + +#include "Globals.h" +#include "CompoGen.h" +#include "BlockID.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCompoGenSameBlock: + +void cCompoGenSameBlock::ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) +) +{ + memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes)); + memset(a_BlockMeta, 0, sizeof(a_BlockMeta)); + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + int Start; + if (m_IsBedrocked) + { + a_BlockTypes[cChunkDef::MakeIndex(x, 0, z)] = E_BLOCK_BEDROCK; + Start = 1; + } + else + { + Start = 0; + } + for (int y = a_HeightMap[x + cChunkDef::Width * z]; y >= Start; y--) + { + a_BlockTypes[cChunkDef::MakeIndex(x, y, z)] = m_BlockType; + } // for y + } // for z + } // for x +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCompoGenDebugBiomes: + +void cCompoGenDebugBiomes::ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) +) +{ + static BLOCKTYPE Blocks[] = + { + E_BLOCK_STONE, + E_BLOCK_COBBLESTONE, + E_BLOCK_LOG, + E_BLOCK_PLANKS, + E_BLOCK_SANDSTONE, + E_BLOCK_WHITE_CLOTH, + E_BLOCK_COAL_ORE, + E_BLOCK_IRON_ORE, + E_BLOCK_GOLD_ORE, + E_BLOCK_DIAMOND_ORE, + E_BLOCK_LAPIS_ORE, + E_BLOCK_REDSTONE_ORE, + E_BLOCK_IRON_BLOCK, + E_BLOCK_GOLD_BLOCK, + E_BLOCK_DIAMOND_BLOCK, + E_BLOCK_LAPIS_BLOCK, + E_BLOCK_BRICK, + E_BLOCK_MOSSY_COBBLESTONE, + E_BLOCK_OBSIDIAN, + E_BLOCK_NETHERRACK, + E_BLOCK_SOULSAND, + E_BLOCK_NETHER_BRICK, + E_BLOCK_BEDROCK, + } ; + + memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes)); + memset(a_BlockMeta, 0, sizeof(a_BlockMeta)); + + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + BLOCKTYPE BlockType = Blocks[cChunkDef::GetBiome(a_BiomeMap, x, z) % ARRAYCOUNT(Blocks)]; + for (int y = a_HeightMap[x + cChunkDef::Width * z]; y >= 0; y--) + { + cChunkDef::SetBlock(a_BlockTypes, x, y, z, BlockType); + } // for y + } // for z + } // for x +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCompoGenClassic: + +cCompoGenClassic::cCompoGenClassic( + int a_SeaLevel, int a_BeachHeight, int a_BeachDepth, + BLOCKTYPE a_BlockTop, BLOCKTYPE a_BlockMiddle, BLOCKTYPE a_BlockBottom, + BLOCKTYPE a_BlockBeach, BLOCKTYPE a_BlockBeachBottom, BLOCKTYPE a_BlockSea +) : + m_SeaLevel(a_SeaLevel), + m_BeachHeight(a_BeachHeight), + m_BeachDepth(a_BeachDepth), + m_BlockTop(a_BlockTop), + m_BlockMiddle(a_BlockMiddle), + m_BlockBottom(a_BlockBottom), + m_BlockBeach(a_BlockBeach), + m_BlockBeachBottom(a_BlockBeachBottom), + m_BlockSea(a_BlockSea) +{ +} + + + + + +void cCompoGenClassic::ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) +) +{ + /* The classic composition means: + - 1 layer of grass, 3 of dirt and the rest stone, if the height > sealevel + beachheight + - 3 sand and a 1 sandstone, rest stone if between sealevel and sealevel + beachheight + - water from waterlevel to height, then 3 sand, 1 sandstone, the rest stone, if water depth < beachdepth + - water from waterlevel, then 3 dirt, the rest stone otherwise + - bedrock at the bottom + */ + + memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes)); + memset(a_BlockMeta, 0, sizeof(a_BlockMeta)); + + // The patterns to use for different situations, must be same length! + static const BLOCKTYPE PatternGround[] = {m_BlockTop, m_BlockMiddle, m_BlockMiddle, m_BlockMiddle} ; + static const BLOCKTYPE PatternBeach[] = {m_BlockBeach, m_BlockBeach, m_BlockBeach, m_BlockBeachBottom} ; + static const BLOCKTYPE PatternOcean[] = {m_BlockMiddle, m_BlockMiddle, m_BlockMiddle, m_BlockBottom} ; + static int PatternLength = ARRAYCOUNT(PatternGround); + ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternBeach)); + ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternOcean)); + + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + int Height = cChunkDef::GetHeight(a_HeightMap, x, z); + const BLOCKTYPE * Pattern; + if (Height > m_SeaLevel + m_BeachHeight) + { + Pattern = PatternGround; + } + else if (Height > m_SeaLevel - m_BeachDepth) + { + Pattern = PatternBeach; + } + else + { + Pattern = PatternOcean; + } + + // Fill water from sealevel down to height (if any): + for (int y = m_SeaLevel; y >= Height; --y) + { + cChunkDef::SetBlock(a_BlockTypes, x, y, z, m_BlockSea); + } + + // Fill from height till the bottom: + for (int y = Height; y >= 1; y--) + { + cChunkDef::SetBlock(a_BlockTypes, x, y, z, (Height - y < PatternLength) ? Pattern[Height - y] : m_BlockBottom); + } + + // The last layer is always bedrock: + cChunkDef::SetBlock(a_BlockTypes, x, 0, z, E_BLOCK_BEDROCK); + } // for x + } // for z +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCompoGenBiomal: + +void cCompoGenBiomal::ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) +) +{ + memset(a_BlockTypes, 0, sizeof(a_BlockTypes)); + memset(a_BlockMeta, 0, sizeof(a_BlockMeta)); + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + int Height = cChunkDef::GetHeight(a_HeightMap, x, z); + if (Height > m_SeaLevel) + { + switch (cChunkDef::GetBiome(a_BiomeMap, x, z)) + { + case biOcean: + case biPlains: + case biExtremeHills: + case biForest: + case biTaiga: + case biSwampland: + case biRiver: + case biFrozenOcean: + case biFrozenRiver: + case biIcePlains: + case biIceMountains: + case biForestHills: + case biTaigaHills: + case biExtremeHillsEdge: + case biJungle: + case biJungleHills: + { + FillColumnGrass(x, z, Height, a_BlockTypes); + break; + } + case biDesertHills: + case biDesert: + case biBeach: + { + FillColumnSand(x, z, Height, a_BlockTypes); + break; + } + case biMushroomIsland: + case biMushroomShore: + { + FillColumnMycelium(x, z, Height, a_BlockTypes); + break; + } + default: + { + // TODO + ASSERT(!"CompoGenBiomal: Biome not implemented yet!"); + break; + } + } + } + else + { + switch (cChunkDef::GetBiome(a_BiomeMap, x, z)) + { + case biDesert: + case biBeach: + { + // Fill with water, sand, sandstone and stone + FillColumnWaterSand(x, z, Height, a_BlockTypes); + break; + } + default: + { + // Fill with water, sand/dirt/clay mix and stone + FillColumnWaterMix(a_ChunkX, a_ChunkZ, x, z, Height, a_BlockTypes); + break; + } + } // switch (biome) + } // else (under water) + cChunkDef::SetBlock(a_BlockTypes, x, 0, z, E_BLOCK_BEDROCK); + } // for x + } // for z +} + + + + + +void cCompoGenBiomal::FillColumnGrass(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) +{ + BLOCKTYPE Pattern[] = + { + E_BLOCK_GRASS, + E_BLOCK_DIRT, + E_BLOCK_DIRT, + E_BLOCK_DIRT, + } ; + FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); + + for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); + } +} + + + + + +void cCompoGenBiomal::FillColumnSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) +{ + BLOCKTYPE Pattern[] = + { + E_BLOCK_SAND, + E_BLOCK_SAND, + E_BLOCK_SAND, + E_BLOCK_SANDSTONE, + } ; + FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); + + for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); + } +} + + + + + + +void cCompoGenBiomal::FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) +{ + BLOCKTYPE Pattern[] = + { + E_BLOCK_MYCELIUM, + E_BLOCK_DIRT, + E_BLOCK_DIRT, + E_BLOCK_DIRT, + } ; + FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); + + for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); + } +} + + + + + +void cCompoGenBiomal::FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) +{ + FillColumnSand(a_RelX, a_RelZ, a_Height, a_BlockTypes); + for (int y = a_Height + 1; y <= m_SeaLevel + 1; y++) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_WATER); + } +} + + + + + +void cCompoGenBiomal::FillColumnWaterMix(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) +{ + if (m_Noise.CubicNoise2D(0.5f * (cChunkDef::Width * a_ChunkX + a_RelX), 0.5f * (cChunkDef::Width * a_ChunkZ + a_RelZ)) < 0) + { + FillColumnWaterSand(a_RelX, a_RelZ, a_Height, a_BlockTypes); + } + else + { + // Dirt + BLOCKTYPE Pattern[] = + { + E_BLOCK_DIRT, + E_BLOCK_DIRT, + E_BLOCK_DIRT, + E_BLOCK_DIRT, + } ; + FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern)); + + for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE); + } + for (int y = a_Height + 1; y <= m_SeaLevel + 1; y++) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_WATER); + } + } +} + + + + + + +void cCompoGenBiomal::FillColumnPattern(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes, const BLOCKTYPE * a_Pattern, int a_PatternSize) +{ + for (int y = a_Height, idx = 0; (y >= 0) && (idx < a_PatternSize); y--, idx++) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, a_Pattern[idx]); + } +} + + + + diff --git a/source/CompoGen.h b/source/CompoGen.h index e04494fd8..a7939e68d 100644 --- a/source/CompoGen.h +++ b/source/CompoGen.h @@ -1,154 +1,154 @@ -
-// CompoGen.h
-
-/* Interfaces to the various terrain composition generators:
- - cCompoGenSameBlock
- - cCompoGenDebugBiomes
- - cCompoGenClassic
- - cCompoGenBiomal
-*/
-
-
-
-
-
-#pragma once
-
-#include "cChunkGenerator.h"
-#include "cNoise.h"
-
-
-
-
-
-class cCompoGenSameBlock :
- public cTerrainCompositionGen
-{
-public:
- cCompoGenSameBlock(BLOCKTYPE a_BlockType, bool a_IsBedrocked) :
- m_BlockType(a_BlockType),
- m_IsBedrocked(a_IsBedrocked)
- {}
-
-protected:
-
- BLOCKTYPE m_BlockType;
- bool m_IsBedrocked;
-
- // cTerrainCompositionGen overrides:
- virtual void ComposeTerrain(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated
- cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated
- const cChunkDef::HeightMap & a_HeightMap, // The height map to fit
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entitites may be generated along with the terrain
- cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...)
- ) override;
-} ;
-
-
-
-
-
-class cCompoGenDebugBiomes :
- public cTerrainCompositionGen
-{
-public:
- cCompoGenDebugBiomes(void) {}
-
-protected:
-
- // cTerrainCompositionGen overrides:
- virtual void ComposeTerrain(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated
- cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated
- const cChunkDef::HeightMap & a_HeightMap, // The height map to fit
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entitites may be generated along with the terrain
- cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...)
- ) override;
-} ;
-
-
-
-
-
-class cCompoGenClassic :
- public cTerrainCompositionGen
-{
-public:
- cCompoGenClassic(
- int a_SeaLevel, int a_BeachHeight, int a_BeachDepth,
- BLOCKTYPE a_BlockTop, BLOCKTYPE a_BlockMiddle, BLOCKTYPE a_BlockBottom,
- BLOCKTYPE a_BlockBeach, BLOCKTYPE a_BlockBeachBottom, BLOCKTYPE a_BlockSea
- );
-
-protected:
-
- int m_SeaLevel;
- int m_BeachHeight;
- int m_BeachDepth;
- BLOCKTYPE m_BlockTop;
- BLOCKTYPE m_BlockMiddle;
- BLOCKTYPE m_BlockBottom;
- BLOCKTYPE m_BlockBeach;
- BLOCKTYPE m_BlockBeachBottom;
- BLOCKTYPE m_BlockSea;
-
- // cTerrainCompositionGen overrides:
- virtual void ComposeTerrain(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated
- cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated
- const cChunkDef::HeightMap & a_HeightMap, // The height map to fit
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entitites may be generated along with the terrain
- cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...)
- ) override;
-} ;
-
-
-
-
-
-class cCompoGenBiomal :
- public cTerrainCompositionGen
-{
-public:
- cCompoGenBiomal(int a_Seed, int a_SeaLevel) :
- m_Noise(a_Seed + 1000),
- m_SeaLevel(a_SeaLevel - 1) // we do an adjustment later in filling the terrain with water
- {
- }
-
-protected:
-
- cNoise m_Noise;
- int m_SeaLevel;
-
- // cTerrainCompositionGen overrides:
- virtual void ComposeTerrain(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated
- cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated
- const cChunkDef::HeightMap & a_HeightMap, // The height map to fit
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entitites may be generated along with the terrain
- cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...)
- ) override;
-
- void FillColumnGrass (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes);
- void FillColumnSand (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes);
- void FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes);
- void FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes);
-
- void FillColumnWaterMix (int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes);
-
- void FillColumnPattern (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes, const BLOCKTYPE * a_Pattern, int a_PatternSize);
-} ;
-
-
-
-
+ +// CompoGen.h + +/* Interfaces to the various terrain composition generators: + - cCompoGenSameBlock + - cCompoGenDebugBiomes + - cCompoGenClassic + - cCompoGenBiomal +*/ + + + + + +#pragma once + +#include "cChunkGenerator.h" +#include "cNoise.h" + + + + + +class cCompoGenSameBlock : + public cTerrainCompositionGen +{ +public: + cCompoGenSameBlock(BLOCKTYPE a_BlockType, bool a_IsBedrocked) : + m_BlockType(a_BlockType), + m_IsBedrocked(a_IsBedrocked) + {} + +protected: + + BLOCKTYPE m_BlockType; + bool m_IsBedrocked; + + // cTerrainCompositionGen overrides: + virtual void ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) + ) override; +} ; + + + + + +class cCompoGenDebugBiomes : + public cTerrainCompositionGen +{ +public: + cCompoGenDebugBiomes(void) {} + +protected: + + // cTerrainCompositionGen overrides: + virtual void ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) + ) override; +} ; + + + + + +class cCompoGenClassic : + public cTerrainCompositionGen +{ +public: + cCompoGenClassic( + int a_SeaLevel, int a_BeachHeight, int a_BeachDepth, + BLOCKTYPE a_BlockTop, BLOCKTYPE a_BlockMiddle, BLOCKTYPE a_BlockBottom, + BLOCKTYPE a_BlockBeach, BLOCKTYPE a_BlockBeachBottom, BLOCKTYPE a_BlockSea + ); + +protected: + + int m_SeaLevel; + int m_BeachHeight; + int m_BeachDepth; + BLOCKTYPE m_BlockTop; + BLOCKTYPE m_BlockMiddle; + BLOCKTYPE m_BlockBottom; + BLOCKTYPE m_BlockBeach; + BLOCKTYPE m_BlockBeachBottom; + BLOCKTYPE m_BlockSea; + + // cTerrainCompositionGen overrides: + virtual void ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) + ) override; +} ; + + + + + +class cCompoGenBiomal : + public cTerrainCompositionGen +{ +public: + cCompoGenBiomal(int a_Seed, int a_SeaLevel) : + m_Noise(a_Seed + 1000), + m_SeaLevel(a_SeaLevel - 1) // we do an adjustment later in filling the terrain with water + { + } + +protected: + + cNoise m_Noise; + int m_SeaLevel; + + // cTerrainCompositionGen overrides: + virtual void ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) + ) override; + + void FillColumnGrass (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + void FillColumnSand (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + void FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + void FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + + void FillColumnWaterMix (int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + + void FillColumnPattern (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes, const BLOCKTYPE * a_Pattern, int a_PatternSize); +} ; + + + + diff --git a/source/CraftingRecipes.cpp b/source/CraftingRecipes.cpp index d26f553e9..38daa1fe8 100644 --- a/source/CraftingRecipes.cpp +++ b/source/CraftingRecipes.cpp @@ -1,765 +1,765 @@ -
-// CraftingRecipes.cpp
-
-// Interfaces to the cCraftingRecipes class representing the storage of crafting recipes
-
-#include "Globals.h"
-#include "CraftingRecipes.h"
-#include "cRoot.h"
-#include "cPluginManager.h"
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cCraftingGrid:
-
-cCraftingGrid::cCraftingGrid(int a_Width, int a_Height) :
- m_Width(a_Width),
- m_Height(a_Height),
- m_Items(new cItem[a_Width * a_Height])
-{
-}
-
-
-
-
-
-cCraftingGrid::cCraftingGrid(cItem * a_Items, int a_Width, int a_Height) :
- m_Width(a_Width),
- m_Height(a_Height),
- m_Items(new cItem[a_Width * a_Height])
-{
- for (int i = a_Width * a_Height - 1; i >= 0; i--)
- {
- m_Items[i] = a_Items[i];
- }
-}
-
-
-
-
-
-cCraftingGrid::cCraftingGrid(const cCraftingGrid & a_Original) :
- m_Width(a_Original.m_Width),
- m_Height(a_Original.m_Height),
- m_Items(new cItem[a_Original.m_Width * a_Original.m_Height])
-{
- for (int i = m_Width * m_Height - 1; i >= 0; i--)
- {
- m_Items[i] = a_Original.m_Items[i];
- }
-}
-
-
-
-
-
-cCraftingGrid::~cCraftingGrid()
-{
- delete[] m_Items;
-}
-
-
-
-
-
-cItem & cCraftingGrid::GetItem(int x, int y) const
-{
- // Accessible through scripting, must verify parameters:
- if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height))
- {
- LOGERROR("Attempted to get an invalid item from a crafting grid: (%d, %d), grid dimensions: (%d, %d).",
- x, y, m_Width, m_Height
- );
- return m_Items[0];
- }
- return m_Items[x + m_Width * y];
-}
-
-
-
-
-
-void cCraftingGrid::SetItem(int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth)
-{
- // Accessible through scripting, must verify parameters:
- if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height))
- {
- LOGERROR("Attempted to set an invalid item in a crafting grid: (%d, %d), grid dimensions: (%d, %d).",
- x, y, m_Width, m_Height
- );
- return;
- }
-
- m_Items[x + m_Width * y] = cItem(a_ItemType, a_ItemCount, a_ItemHealth);
-}
-
-
-
-
-
-void cCraftingGrid::SetItem(int x, int y, const cItem & a_Item)
-{
- // Accessible through scripting, must verify parameters:
- if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height))
- {
- LOGERROR("Attempted to set an invalid item in a crafting grid: (%d, %d), grid dimensions: (%d, %d).",
- x, y, m_Width, m_Height
- );
- return;
- }
-
- m_Items[x + m_Width * y] = a_Item;
-}
-
-
-
-
-
-void cCraftingGrid::Clear(void)
-{
- for (int y = 0; y < m_Height; y++) for (int x = 0; x < m_Width; x++)
- {
- m_Items[x + m_Width * y].Empty();
- }
-}
-
-
-
-
-
-void cCraftingGrid::ConsumeGrid(const cCraftingGrid & a_Grid)
-{
- if ((a_Grid.m_Width != m_Width) || (a_Grid.m_Height != m_Height))
- {
- LOGWARNING("Consuming a grid of different dimensions: (%d, %d) vs (%d, %d)",
- a_Grid.m_Width, a_Grid.m_Height, m_Width, m_Height
- );
- }
- int MinX = std::min(a_Grid.m_Width, m_Width);
- int MinY = std::min(a_Grid.m_Height, m_Height);
- for (int y = 0; y < MinY; y++) for (int x = 0; x < MinX; x++)
- {
- int ThatIdx = x + a_Grid.m_Width * y;
- if (a_Grid.m_Items[ThatIdx].IsEmpty())
- {
- continue;
- }
- int ThisIdx = x + m_Width * y;
- if (a_Grid.m_Items[ThatIdx].m_ItemID != m_Items[ThisIdx].m_ItemID)
- {
- LOGWARNING("Consuming incompatible grids: item at (%d, %d) is %d in grid and %d in ingredients. Item not consumed.",
- x, y, m_Items[ThisIdx].m_ItemID, a_Grid.m_Items[ThatIdx].m_ItemID
- );
- continue;
- }
- char NumWantedItems = a_Grid.m_Items[ThatIdx].m_ItemCount;
- if (NumWantedItems > m_Items[ThisIdx].m_ItemCount)
- {
- LOGWARNING("Consuming more items than there actually are in slot (%d, %d), item %d (want %d, have %d). Item zeroed out.",
- x, y, m_Items[ThisIdx].m_ItemID,
- NumWantedItems, m_Items[ThisIdx].m_ItemCount
- );
- NumWantedItems = m_Items[ThisIdx].m_ItemCount;
- }
- m_Items[ThisIdx].m_ItemCount -= NumWantedItems;
- if (m_Items[ThisIdx].m_ItemCount == 0)
- {
- m_Items[ThisIdx].Clear();
- }
- } // for x, for y
-}
-
-
-
-
-
-void cCraftingGrid::CopyToItems(cItem * a_Items) const
-{
- for (int i = m_Height * m_Width - 1; i >= 0; i--)
- {
- a_Items[i] = m_Items[i];
- } // for x, for y
-}
-
-
-
-
-
-void cCraftingGrid::Dump(void)
-{
- for (int y = 0; y < m_Height; y++) for (int x = 0; x < m_Width; x++)
- {
- int idx = x + m_Width * y;
- LOGD("Slot (%d, %d): Type %d, health %d, count %d",
- x, y, m_Items[idx].m_ItemID, m_Items[idx].m_ItemHealth, m_Items[idx].m_ItemCount
- );
- }
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cCraftingRecipe:
-
-cCraftingRecipe::cCraftingRecipe(const cCraftingGrid & a_CraftingGrid) :
- m_Ingredients(a_CraftingGrid)
-{
-}
-
-
-
-
-
-void cCraftingRecipe::Clear(void)
-{
- m_Ingredients.Clear();
- m_Result.Clear();
-}
-
-
-
-
-
-void cCraftingRecipe::SetResult(ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth)
-{
- m_Result = cItem(a_ItemType, a_ItemCount, a_ItemHealth);
-}
-
-
-
-
-
-void cCraftingRecipe::ConsumeIngredients(cCraftingGrid & a_CraftingGrid)
-{
- a_CraftingGrid.ConsumeGrid(m_Ingredients);
-}
-
-
-
-
-
-void cCraftingRecipe::Dump(void)
-{
- LOGD("Recipe ingredients:");
- m_Ingredients.Dump();
- LOGD("Result: Type %d, health %d, count %d",
- m_Result.m_ItemID, m_Result.m_ItemHealth, m_Result.m_ItemCount
- );
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cCraftingRecipes:
-
-cCraftingRecipes::cCraftingRecipes(void)
-{
- LoadRecipes();
-}
-
-
-
-
-
-cCraftingRecipes::~cCraftingRecipes()
-{
- ClearRecipes();
-}
-
-
-
-
-
-void cCraftingRecipes::GetRecipe(const cPlayer * a_Player, const cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe)
-{
- // Allow plugins to intercept recipes using a pre-craft hook:
- if (cRoot::Get()->GetPluginManager()->CallHookPreCrafting(a_Player, &a_CraftingGrid, &a_Recipe))
- {
- return;
- }
-
- // Built-in recipes:
- std::auto_ptr<cRecipe> Recipe(FindRecipe(a_CraftingGrid.GetItems(), a_CraftingGrid.GetWidth(), a_CraftingGrid.GetHeight()));
- a_Recipe.Clear();
- if (Recipe.get() == NULL)
- {
- // Allow plugins to intercept a no-recipe-found situation:
- cRoot::Get()->GetPluginManager()->CallHookCraftingNoRecipe(a_Player, &a_CraftingGrid, &a_Recipe);
- return;
- }
- for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr)
- {
- a_Recipe.SetIngredient(itr->x, itr->y, itr->m_Item);
- } // for itr
- a_Recipe.SetResult(Recipe->m_Result);
-
- // Allow plugins to intercept recipes after they are processed:
- cRoot::Get()->GetPluginManager()->CallHookPostCrafting(a_Player, &a_CraftingGrid, &a_Recipe);
-}
-
-
-
-
-
-void cCraftingRecipes::LoadRecipes(void)
-{
- LOG("-- Loading crafting recipes from crafting.txt --");
- ClearRecipes();
-
- // Load the crafting.txt file:
- cFile f;
- if (!f.Open("crafting.txt", cFile::fmRead))
- {
- LOGWARNING("Cannot open file \"crafting.txt\", no crafting recipes will be available!");
- return;
- }
- AString Everything;
- f.ReadRestOfFile(Everything);
- f.Close();
-
- // Split it into lines, then process each line as a single recipe:
- AStringVector Split = StringSplit(Everything, "\n");
- int LineNum = 1;
- for (AStringVector::const_iterator itr = Split.begin(); itr != Split.end(); ++itr, ++LineNum)
- {
- // Remove anything after a '#' sign and trim away the whitespace:
- AString Recipe = TrimString(itr->substr(0, itr->find('#')));
- if (Recipe.empty())
- {
- // Empty recipe
- continue;
- }
- AddRecipeLine(LineNum, Recipe);
- } // for itr - Split[]
- LOG("-- %d crafting recipes loaded from crafting.txt --", m_Recipes.size());
-}
-
-
-
-
-void cCraftingRecipes::ClearRecipes(void)
-{
- for (cRecipes::iterator itr = m_Recipes.begin(); itr != m_Recipes.end(); ++itr)
- {
- delete *itr;
- }
- m_Recipes.clear();
-}
-
-
-
-
-
-void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine)
-{
- AStringVector Sides = StringSplit(a_RecipeLine, "=");
- if (Sides.size() != 2)
- {
- LOGWARNING("crafting.txt: line %d: A single '=' was expected, got %d", a_LineNum, (int)Sides.size() - 1);
- return;
- }
-
- std::auto_ptr<cCraftingRecipes::cRecipe> Recipe(new cCraftingRecipes::cRecipe);
-
- // Parse the result:
- AStringVector ResultSplit = StringSplit(Sides[0], ",");
- if (ResultSplit.empty())
- {
- LOGWARNING("crafting.txt: line %d: Result is empty, ignoring the recipe.", a_LineNum);
- return;
- }
- if (!ParseItem(ResultSplit[0], Recipe->m_Result))
- {
- LOGWARNING("crafting.txt: line %d: Cannot parse result item, ignoring the recipe.", a_LineNum);
- return;
- }
- if (ResultSplit.size() > 1)
- {
- Recipe->m_Result.m_ItemCount = atoi(ResultSplit[1].c_str());
- if (Recipe->m_Result.m_ItemCount == 0)
- {
- LOGWARNING("crafting.txt: line %d: Cannot parse result count, ignoring the recipe.", a_LineNum);
- return;
- }
- }
- else
- {
- Recipe->m_Result.m_ItemCount = 1;
- }
-
- // Parse each ingredient:
- AStringVector Ingredients = StringSplit(Sides[1], "|");
- int Num = 1;
- for (AStringVector::const_iterator itr = Ingredients.begin(); itr != Ingredients.end(); ++itr, ++Num)
- {
- if (!ParseIngredient(*itr, Recipe.get()))
- {
- LOGWARNING("crafting.txt: line %d: Cannot parse ingredient #%d, ignoring the recipe.", a_LineNum, Num);
- return;
- }
- } // for itr - Ingredients[]
-
- NormalizeIngredients(Recipe.get());
-
- m_Recipes.push_back(Recipe.release());
-}
-
-
-
-
-
-bool cCraftingRecipes::ParseItem(const AString & a_String, cItem & a_Item)
-{
- // The caller provides error logging
-
- AStringVector Split = StringSplit(a_String, "^");
- if (Split.empty())
- {
- return false;
- }
-
- if (!StringToItem(Split[0], a_Item))
- {
- return false;
- }
-
- if (Split.size() > 1)
- {
- AString Damage = TrimString(Split[1]);
- a_Item.m_ItemHealth = atoi(Damage.c_str());
- if ((a_Item.m_ItemHealth == 0) && (Damage.compare("0") != 0))
- {
- // Parsing the number failed
- return false;
- }
- }
-
- // Success
- return true;
-}
-
-
-
-
-
-bool cCraftingRecipes::ParseIngredient(const AString & a_String, cRecipe * a_Recipe)
-{
- // a_String is in this format: "ItemType^damage, X:Y, X:Y, X:Y..."
- AStringVector Split = StringSplit(a_String, ",");
- if (Split.size() < 2)
- {
- // Not enough split items
- return false;
- }
- cItem Item;
- if (!ParseItem(Split[0], Item))
- {
- return false;
- }
- Item.m_ItemCount = 1;
-
- cCraftingRecipes::cRecipeSlots TempSlots;
- for (AStringVector::const_iterator itr = Split.begin() + 1; itr != Split.end(); ++itr)
- {
- // Parse the coords in the split item:
- AStringVector Coords = StringSplit(*itr, ":");
- if ((Coords.size() == 1) && (TrimString(Coords[0]) == "*"))
- {
- cCraftingRecipes::cRecipeSlot Slot;
- Slot.m_Item = Item;
- Slot.x = -1;
- Slot.y = -1;
- TempSlots.push_back(Slot);
- continue;
- }
- if (Coords.size() != 2)
- {
- return false;
- }
- Coords[0] = TrimString(Coords[0]);
- Coords[1] = TrimString(Coords[1]);
- if (Coords[0].empty() || Coords[1].empty())
- {
- return false;
- }
- cCraftingRecipes::cRecipeSlot Slot;
- Slot.m_Item = Item;
- switch (Coords[0][0])
- {
- case '1': Slot.x = 0; break;
- case '2': Slot.x = 1; break;
- case '3': Slot.x = 2; break;
- case '*': Slot.x = -1; break;
- default:
- {
- return false;
- }
- }
- switch (Coords[1][0])
- {
- case '1': Slot.y = 0; break;
- case '2': Slot.y = 1; break;
- case '3': Slot.y = 2; break;
- case '*': Slot.y = -1; break;
- default:
- {
- return false;
- }
- }
- TempSlots.push_back(Slot);
- } // for itr - Split[]
-
- // Append the ingredients:
- a_Recipe->m_Ingredients.insert(a_Recipe->m_Ingredients.end(), TempSlots.begin(), TempSlots.end());
- return true;
-}
-
-
-
-
-
-void cCraftingRecipes::NormalizeIngredients(cCraftingRecipes::cRecipe * a_Recipe)
-{
- // Calculate the minimum coords for ingredients, excluding the "anywhere" items:
- int MinX = MAX_GRID_WIDTH, MaxX = 0;
- int MinY = MAX_GRID_HEIGHT, MaxY = 0;
- for (cRecipeSlots::const_iterator itr = a_Recipe->m_Ingredients.begin(); itr != a_Recipe->m_Ingredients.end(); ++itr)
- {
- if (itr->x >= 0)
- {
- MinX = std::min(itr->x, MinX);
- MaxX = std::max(itr->x, MaxX);
- }
- if (itr->y >= 0)
- {
- MinY = std::min(itr->y, MinY);
- MaxY = std::max(itr->y, MaxY);
- }
- } // for itr - a_Recipe->m_Ingredients[]
-
- // Move ingredients so that the minimum coords are 0:0
- for (cRecipeSlots::iterator itr = a_Recipe->m_Ingredients.begin(); itr != a_Recipe->m_Ingredients.end(); ++itr)
- {
- if (itr->x >= 0)
- {
- itr->x -= MinX;
- }
- if (itr->y >= 0)
- {
- itr->y -= MinY;
- }
- } // for itr - a_Recipe->m_Ingredients[]
- a_Recipe->m_Width = std::max(MaxX - MinX + 1, 1);
- a_Recipe->m_Height = std::max(MaxY - MinY + 1, 1);
-
- // TODO: Compress two same ingredients with the same coords into a single ingredient with increased item count
-}
-
-
-
-
-
-cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight)
-{
- ASSERT(a_GridWidth <= MAX_GRID_WIDTH);
- ASSERT(a_GridHeight <= MAX_GRID_HEIGHT);
-
- // Get the real bounds of the crafting grid:
- int GridLeft = MAX_GRID_WIDTH, GridTop = MAX_GRID_HEIGHT;
- int GridRight = 0, GridBottom = 0;
- for (int y = 0; y < a_GridHeight; y++ ) for(int x = 0; x < a_GridWidth; x++)
- {
- if (!a_CraftingGrid[x + y * a_GridWidth].IsEmpty())
- {
- GridRight = MAX(x, GridRight);
- GridBottom = MAX(y, GridBottom);
- GridLeft = MIN(x, GridLeft);
- GridTop = MIN(y, GridTop);
- }
- }
- int GridWidth = GridRight - GridLeft + 1;
- int GridHeight = GridBottom - GridTop + 1;
-
- // Search in the possibly minimized grid, but keep the stride:
- const cItem * Grid = a_CraftingGrid + GridLeft + (a_GridWidth * GridTop);
- cRecipe * Recipe = FindRecipeCropped(Grid, GridWidth, GridHeight, a_GridWidth);
- if (Recipe == NULL)
- {
- return NULL;
- }
-
- // A recipe has been found, move it to correspond to the original crafting grid:
- for (cRecipeSlots::iterator itrS = Recipe->m_Ingredients.begin(); itrS != Recipe->m_Ingredients.end(); ++itrS)
- {
- itrS->x += GridLeft;
- itrS->y += GridTop;
- } // for itrS - Recipe->m_Ingredients[]
-
- return Recipe;
-}
-
-
-
-
-
-cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipeCropped(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride)
-{
- for (cRecipes::const_iterator itr = m_Recipes.begin(); itr != m_Recipes.end(); ++itr)
- {
- // Both the crafting grid and the recipes are normalized. The only variable possible is the "anywhere" items.
- // This still means that the "anywhere" item may be the one that is offsetting the grid contents to the right or downwards, so we need to check all possible positions.
- // E. g. recipe "A, * | B, 1:1 | ..." still needs to check grid for B at 2:2 (in case A was in grid's 1:1)
- // Calculate the maximum offsets for this recipe relative to the grid size, and iterate through all combinations of offsets.
- // Also, this calculation automatically filters out recipes that are too large for the current grid - the loop won't be entered at all.
-
- int MaxOfsX = a_GridWidth - (*itr)->m_Width;
- int MaxOfsY = a_GridHeight - (*itr)->m_Height;
- for (int x = 0; x <= MaxOfsX; x++) for (int y = 0; y <= MaxOfsY; y++)
- {
- cRecipe * Recipe = MatchRecipe(a_CraftingGrid, a_GridWidth, a_GridHeight, a_GridStride, *itr, x, y);
- if (Recipe != NULL)
- {
- return Recipe;
- }
- } // for y, for x
- } // for itr - m_Recipes[]
-
- // No matching recipe found
- return NULL;
-}
-
-
-
-
-
-cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride, const cRecipe * a_Recipe, int a_OffsetX, int a_OffsetY)
-{
- // Check the regular items first:
- bool HasMatched[MAX_GRID_WIDTH][MAX_GRID_HEIGHT];
- memset(HasMatched, 0, sizeof(HasMatched));
- for (cRecipeSlots::const_iterator itrS = a_Recipe->m_Ingredients.begin(); itrS != a_Recipe->m_Ingredients.end(); ++itrS)
- {
- if ((itrS->x < 0) || (itrS->y < 0))
- {
- // "Anywhere" item, process later
- continue;
- }
- ASSERT(itrS->x + a_OffsetX < a_GridWidth);
- ASSERT(itrS->y + a_OffsetY < a_GridHeight);
- int GridID = (itrS->x + a_OffsetX) + a_GridStride * (itrS->y + a_OffsetY);
- if (
- (itrS->x >= a_GridWidth) ||
- (itrS->y >= a_GridHeight) ||
- (itrS->m_Item.m_ItemID != a_CraftingGrid[GridID].m_ItemID) || // same item type?
- (itrS->m_Item.m_ItemCount > a_CraftingGrid[GridID].m_ItemCount) || // not enough items
- (
- (itrS->m_Item.m_ItemHealth > 0) && // should compare damage values?
- (itrS->m_Item.m_ItemHealth != a_CraftingGrid[GridID].m_ItemHealth)
- )
- )
- {
- // Doesn't match
- return NULL;
- }
- HasMatched[itrS->x + a_OffsetX][itrS->y + a_OffsetY] = true;
- } // for itrS - Recipe->m_Ingredients[]
-
- // Process the "Anywhere" items now, and only in the cells that haven't matched yet
- // The "anywhere" items are processed on a first-come-first-served basis.
- // Do not use a recipe with one horizontal and one vertical "anywhere" ("*:1, 1:*") as it may not match properly!
- cRecipeSlots MatchedSlots; // Stores the slots of "anywhere" items that have matched, with the match coords
- for (cRecipeSlots::const_iterator itrS = a_Recipe->m_Ingredients.begin(); itrS != a_Recipe->m_Ingredients.end(); ++itrS)
- {
- if ((itrS->x >= 0) && (itrS->y >= 0))
- {
- // Regular item, already processed
- continue;
- }
- int StartX = 0, EndX = a_GridWidth - 1;
- int StartY = 0, EndY = a_GridHeight - 1;
- if (itrS->x >= 0)
- {
- StartX = itrS->x;
- EndX = itrS->x;
- }
- else if (itrS->y >= 0)
- {
- StartY = itrS->y;
- EndY = itrS->y;
- }
- bool Found = false;
- for (int x = StartX; x <= EndX; x++)
- {
- for (int y = StartY; y <= EndY; y++)
- {
- if (HasMatched[x][y])
- {
- // Already matched some other item
- continue;
- }
- int GridIdx = x + a_GridStride * y;
- if (
- (a_CraftingGrid[GridIdx].m_ItemID == itrS->m_Item.m_ItemID) &&
- (
- (itrS->m_Item.m_ItemHealth < 0) || // doesn't want damage comparison
- (itrS->m_Item.m_ItemHealth == a_CraftingGrid[GridIdx].m_ItemHealth) // the damage matches
- )
- )
- {
- HasMatched[x][y] = true;
- Found = true;
- MatchedSlots.push_back(*itrS);
- MatchedSlots.back().x = x;
- MatchedSlots.back().y = y;
- break;
- }
- } // for y
- if (Found)
- {
- break;
- }
- } // for x
- if (!Found)
- {
- return NULL;
- }
- } // for itrS - a_Recipe->m_Ingredients[]
-
- // Check if the whole grid has matched:
- for (int x = 0; x < a_GridWidth; x++) for (int y = 0; y < a_GridHeight; y++)
- {
- if (!HasMatched[x][y] && !a_CraftingGrid[x + a_GridStride * y].IsEmpty())
- {
- // There's an unmatched item in the grid
- return NULL;
- }
- } // for y, for x
-
- // The recipe has matched. Create a copy of the recipe and set its coords to match the crafting grid:
- std::auto_ptr<cRecipe> Recipe(new cRecipe);
- Recipe->m_Result = a_Recipe->m_Result;
- Recipe->m_Width = a_Recipe->m_Width;
- Recipe->m_Height = a_Recipe->m_Height;
- for (cRecipeSlots::const_iterator itrS = a_Recipe->m_Ingredients.begin(); itrS != a_Recipe->m_Ingredients.end(); ++itrS)
- {
- if ((itrS->x < 0) || (itrS->y < 0))
- {
- // "Anywhere" item, process later
- continue;
- }
- Recipe->m_Ingredients.push_back(*itrS);
- }
- Recipe->m_Ingredients.insert(Recipe->m_Ingredients.end(), MatchedSlots.begin(), MatchedSlots.end());
- return Recipe.release();
-}
-
-
-
-
+ +// CraftingRecipes.cpp + +// Interfaces to the cCraftingRecipes class representing the storage of crafting recipes + +#include "Globals.h" +#include "CraftingRecipes.h" +#include "cRoot.h" +#include "cPluginManager.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCraftingGrid: + +cCraftingGrid::cCraftingGrid(int a_Width, int a_Height) : + m_Width(a_Width), + m_Height(a_Height), + m_Items(new cItem[a_Width * a_Height]) +{ +} + + + + + +cCraftingGrid::cCraftingGrid(cItem * a_Items, int a_Width, int a_Height) : + m_Width(a_Width), + m_Height(a_Height), + m_Items(new cItem[a_Width * a_Height]) +{ + for (int i = a_Width * a_Height - 1; i >= 0; i--) + { + m_Items[i] = a_Items[i]; + } +} + + + + + +cCraftingGrid::cCraftingGrid(const cCraftingGrid & a_Original) : + m_Width(a_Original.m_Width), + m_Height(a_Original.m_Height), + m_Items(new cItem[a_Original.m_Width * a_Original.m_Height]) +{ + for (int i = m_Width * m_Height - 1; i >= 0; i--) + { + m_Items[i] = a_Original.m_Items[i]; + } +} + + + + + +cCraftingGrid::~cCraftingGrid() +{ + delete[] m_Items; +} + + + + + +cItem & cCraftingGrid::GetItem(int x, int y) const +{ + // Accessible through scripting, must verify parameters: + if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height)) + { + LOGERROR("Attempted to get an invalid item from a crafting grid: (%d, %d), grid dimensions: (%d, %d).", + x, y, m_Width, m_Height + ); + return m_Items[0]; + } + return m_Items[x + m_Width * y]; +} + + + + + +void cCraftingGrid::SetItem(int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) +{ + // Accessible through scripting, must verify parameters: + if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height)) + { + LOGERROR("Attempted to set an invalid item in a crafting grid: (%d, %d), grid dimensions: (%d, %d).", + x, y, m_Width, m_Height + ); + return; + } + + m_Items[x + m_Width * y] = cItem(a_ItemType, a_ItemCount, a_ItemHealth); +} + + + + + +void cCraftingGrid::SetItem(int x, int y, const cItem & a_Item) +{ + // Accessible through scripting, must verify parameters: + if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height)) + { + LOGERROR("Attempted to set an invalid item in a crafting grid: (%d, %d), grid dimensions: (%d, %d).", + x, y, m_Width, m_Height + ); + return; + } + + m_Items[x + m_Width * y] = a_Item; +} + + + + + +void cCraftingGrid::Clear(void) +{ + for (int y = 0; y < m_Height; y++) for (int x = 0; x < m_Width; x++) + { + m_Items[x + m_Width * y].Empty(); + } +} + + + + + +void cCraftingGrid::ConsumeGrid(const cCraftingGrid & a_Grid) +{ + if ((a_Grid.m_Width != m_Width) || (a_Grid.m_Height != m_Height)) + { + LOGWARNING("Consuming a grid of different dimensions: (%d, %d) vs (%d, %d)", + a_Grid.m_Width, a_Grid.m_Height, m_Width, m_Height + ); + } + int MinX = std::min(a_Grid.m_Width, m_Width); + int MinY = std::min(a_Grid.m_Height, m_Height); + for (int y = 0; y < MinY; y++) for (int x = 0; x < MinX; x++) + { + int ThatIdx = x + a_Grid.m_Width * y; + if (a_Grid.m_Items[ThatIdx].IsEmpty()) + { + continue; + } + int ThisIdx = x + m_Width * y; + if (a_Grid.m_Items[ThatIdx].m_ItemID != m_Items[ThisIdx].m_ItemID) + { + LOGWARNING("Consuming incompatible grids: item at (%d, %d) is %d in grid and %d in ingredients. Item not consumed.", + x, y, m_Items[ThisIdx].m_ItemID, a_Grid.m_Items[ThatIdx].m_ItemID + ); + continue; + } + char NumWantedItems = a_Grid.m_Items[ThatIdx].m_ItemCount; + if (NumWantedItems > m_Items[ThisIdx].m_ItemCount) + { + LOGWARNING("Consuming more items than there actually are in slot (%d, %d), item %d (want %d, have %d). Item zeroed out.", + x, y, m_Items[ThisIdx].m_ItemID, + NumWantedItems, m_Items[ThisIdx].m_ItemCount + ); + NumWantedItems = m_Items[ThisIdx].m_ItemCount; + } + m_Items[ThisIdx].m_ItemCount -= NumWantedItems; + if (m_Items[ThisIdx].m_ItemCount == 0) + { + m_Items[ThisIdx].Clear(); + } + } // for x, for y +} + + + + + +void cCraftingGrid::CopyToItems(cItem * a_Items) const +{ + for (int i = m_Height * m_Width - 1; i >= 0; i--) + { + a_Items[i] = m_Items[i]; + } // for x, for y +} + + + + + +void cCraftingGrid::Dump(void) +{ + for (int y = 0; y < m_Height; y++) for (int x = 0; x < m_Width; x++) + { + int idx = x + m_Width * y; + LOGD("Slot (%d, %d): Type %d, health %d, count %d", + x, y, m_Items[idx].m_ItemID, m_Items[idx].m_ItemHealth, m_Items[idx].m_ItemCount + ); + } +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCraftingRecipe: + +cCraftingRecipe::cCraftingRecipe(const cCraftingGrid & a_CraftingGrid) : + m_Ingredients(a_CraftingGrid) +{ +} + + + + + +void cCraftingRecipe::Clear(void) +{ + m_Ingredients.Clear(); + m_Result.Clear(); +} + + + + + +void cCraftingRecipe::SetResult(ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) +{ + m_Result = cItem(a_ItemType, a_ItemCount, a_ItemHealth); +} + + + + + +void cCraftingRecipe::ConsumeIngredients(cCraftingGrid & a_CraftingGrid) +{ + a_CraftingGrid.ConsumeGrid(m_Ingredients); +} + + + + + +void cCraftingRecipe::Dump(void) +{ + LOGD("Recipe ingredients:"); + m_Ingredients.Dump(); + LOGD("Result: Type %d, health %d, count %d", + m_Result.m_ItemID, m_Result.m_ItemHealth, m_Result.m_ItemCount + ); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCraftingRecipes: + +cCraftingRecipes::cCraftingRecipes(void) +{ + LoadRecipes(); +} + + + + + +cCraftingRecipes::~cCraftingRecipes() +{ + ClearRecipes(); +} + + + + + +void cCraftingRecipes::GetRecipe(const cPlayer * a_Player, const cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe) +{ + // Allow plugins to intercept recipes using a pre-craft hook: + if (cRoot::Get()->GetPluginManager()->CallHookPreCrafting(a_Player, &a_CraftingGrid, &a_Recipe)) + { + return; + } + + // Built-in recipes: + std::auto_ptr<cRecipe> Recipe(FindRecipe(a_CraftingGrid.GetItems(), a_CraftingGrid.GetWidth(), a_CraftingGrid.GetHeight())); + a_Recipe.Clear(); + if (Recipe.get() == NULL) + { + // Allow plugins to intercept a no-recipe-found situation: + cRoot::Get()->GetPluginManager()->CallHookCraftingNoRecipe(a_Player, &a_CraftingGrid, &a_Recipe); + return; + } + for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) + { + a_Recipe.SetIngredient(itr->x, itr->y, itr->m_Item); + } // for itr + a_Recipe.SetResult(Recipe->m_Result); + + // Allow plugins to intercept recipes after they are processed: + cRoot::Get()->GetPluginManager()->CallHookPostCrafting(a_Player, &a_CraftingGrid, &a_Recipe); +} + + + + + +void cCraftingRecipes::LoadRecipes(void) +{ + LOG("-- Loading crafting recipes from crafting.txt --"); + ClearRecipes(); + + // Load the crafting.txt file: + cFile f; + if (!f.Open("crafting.txt", cFile::fmRead)) + { + LOGWARNING("Cannot open file \"crafting.txt\", no crafting recipes will be available!"); + return; + } + AString Everything; + f.ReadRestOfFile(Everything); + f.Close(); + + // Split it into lines, then process each line as a single recipe: + AStringVector Split = StringSplit(Everything, "\n"); + int LineNum = 1; + for (AStringVector::const_iterator itr = Split.begin(); itr != Split.end(); ++itr, ++LineNum) + { + // Remove anything after a '#' sign and trim away the whitespace: + AString Recipe = TrimString(itr->substr(0, itr->find('#'))); + if (Recipe.empty()) + { + // Empty recipe + continue; + } + AddRecipeLine(LineNum, Recipe); + } // for itr - Split[] + LOG("-- %d crafting recipes loaded from crafting.txt --", m_Recipes.size()); +} + + + + +void cCraftingRecipes::ClearRecipes(void) +{ + for (cRecipes::iterator itr = m_Recipes.begin(); itr != m_Recipes.end(); ++itr) + { + delete *itr; + } + m_Recipes.clear(); +} + + + + + +void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine) +{ + AStringVector Sides = StringSplit(a_RecipeLine, "="); + if (Sides.size() != 2) + { + LOGWARNING("crafting.txt: line %d: A single '=' was expected, got %d", a_LineNum, (int)Sides.size() - 1); + return; + } + + std::auto_ptr<cCraftingRecipes::cRecipe> Recipe(new cCraftingRecipes::cRecipe); + + // Parse the result: + AStringVector ResultSplit = StringSplit(Sides[0], ","); + if (ResultSplit.empty()) + { + LOGWARNING("crafting.txt: line %d: Result is empty, ignoring the recipe.", a_LineNum); + return; + } + if (!ParseItem(ResultSplit[0], Recipe->m_Result)) + { + LOGWARNING("crafting.txt: line %d: Cannot parse result item, ignoring the recipe.", a_LineNum); + return; + } + if (ResultSplit.size() > 1) + { + Recipe->m_Result.m_ItemCount = atoi(ResultSplit[1].c_str()); + if (Recipe->m_Result.m_ItemCount == 0) + { + LOGWARNING("crafting.txt: line %d: Cannot parse result count, ignoring the recipe.", a_LineNum); + return; + } + } + else + { + Recipe->m_Result.m_ItemCount = 1; + } + + // Parse each ingredient: + AStringVector Ingredients = StringSplit(Sides[1], "|"); + int Num = 1; + for (AStringVector::const_iterator itr = Ingredients.begin(); itr != Ingredients.end(); ++itr, ++Num) + { + if (!ParseIngredient(*itr, Recipe.get())) + { + LOGWARNING("crafting.txt: line %d: Cannot parse ingredient #%d, ignoring the recipe.", a_LineNum, Num); + return; + } + } // for itr - Ingredients[] + + NormalizeIngredients(Recipe.get()); + + m_Recipes.push_back(Recipe.release()); +} + + + + + +bool cCraftingRecipes::ParseItem(const AString & a_String, cItem & a_Item) +{ + // The caller provides error logging + + AStringVector Split = StringSplit(a_String, "^"); + if (Split.empty()) + { + return false; + } + + if (!StringToItem(Split[0], a_Item)) + { + return false; + } + + if (Split.size() > 1) + { + AString Damage = TrimString(Split[1]); + a_Item.m_ItemHealth = atoi(Damage.c_str()); + if ((a_Item.m_ItemHealth == 0) && (Damage.compare("0") != 0)) + { + // Parsing the number failed + return false; + } + } + + // Success + return true; +} + + + + + +bool cCraftingRecipes::ParseIngredient(const AString & a_String, cRecipe * a_Recipe) +{ + // a_String is in this format: "ItemType^damage, X:Y, X:Y, X:Y..." + AStringVector Split = StringSplit(a_String, ","); + if (Split.size() < 2) + { + // Not enough split items + return false; + } + cItem Item; + if (!ParseItem(Split[0], Item)) + { + return false; + } + Item.m_ItemCount = 1; + + cCraftingRecipes::cRecipeSlots TempSlots; + for (AStringVector::const_iterator itr = Split.begin() + 1; itr != Split.end(); ++itr) + { + // Parse the coords in the split item: + AStringVector Coords = StringSplit(*itr, ":"); + if ((Coords.size() == 1) && (TrimString(Coords[0]) == "*")) + { + cCraftingRecipes::cRecipeSlot Slot; + Slot.m_Item = Item; + Slot.x = -1; + Slot.y = -1; + TempSlots.push_back(Slot); + continue; + } + if (Coords.size() != 2) + { + return false; + } + Coords[0] = TrimString(Coords[0]); + Coords[1] = TrimString(Coords[1]); + if (Coords[0].empty() || Coords[1].empty()) + { + return false; + } + cCraftingRecipes::cRecipeSlot Slot; + Slot.m_Item = Item; + switch (Coords[0][0]) + { + case '1': Slot.x = 0; break; + case '2': Slot.x = 1; break; + case '3': Slot.x = 2; break; + case '*': Slot.x = -1; break; + default: + { + return false; + } + } + switch (Coords[1][0]) + { + case '1': Slot.y = 0; break; + case '2': Slot.y = 1; break; + case '3': Slot.y = 2; break; + case '*': Slot.y = -1; break; + default: + { + return false; + } + } + TempSlots.push_back(Slot); + } // for itr - Split[] + + // Append the ingredients: + a_Recipe->m_Ingredients.insert(a_Recipe->m_Ingredients.end(), TempSlots.begin(), TempSlots.end()); + return true; +} + + + + + +void cCraftingRecipes::NormalizeIngredients(cCraftingRecipes::cRecipe * a_Recipe) +{ + // Calculate the minimum coords for ingredients, excluding the "anywhere" items: + int MinX = MAX_GRID_WIDTH, MaxX = 0; + int MinY = MAX_GRID_HEIGHT, MaxY = 0; + for (cRecipeSlots::const_iterator itr = a_Recipe->m_Ingredients.begin(); itr != a_Recipe->m_Ingredients.end(); ++itr) + { + if (itr->x >= 0) + { + MinX = std::min(itr->x, MinX); + MaxX = std::max(itr->x, MaxX); + } + if (itr->y >= 0) + { + MinY = std::min(itr->y, MinY); + MaxY = std::max(itr->y, MaxY); + } + } // for itr - a_Recipe->m_Ingredients[] + + // Move ingredients so that the minimum coords are 0:0 + for (cRecipeSlots::iterator itr = a_Recipe->m_Ingredients.begin(); itr != a_Recipe->m_Ingredients.end(); ++itr) + { + if (itr->x >= 0) + { + itr->x -= MinX; + } + if (itr->y >= 0) + { + itr->y -= MinY; + } + } // for itr - a_Recipe->m_Ingredients[] + a_Recipe->m_Width = std::max(MaxX - MinX + 1, 1); + a_Recipe->m_Height = std::max(MaxY - MinY + 1, 1); + + // TODO: Compress two same ingredients with the same coords into a single ingredient with increased item count +} + + + + + +cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight) +{ + ASSERT(a_GridWidth <= MAX_GRID_WIDTH); + ASSERT(a_GridHeight <= MAX_GRID_HEIGHT); + + // Get the real bounds of the crafting grid: + int GridLeft = MAX_GRID_WIDTH, GridTop = MAX_GRID_HEIGHT; + int GridRight = 0, GridBottom = 0; + for (int y = 0; y < a_GridHeight; y++ ) for(int x = 0; x < a_GridWidth; x++) + { + if (!a_CraftingGrid[x + y * a_GridWidth].IsEmpty()) + { + GridRight = MAX(x, GridRight); + GridBottom = MAX(y, GridBottom); + GridLeft = MIN(x, GridLeft); + GridTop = MIN(y, GridTop); + } + } + int GridWidth = GridRight - GridLeft + 1; + int GridHeight = GridBottom - GridTop + 1; + + // Search in the possibly minimized grid, but keep the stride: + const cItem * Grid = a_CraftingGrid + GridLeft + (a_GridWidth * GridTop); + cRecipe * Recipe = FindRecipeCropped(Grid, GridWidth, GridHeight, a_GridWidth); + if (Recipe == NULL) + { + return NULL; + } + + // A recipe has been found, move it to correspond to the original crafting grid: + for (cRecipeSlots::iterator itrS = Recipe->m_Ingredients.begin(); itrS != Recipe->m_Ingredients.end(); ++itrS) + { + itrS->x += GridLeft; + itrS->y += GridTop; + } // for itrS - Recipe->m_Ingredients[] + + return Recipe; +} + + + + + +cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipeCropped(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride) +{ + for (cRecipes::const_iterator itr = m_Recipes.begin(); itr != m_Recipes.end(); ++itr) + { + // Both the crafting grid and the recipes are normalized. The only variable possible is the "anywhere" items. + // This still means that the "anywhere" item may be the one that is offsetting the grid contents to the right or downwards, so we need to check all possible positions. + // E. g. recipe "A, * | B, 1:1 | ..." still needs to check grid for B at 2:2 (in case A was in grid's 1:1) + // Calculate the maximum offsets for this recipe relative to the grid size, and iterate through all combinations of offsets. + // Also, this calculation automatically filters out recipes that are too large for the current grid - the loop won't be entered at all. + + int MaxOfsX = a_GridWidth - (*itr)->m_Width; + int MaxOfsY = a_GridHeight - (*itr)->m_Height; + for (int x = 0; x <= MaxOfsX; x++) for (int y = 0; y <= MaxOfsY; y++) + { + cRecipe * Recipe = MatchRecipe(a_CraftingGrid, a_GridWidth, a_GridHeight, a_GridStride, *itr, x, y); + if (Recipe != NULL) + { + return Recipe; + } + } // for y, for x + } // for itr - m_Recipes[] + + // No matching recipe found + return NULL; +} + + + + + +cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride, const cRecipe * a_Recipe, int a_OffsetX, int a_OffsetY) +{ + // Check the regular items first: + bool HasMatched[MAX_GRID_WIDTH][MAX_GRID_HEIGHT]; + memset(HasMatched, 0, sizeof(HasMatched)); + for (cRecipeSlots::const_iterator itrS = a_Recipe->m_Ingredients.begin(); itrS != a_Recipe->m_Ingredients.end(); ++itrS) + { + if ((itrS->x < 0) || (itrS->y < 0)) + { + // "Anywhere" item, process later + continue; + } + ASSERT(itrS->x + a_OffsetX < a_GridWidth); + ASSERT(itrS->y + a_OffsetY < a_GridHeight); + int GridID = (itrS->x + a_OffsetX) + a_GridStride * (itrS->y + a_OffsetY); + if ( + (itrS->x >= a_GridWidth) || + (itrS->y >= a_GridHeight) || + (itrS->m_Item.m_ItemID != a_CraftingGrid[GridID].m_ItemID) || // same item type? + (itrS->m_Item.m_ItemCount > a_CraftingGrid[GridID].m_ItemCount) || // not enough items + ( + (itrS->m_Item.m_ItemHealth > 0) && // should compare damage values? + (itrS->m_Item.m_ItemHealth != a_CraftingGrid[GridID].m_ItemHealth) + ) + ) + { + // Doesn't match + return NULL; + } + HasMatched[itrS->x + a_OffsetX][itrS->y + a_OffsetY] = true; + } // for itrS - Recipe->m_Ingredients[] + + // Process the "Anywhere" items now, and only in the cells that haven't matched yet + // The "anywhere" items are processed on a first-come-first-served basis. + // Do not use a recipe with one horizontal and one vertical "anywhere" ("*:1, 1:*") as it may not match properly! + cRecipeSlots MatchedSlots; // Stores the slots of "anywhere" items that have matched, with the match coords + for (cRecipeSlots::const_iterator itrS = a_Recipe->m_Ingredients.begin(); itrS != a_Recipe->m_Ingredients.end(); ++itrS) + { + if ((itrS->x >= 0) && (itrS->y >= 0)) + { + // Regular item, already processed + continue; + } + int StartX = 0, EndX = a_GridWidth - 1; + int StartY = 0, EndY = a_GridHeight - 1; + if (itrS->x >= 0) + { + StartX = itrS->x; + EndX = itrS->x; + } + else if (itrS->y >= 0) + { + StartY = itrS->y; + EndY = itrS->y; + } + bool Found = false; + for (int x = StartX; x <= EndX; x++) + { + for (int y = StartY; y <= EndY; y++) + { + if (HasMatched[x][y]) + { + // Already matched some other item + continue; + } + int GridIdx = x + a_GridStride * y; + if ( + (a_CraftingGrid[GridIdx].m_ItemID == itrS->m_Item.m_ItemID) && + ( + (itrS->m_Item.m_ItemHealth < 0) || // doesn't want damage comparison + (itrS->m_Item.m_ItemHealth == a_CraftingGrid[GridIdx].m_ItemHealth) // the damage matches + ) + ) + { + HasMatched[x][y] = true; + Found = true; + MatchedSlots.push_back(*itrS); + MatchedSlots.back().x = x; + MatchedSlots.back().y = y; + break; + } + } // for y + if (Found) + { + break; + } + } // for x + if (!Found) + { + return NULL; + } + } // for itrS - a_Recipe->m_Ingredients[] + + // Check if the whole grid has matched: + for (int x = 0; x < a_GridWidth; x++) for (int y = 0; y < a_GridHeight; y++) + { + if (!HasMatched[x][y] && !a_CraftingGrid[x + a_GridStride * y].IsEmpty()) + { + // There's an unmatched item in the grid + return NULL; + } + } // for y, for x + + // The recipe has matched. Create a copy of the recipe and set its coords to match the crafting grid: + std::auto_ptr<cRecipe> Recipe(new cRecipe); + Recipe->m_Result = a_Recipe->m_Result; + Recipe->m_Width = a_Recipe->m_Width; + Recipe->m_Height = a_Recipe->m_Height; + for (cRecipeSlots::const_iterator itrS = a_Recipe->m_Ingredients.begin(); itrS != a_Recipe->m_Ingredients.end(); ++itrS) + { + if ((itrS->x < 0) || (itrS->y < 0)) + { + // "Anywhere" item, process later + continue; + } + Recipe->m_Ingredients.push_back(*itrS); + } + Recipe->m_Ingredients.insert(Recipe->m_Ingredients.end(), MatchedSlots.begin(), MatchedSlots.end()); + return Recipe.release(); +} + + + + diff --git a/source/CraftingRecipes.h b/source/CraftingRecipes.h index 8e4422b1c..25f8fdae2 100644 --- a/source/CraftingRecipes.h +++ b/source/CraftingRecipes.h @@ -1,172 +1,172 @@ -
-// CraftingRecipes.h
-
-// Interfaces to the cCraftingRecipes class representing the storage of crafting recipes
-
-
-
-
-#pragma once
-
-#include "cItem.h"
-
-
-
-
-
-// fwd: cPlayer.h
-class cPlayer;
-
-
-
-
-
-class cCraftingGrid // tolua_export
-{ // tolua_export
-public:
- cCraftingGrid(const cCraftingGrid & a_Original);
- cCraftingGrid(int a_Width, int a_Height); // tolua_export
- cCraftingGrid(cItem * a_Items, int a_Width, int a_Height);
- ~cCraftingGrid();
-
- // tolua_begin
- int GetWidth (void) const {return m_Width; }
- int GetHeight(void) const {return m_Height; }
- cItem & GetItem (int x, int y) const;
- void SetItem (int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth);
- void SetItem (int x, int y, const cItem & a_Item);
- void Clear (void);
-
- /// Removes items in a_Grid from m_Items[] (used by cCraftingRecipe::ConsumeIngredients())
- void ConsumeGrid(const cCraftingGrid & a_Grid);
-
- /// Dumps the entire crafting grid using LOGD()
- void Dump(void);
-
- // tolua_end
-
- cItem * GetItems(void) const {return m_Items; }
-
- /// Copies internal contents into the item array specified. Assumes that the array has the same dimensions as self
- void CopyToItems(cItem * a_Items) const;
-
-protected:
-
- int m_Width;
- int m_Height;
- cItem * m_Items;
-} ; // tolua_export
-
-
-
-
-
-class cCraftingRecipe // tolua_export
-{ // tolua_export
-public:
- cCraftingRecipe(const cCraftingGrid & a_CraftingGrid);
-
- // tolua_begin
- void Clear (void);
- int GetIngredientsWidth (void) const {return m_Ingredients.GetWidth(); }
- int GetIngredientsHeight(void) const {return m_Ingredients.GetHeight(); }
- cItem & GetIngredient (int x, int y) const {return m_Ingredients.GetItem(x, y); }
- const cItem & GetResult (void) const {return m_Result; }
- void SetResult (ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth);
- void SetResult (const cItem & a_Item)
- {
- m_Result = a_Item;
- }
-
- void SetIngredient (int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth)
- {
- m_Ingredients.SetItem(x, y, a_ItemType, a_ItemCount, a_ItemHealth);
- }
-
- void SetIngredient (int x, int y, const cItem & a_Item)
- {
- m_Ingredients.SetItem(x, y, a_Item);
- }
-
- /// Consumes ingredients from the crafting grid specified
- void ConsumeIngredients(cCraftingGrid & a_CraftingGrid);
-
- /// Dumps the entire recipe using LOGD()
- void Dump(void);
- // tolua_end
-
-protected:
-
- cCraftingGrid m_Ingredients; // Adjusted to correspond to the input crafting grid!
- cItem m_Result;
-} ; // tolua_export
-
-
-
-
-
-class cCraftingRecipes
-{
-public:
- static const int MAX_GRID_WIDTH = 3;
- static const int MAX_GRID_HEIGHT = 3;
-
- cCraftingRecipes(void);
- ~cCraftingRecipes();
-
- /// Returns the recipe for current crafting grid. Doesn't modify the grid. Clears a_Recipe if no recipe found.
- void GetRecipe(const cPlayer * a_Player, const cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe);
-
-protected:
-
- struct cRecipeSlot
- {
- cItem m_Item;
- int x, y; // 1..3, or -1 for "any"
- } ;
- typedef std::vector<cRecipeSlot> cRecipeSlots;
-
- /** A single recipe, stored. Each recipe is normalized right after parsing (NormalizeIngredients())
- A normalized recipe starts at (0,0)
- */
- struct cRecipe
- {
- cRecipeSlots m_Ingredients;
- cItem m_Result;
-
- // Size of the regular items in the recipe; "anywhere" items are excluded:
- int m_Width;
- int m_Height;
- } ;
- typedef std::vector<cRecipe *> cRecipes;
-
- cRecipes m_Recipes;
-
- void LoadRecipes(void);
- void ClearRecipes(void);
-
- /// Parses the recipe line and adds it into m_Recipes. a_LineNum is used for diagnostic warnings only
- void AddRecipeLine(int a_LineNum, const AString & a_RecipeLine);
-
- /// Parses an item string in the format "<ItemType>[^<Damage>]", returns true if successful.
- bool ParseItem(const AString & a_String, cItem & a_Item);
-
- /// Parses one ingredient and adds it to the specified recipe. Returns true if successful.
- bool ParseIngredient(const AString & a_String, cRecipe * a_Recipe);
-
- /// Moves the recipe to top-left corner, sets its MinWidth / MinHeight
- void NormalizeIngredients(cRecipe * a_Recipe);
-
- /// Finds a recipe matching the crafting grid. Returns a newly allocated recipe (with all its coords set) or NULL if not found. Caller must delete return value!
- cRecipe * FindRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight);
-
- /// Same as FindRecipe, but the grid is guaranteed to be of minimal dimensions needed
- cRecipe * FindRecipeCropped(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride);
-
- /// Checks if the grid matches the specified recipe, offset by the specified offsets. Returns a matched cRecipe * if so, or NULL if not matching. Caller must delete the return value!
- cRecipe * MatchRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride, const cRecipe * a_Recipe, int a_OffsetX, int a_OffsetY);
-} ;
-
-
-
-
+ +// CraftingRecipes.h + +// Interfaces to the cCraftingRecipes class representing the storage of crafting recipes + + + + +#pragma once + +#include "cItem.h" + + + + + +// fwd: cPlayer.h +class cPlayer; + + + + + +class cCraftingGrid // tolua_export +{ // tolua_export +public: + cCraftingGrid(const cCraftingGrid & a_Original); + cCraftingGrid(int a_Width, int a_Height); // tolua_export + cCraftingGrid(cItem * a_Items, int a_Width, int a_Height); + ~cCraftingGrid(); + + // tolua_begin + int GetWidth (void) const {return m_Width; } + int GetHeight(void) const {return m_Height; } + cItem & GetItem (int x, int y) const; + void SetItem (int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth); + void SetItem (int x, int y, const cItem & a_Item); + void Clear (void); + + /// Removes items in a_Grid from m_Items[] (used by cCraftingRecipe::ConsumeIngredients()) + void ConsumeGrid(const cCraftingGrid & a_Grid); + + /// Dumps the entire crafting grid using LOGD() + void Dump(void); + + // tolua_end + + cItem * GetItems(void) const {return m_Items; } + + /// Copies internal contents into the item array specified. Assumes that the array has the same dimensions as self + void CopyToItems(cItem * a_Items) const; + +protected: + + int m_Width; + int m_Height; + cItem * m_Items; +} ; // tolua_export + + + + + +class cCraftingRecipe // tolua_export +{ // tolua_export +public: + cCraftingRecipe(const cCraftingGrid & a_CraftingGrid); + + // tolua_begin + void Clear (void); + int GetIngredientsWidth (void) const {return m_Ingredients.GetWidth(); } + int GetIngredientsHeight(void) const {return m_Ingredients.GetHeight(); } + cItem & GetIngredient (int x, int y) const {return m_Ingredients.GetItem(x, y); } + const cItem & GetResult (void) const {return m_Result; } + void SetResult (ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth); + void SetResult (const cItem & a_Item) + { + m_Result = a_Item; + } + + void SetIngredient (int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) + { + m_Ingredients.SetItem(x, y, a_ItemType, a_ItemCount, a_ItemHealth); + } + + void SetIngredient (int x, int y, const cItem & a_Item) + { + m_Ingredients.SetItem(x, y, a_Item); + } + + /// Consumes ingredients from the crafting grid specified + void ConsumeIngredients(cCraftingGrid & a_CraftingGrid); + + /// Dumps the entire recipe using LOGD() + void Dump(void); + // tolua_end + +protected: + + cCraftingGrid m_Ingredients; // Adjusted to correspond to the input crafting grid! + cItem m_Result; +} ; // tolua_export + + + + + +class cCraftingRecipes +{ +public: + static const int MAX_GRID_WIDTH = 3; + static const int MAX_GRID_HEIGHT = 3; + + cCraftingRecipes(void); + ~cCraftingRecipes(); + + /// Returns the recipe for current crafting grid. Doesn't modify the grid. Clears a_Recipe if no recipe found. + void GetRecipe(const cPlayer * a_Player, const cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe); + +protected: + + struct cRecipeSlot + { + cItem m_Item; + int x, y; // 1..3, or -1 for "any" + } ; + typedef std::vector<cRecipeSlot> cRecipeSlots; + + /** A single recipe, stored. Each recipe is normalized right after parsing (NormalizeIngredients()) + A normalized recipe starts at (0,0) + */ + struct cRecipe + { + cRecipeSlots m_Ingredients; + cItem m_Result; + + // Size of the regular items in the recipe; "anywhere" items are excluded: + int m_Width; + int m_Height; + } ; + typedef std::vector<cRecipe *> cRecipes; + + cRecipes m_Recipes; + + void LoadRecipes(void); + void ClearRecipes(void); + + /// Parses the recipe line and adds it into m_Recipes. a_LineNum is used for diagnostic warnings only + void AddRecipeLine(int a_LineNum, const AString & a_RecipeLine); + + /// Parses an item string in the format "<ItemType>[^<Damage>]", returns true if successful. + bool ParseItem(const AString & a_String, cItem & a_Item); + + /// Parses one ingredient and adds it to the specified recipe. Returns true if successful. + bool ParseIngredient(const AString & a_String, cRecipe * a_Recipe); + + /// Moves the recipe to top-left corner, sets its MinWidth / MinHeight + void NormalizeIngredients(cRecipe * a_Recipe); + + /// Finds a recipe matching the crafting grid. Returns a newly allocated recipe (with all its coords set) or NULL if not found. Caller must delete return value! + cRecipe * FindRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight); + + /// Same as FindRecipe, but the grid is guaranteed to be of minimal dimensions needed + cRecipe * FindRecipeCropped(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride); + + /// Checks if the grid matches the specified recipe, offset by the specified offsets. Returns a matched cRecipe * if so, or NULL if not matching. Caller must delete the return value! + cRecipe * MatchRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride, const cRecipe * a_Recipe, int a_OffsetX, int a_OffsetY); +} ; + + + + diff --git a/source/Defines.h b/source/Defines.h index fae466e4a..d0279875f 100644 --- a/source/Defines.h +++ b/source/Defines.h @@ -1,293 +1,293 @@ -#pragma once
-
-#include "BlockID.h"
-
-//tolua_begin
-// emissive blocks
-extern unsigned char g_BlockLightValue[];
-// whether blocks allow spreading
-extern unsigned char g_BlockSpreadLightFalloff[];
-// whether blocks are transparent (light can shine though)
-extern bool g_BlockTransparent[];
-// one hit break blocks
-extern bool g_BlockOneHitDig[];
-//tolua_end
-
-//--DO NOT DELETE THIS COMMENT-- //tolua_export
-
-
-
-
-
-inline bool IsValidBlock( int a_BlockID ) //tolua_export
-{ //tolua_export
- if( a_BlockID > -1 &&
- a_BlockID <= 126 && //items to 109 are valid for Beta1.8.1.. 1.2.5 is up to 126
- //a_BlockID != 29 && allow pistons
- //a_BlockID != 33 && allow pistons
- a_BlockID != 34 &&
- a_BlockID != 36 )
- {
- return true;
- }
- return false;
-} //tolua_export
-
-
-
-
-
-// Was old :o
-// Changed to fit the style ;)
-inline bool IsValidItem( int a_ItemID ) //tolua_export
-{ //tolua_export
- if( (a_ItemID >= 256 && a_ItemID <= 388)
- || (a_ItemID >= 2256 && a_ItemID <= 2266) )
- {
- return true;
- }
-
- if( a_ItemID == 0 )
- return false;
-
- return IsValidBlock( a_ItemID );
-} //tolua_export
-
-
-
-
-
-inline bool IsBlockWater(char a_BlockID)
-{
- return (a_BlockID == E_BLOCK_WATER || a_BlockID == E_BLOCK_STATIONARY_WATER);
-}
-
-
-
-
-
-inline bool IsBlockLava(char a_BlockID)
-{
- return (a_BlockID == E_BLOCK_LAVA || a_BlockID == E_BLOCK_STATIONARY_LAVA);
-}
-
-
-
-
-
-inline void AddDirection( int & a_X, int & a_Y, int & a_Z, char a_Direction, bool a_bInverse = false )
-{
- if( !a_bInverse )
- {
- switch( a_Direction )
- {
- case 0:
- a_Y--;
- break;
- case 1:
- a_Y++;
- break;
- case 2:
- a_Z--;
- break;
- case 3:
- a_Z++;
- break;
- case 4:
- a_X--;
- break;
- case 5:
- a_X++;
- break;
- };
- }
- else
- {
- switch( a_Direction ) // other way around
- {
- case 0:
- a_Y++;
- break;
- case 1:
- a_Y--;
- break;
- case 2:
- a_Z++;
- break;
- case 3:
- a_Z--;
- break;
- case 4:
- a_X++;
- break;
- case 5:
- a_X--;
- break;
- };
- }
-}
-
-
-
-
-
-inline void AddDirection( int & a_X, unsigned char & a_Y, int & a_Z, char a_Direction, bool a_bInverse = false ) //tolua_export
-{//tolua_export
- int Y = a_Y;
- AddDirection( a_X, Y, a_Z, a_Direction, a_bInverse );
- if( Y < 0 ) a_Y = 0;
- else if( Y > 255 ) a_Y = 255;
- else a_Y = (unsigned char)Y;
-}//tolua_export
-
-
-
-
-
-#include <math.h>
-#define PI 3.14159265358979323846264338327950288419716939937510582097494459072381640628620899862803482534211706798f
-#define MIN(a,b) (((a)>(b))?(b):(a))
-#define MAX(a,b) (((a)>(b))?(a):(b))
-inline void EulerToVector( float a_Pan, float a_Pitch, float & a_X, float & a_Y, float & a_Z )
-{
- // a_X = sinf ( a_Pan / 180 * PI ) * cosf ( a_Pitch / 180 * PI );
- // a_Y = -sinf ( a_Pitch / 180 * PI );
- // a_Z = -cosf ( a_Pan / 180 * PI ) * cosf ( a_Pitch / 180 * PI );
- a_X = cos(a_Pan / 180 * PI)*cos(a_Pitch / 180 * PI);
- a_Y = sin(a_Pan / 180 * PI)*cos(a_Pitch / 180 * PI);
- a_Z = sin(a_Pitch / 180 * PI);
-}
-
-
-
-
-
-inline void VectorToEuler( float a_X, float a_Y, float a_Z, float & a_Pan, float & a_Pitch )
-{
- if( a_X != 0 )
- a_Pan = atan2( a_Z, a_X ) * 180 / PI - 90;
- else
- a_Pan = 0;
- a_Pitch = atan2(a_Y, sqrtf((a_X * a_X) + (a_Z * a_Z))) * 180 / PI;
-}
-
-
-
-
-
-inline float GetSignf( float a_Val )
-{
- return (a_Val < 0.f)?-1.f:1.f;
-}
-
-
-
-
-
-inline float GetSpecialSignf( float a_Val )
-{
- return (a_Val <= 0.f)?-1.f:1.f;
-}
-
-
-
-
-//tolua_begin
-namespace ItemCategory
-{
- inline bool IsPickaxe(ENUM_ITEM_ID a_ItemID)
- {
- return (a_ItemID == E_ITEM_WOODEN_PICKAXE)
- || (a_ItemID == E_ITEM_STONE_PICKAXE)
- || (a_ItemID == E_ITEM_IRON_PICKAXE)
- || (a_ItemID == E_ITEM_GOLD_PICKAXE)
- || (a_ItemID == E_ITEM_DIAMOND_PICKAXE);
- }
-
-
-
- inline bool IsAxe(ENUM_ITEM_ID a_ItemID)
- {
- return (a_ItemID == E_ITEM_WOODEN_AXE)
- || (a_ItemID == E_ITEM_STONE_AXE)
- || (a_ItemID == E_ITEM_IRON_AXE)
- || (a_ItemID == E_ITEM_GOLD_AXE)
- || (a_ItemID == E_ITEM_DIAMOND_AXE);
- }
-
-
-
- inline bool IsSword(ENUM_ITEM_ID a_ItemID)
- {
- return (a_ItemID == E_ITEM_WOODEN_SWORD)
- || (a_ItemID == E_ITEM_STONE_SWORD)
- || (a_ItemID == E_ITEM_IRON_SWORD)
- || (a_ItemID == E_ITEM_GOLD_SWORD)
- || (a_ItemID == E_ITEM_DIAMOND_SWORD);
- }
-
-
-
- inline bool IsHoe(ENUM_ITEM_ID a_ItemID)
- {
- return (a_ItemID == E_ITEM_WOODEN_HOE)
- || (a_ItemID == E_ITEM_STONE_HOE)
- || (a_ItemID == E_ITEM_IRON_HOE)
- || (a_ItemID == E_ITEM_GOLD_HOE)
- || (a_ItemID == E_ITEM_DIAMOND_HOE);
- }
-
-
-
- inline bool IsShovel(ENUM_ITEM_ID a_ItemID)
- {
- return (a_ItemID == E_ITEM_WOODEN_SHOVEL)
- || (a_ItemID == E_ITEM_STONE_SHOVEL)
- || (a_ItemID == E_ITEM_IRON_SHOVEL)
- || (a_ItemID == E_ITEM_GOLD_SHOVEL)
- || (a_ItemID == E_ITEM_DIAMOND_SHOVEL);
- }
-
-
-
- inline bool IsTool(ENUM_ITEM_ID a_ItemID)
- {
- return IsPickaxe( a_ItemID )
- || IsAxe ( a_ItemID )
- || IsSword ( a_ItemID )
- || IsHoe ( a_ItemID )
- || IsShovel ( a_ItemID );
- }
-}
-//tolua_end
-
-
-
-
-//tolua_begin
-enum eGameMode
-{
- eGameMode_Survival = 0,
- eGameMode_Creative = 1,
-};
-
-
-
-
-
-enum eWeather
-{
- eWeather_Sunny = 0,
- eWeather_Rain = 1,
- eWeather_ThunderStorm = 2,
-
-};
-
-
-
-
-//tolua_end
-
-
-
-
+#pragma once + +#include "BlockID.h" + +//tolua_begin +// emissive blocks +extern unsigned char g_BlockLightValue[]; +// whether blocks allow spreading +extern unsigned char g_BlockSpreadLightFalloff[]; +// whether blocks are transparent (light can shine though) +extern bool g_BlockTransparent[]; +// one hit break blocks +extern bool g_BlockOneHitDig[]; +//tolua_end + +//--DO NOT DELETE THIS COMMENT-- //tolua_export + + + + + +inline bool IsValidBlock( int a_BlockID ) //tolua_export +{ //tolua_export + if( a_BlockID > -1 && + a_BlockID <= 126 && //items to 109 are valid for Beta1.8.1.. 1.2.5 is up to 126 + //a_BlockID != 29 && allow pistons + //a_BlockID != 33 && allow pistons + a_BlockID != 34 && + a_BlockID != 36 ) + { + return true; + } + return false; +} //tolua_export + + + + + +// Was old :o +// Changed to fit the style ;) +inline bool IsValidItem( int a_ItemID ) //tolua_export +{ //tolua_export + if( (a_ItemID >= 256 && a_ItemID <= 388) + || (a_ItemID >= 2256 && a_ItemID <= 2266) ) + { + return true; + } + + if( a_ItemID == 0 ) + return false; + + return IsValidBlock( a_ItemID ); +} //tolua_export + + + + + +inline bool IsBlockWater(char a_BlockID) +{ + return (a_BlockID == E_BLOCK_WATER || a_BlockID == E_BLOCK_STATIONARY_WATER); +} + + + + + +inline bool IsBlockLava(char a_BlockID) +{ + return (a_BlockID == E_BLOCK_LAVA || a_BlockID == E_BLOCK_STATIONARY_LAVA); +} + + + + + +inline void AddDirection( int & a_X, int & a_Y, int & a_Z, char a_Direction, bool a_bInverse = false ) +{ + if( !a_bInverse ) + { + switch( a_Direction ) + { + case 0: + a_Y--; + break; + case 1: + a_Y++; + break; + case 2: + a_Z--; + break; + case 3: + a_Z++; + break; + case 4: + a_X--; + break; + case 5: + a_X++; + break; + }; + } + else + { + switch( a_Direction ) // other way around + { + case 0: + a_Y++; + break; + case 1: + a_Y--; + break; + case 2: + a_Z++; + break; + case 3: + a_Z--; + break; + case 4: + a_X++; + break; + case 5: + a_X--; + break; + }; + } +} + + + + + +inline void AddDirection( int & a_X, unsigned char & a_Y, int & a_Z, char a_Direction, bool a_bInverse = false ) //tolua_export +{//tolua_export + int Y = a_Y; + AddDirection( a_X, Y, a_Z, a_Direction, a_bInverse ); + if( Y < 0 ) a_Y = 0; + else if( Y > 255 ) a_Y = 255; + else a_Y = (unsigned char)Y; +}//tolua_export + + + + + +#include <math.h> +#define PI 3.14159265358979323846264338327950288419716939937510582097494459072381640628620899862803482534211706798f +#define MIN(a,b) (((a)>(b))?(b):(a)) +#define MAX(a,b) (((a)>(b))?(a):(b)) +inline void EulerToVector( float a_Pan, float a_Pitch, float & a_X, float & a_Y, float & a_Z ) +{ + // a_X = sinf ( a_Pan / 180 * PI ) * cosf ( a_Pitch / 180 * PI ); + // a_Y = -sinf ( a_Pitch / 180 * PI ); + // a_Z = -cosf ( a_Pan / 180 * PI ) * cosf ( a_Pitch / 180 * PI ); + a_X = cos(a_Pan / 180 * PI)*cos(a_Pitch / 180 * PI); + a_Y = sin(a_Pan / 180 * PI)*cos(a_Pitch / 180 * PI); + a_Z = sin(a_Pitch / 180 * PI); +} + + + + + +inline void VectorToEuler( float a_X, float a_Y, float a_Z, float & a_Pan, float & a_Pitch ) +{ + if( a_X != 0 ) + a_Pan = atan2( a_Z, a_X ) * 180 / PI - 90; + else + a_Pan = 0; + a_Pitch = atan2(a_Y, sqrtf((a_X * a_X) + (a_Z * a_Z))) * 180 / PI; +} + + + + + +inline float GetSignf( float a_Val ) +{ + return (a_Val < 0.f)?-1.f:1.f; +} + + + + + +inline float GetSpecialSignf( float a_Val ) +{ + return (a_Val <= 0.f)?-1.f:1.f; +} + + + + +//tolua_begin +namespace ItemCategory +{ + inline bool IsPickaxe(ENUM_ITEM_ID a_ItemID) + { + return (a_ItemID == E_ITEM_WOODEN_PICKAXE) + || (a_ItemID == E_ITEM_STONE_PICKAXE) + || (a_ItemID == E_ITEM_IRON_PICKAXE) + || (a_ItemID == E_ITEM_GOLD_PICKAXE) + || (a_ItemID == E_ITEM_DIAMOND_PICKAXE); + } + + + + inline bool IsAxe(ENUM_ITEM_ID a_ItemID) + { + return (a_ItemID == E_ITEM_WOODEN_AXE) + || (a_ItemID == E_ITEM_STONE_AXE) + || (a_ItemID == E_ITEM_IRON_AXE) + || (a_ItemID == E_ITEM_GOLD_AXE) + || (a_ItemID == E_ITEM_DIAMOND_AXE); + } + + + + inline bool IsSword(ENUM_ITEM_ID a_ItemID) + { + return (a_ItemID == E_ITEM_WOODEN_SWORD) + || (a_ItemID == E_ITEM_STONE_SWORD) + || (a_ItemID == E_ITEM_IRON_SWORD) + || (a_ItemID == E_ITEM_GOLD_SWORD) + || (a_ItemID == E_ITEM_DIAMOND_SWORD); + } + + + + inline bool IsHoe(ENUM_ITEM_ID a_ItemID) + { + return (a_ItemID == E_ITEM_WOODEN_HOE) + || (a_ItemID == E_ITEM_STONE_HOE) + || (a_ItemID == E_ITEM_IRON_HOE) + || (a_ItemID == E_ITEM_GOLD_HOE) + || (a_ItemID == E_ITEM_DIAMOND_HOE); + } + + + + inline bool IsShovel(ENUM_ITEM_ID a_ItemID) + { + return (a_ItemID == E_ITEM_WOODEN_SHOVEL) + || (a_ItemID == E_ITEM_STONE_SHOVEL) + || (a_ItemID == E_ITEM_IRON_SHOVEL) + || (a_ItemID == E_ITEM_GOLD_SHOVEL) + || (a_ItemID == E_ITEM_DIAMOND_SHOVEL); + } + + + + inline bool IsTool(ENUM_ITEM_ID a_ItemID) + { + return IsPickaxe( a_ItemID ) + || IsAxe ( a_ItemID ) + || IsSword ( a_ItemID ) + || IsHoe ( a_ItemID ) + || IsShovel ( a_ItemID ); + } +} +//tolua_end + + + + +//tolua_begin +enum eGameMode +{ + eGameMode_Survival = 0, + eGameMode_Creative = 1, +}; + + + + + +enum eWeather +{ + eWeather_Sunny = 0, + eWeather_Rain = 1, + eWeather_ThunderStorm = 2, + +}; + + + + +//tolua_end + + + + diff --git a/source/Endianness.h b/source/Endianness.h index d2c6a8a0a..86eb369f5 100644 --- a/source/Endianness.h +++ b/source/Endianness.h @@ -1,70 +1,70 @@ -
-#pragma once
-
-
-
-
-
-// Changes endianness
-inline unsigned long long HostToNetwork8(const void* a_Value )
-{
- unsigned long long __HostToNetwork8;
- memcpy( &__HostToNetwork8, a_Value, sizeof( __HostToNetwork8 ) );
- __HostToNetwork8 = (( ( (unsigned long long)htonl((u_long)__HostToNetwork8) ) << 32) + htonl(__HostToNetwork8 >> 32));
- return __HostToNetwork8;
-}
-
-
-
-
-
-inline unsigned int HostToNetwork4(const void* a_Value )
-{
- unsigned int __HostToNetwork4;
- memcpy( &__HostToNetwork4, a_Value, sizeof( __HostToNetwork4 ) );
- __HostToNetwork4 = ntohl( __HostToNetwork4 );
- return __HostToNetwork4;
-}
-
-
-
-
-
-inline double NetworkToHostDouble8(const void* a_Value )
-{
-#define ntohll(x) ((((unsigned long long)ntohl((u_long)x)) << 32) + ntohl(x >> 32))
- unsigned long long buf = 0;//(*(unsigned long long*)a_Value);
- memcpy( &buf, a_Value, 8 );
- buf = ntohll(buf);
- double x;
- memcpy(&x, &buf, sizeof(double));
- return x;
-}
-
-
-
-
-
-inline long long NetworkToHostLong8(const void * a_Value )
-{
- unsigned long long buf = *(unsigned long long*)a_Value;
- buf = ntohll(buf);
- return *reinterpret_cast<long long *>(&buf);
-}
-
-
-
-
-
-inline float NetworkToHostFloat4(const void* a_Value )
-{
- u_long buf = *(u_long*)a_Value;
- buf = ntohl( buf );
- float x = 0;
- memcpy( &x, &buf, sizeof(float) );
- return x;
-}
-
-
-
-
+ +#pragma once + + + + + +// Changes endianness +inline unsigned long long HostToNetwork8(const void* a_Value ) +{ + unsigned long long __HostToNetwork8; + memcpy( &__HostToNetwork8, a_Value, sizeof( __HostToNetwork8 ) ); + __HostToNetwork8 = (( ( (unsigned long long)htonl((u_long)__HostToNetwork8) ) << 32) + htonl(__HostToNetwork8 >> 32)); + return __HostToNetwork8; +} + + + + + +inline unsigned int HostToNetwork4(const void* a_Value ) +{ + unsigned int __HostToNetwork4; + memcpy( &__HostToNetwork4, a_Value, sizeof( __HostToNetwork4 ) ); + __HostToNetwork4 = ntohl( __HostToNetwork4 ); + return __HostToNetwork4; +} + + + + + +inline double NetworkToHostDouble8(const void* a_Value ) +{ +#define ntohll(x) ((((unsigned long long)ntohl((u_long)x)) << 32) + ntohl(x >> 32)) + unsigned long long buf = 0;//(*(unsigned long long*)a_Value); + memcpy( &buf, a_Value, 8 ); + buf = ntohll(buf); + double x; + memcpy(&x, &buf, sizeof(double)); + return x; +} + + + + + +inline long long NetworkToHostLong8(const void * a_Value ) +{ + unsigned long long buf = *(unsigned long long*)a_Value; + buf = ntohll(buf); + return *reinterpret_cast<long long *>(&buf); +} + + + + + +inline float NetworkToHostFloat4(const void* a_Value ) +{ + u_long buf = *(u_long*)a_Value; + buf = ntohl( buf ); + float x = 0; + memcpy( &x, &buf, sizeof(float) ); + return x; +} + + + + diff --git a/source/FastNBT.cpp b/source/FastNBT.cpp index 9854fe3bc..773aecf62 100644 --- a/source/FastNBT.cpp +++ b/source/FastNBT.cpp @@ -1,530 +1,530 @@ -
-// FastNBT.cpp
-
-// Implements the fast NBT parser and writer
-
-#include "Globals.h"
-#include "FastNBT.h"
-
-
-
-
-
-#define RETURN_FALSE_IF_FALSE(X) do { if (!X) return false; } while (0)
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cParsedNBT:
-
-#define NEEDBYTES(N) \
- if (m_Length - m_Pos < N) \
- { \
- return false; \
- }
-
-
-
-
-
-cParsedNBT::cParsedNBT(const char * a_Data, int a_Length) :
- m_Data(a_Data),
- m_Length(a_Length),
- m_Pos(0)
-{
- m_IsValid = Parse();
-}
-
-
-
-
-
-bool cParsedNBT::Parse(void)
-{
- if (m_Length < 3)
- {
- // Data too short
- return false;
- }
- if (m_Data[0] != TAG_Compound)
- {
- // The top-level tag must be a Compound
- return false;
- }
-
- m_Tags.reserve(200);
-
- m_Tags.push_back(cFastNBTTag(TAG_Compound, -1));
-
- m_Pos = 1;
-
- RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength));
- RETURN_FALSE_IF_FALSE(ReadCompound());
-
- return true;
-}
-
-
-
-
-
-bool cParsedNBT::ReadString(int & a_StringStart, int & a_StringLen)
-{
- NEEDBYTES(2);
- a_StringStart = m_Pos + 2;
- a_StringLen = ntohs(*((short *)(m_Data + m_Pos)));
- if (a_StringLen < 0)
- {
- // Invalid string length
- return false;
- }
- m_Pos += 2 + a_StringLen;
- return true;
-}
-
-
-
-
-
-bool cParsedNBT::ReadCompound(void)
-{
- // Reads the latest tag as a compound
- int ParentIdx = m_Tags.size() - 1;
- int PrevSibling = -1;
- while (true)
- {
- NEEDBYTES(1);
- eTagType TagType = (eTagType)(m_Data[m_Pos]);
- m_Pos++;
- if (TagType == TAG_End)
- {
- break;
- }
- m_Tags.push_back(cFastNBTTag(TagType, ParentIdx, PrevSibling));
- if (PrevSibling >= 0)
- {
- m_Tags[PrevSibling].m_NextSibling = m_Tags.size() - 1;
- }
- else
- {
- m_Tags[ParentIdx].m_FirstChild = m_Tags.size() - 1;
- }
- PrevSibling = m_Tags.size() - 1;
- RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength));
- RETURN_FALSE_IF_FALSE(ReadTag());
- } // while (true)
- m_Tags[ParentIdx].m_LastChild = PrevSibling;
- return true;
-}
-
-
-
-
-
-bool cParsedNBT::ReadList(eTagType a_ChildrenType)
-{
- // Reads the latest tag as a list of items of type a_ChildrenType
-
- // Read the count:
- NEEDBYTES(4);
- int Count = ntohl(*((int *)(m_Data + m_Pos)));
- m_Pos += 4;
- if (Count < 0)
- {
- return false;
- }
-
- // Read items:
- int ParentIdx = m_Tags.size() - 1;
- int PrevSibling = -1;
- for (int i = 0; i < Count; i++)
- {
- m_Tags.push_back(cFastNBTTag(a_ChildrenType, ParentIdx, PrevSibling));
- if (PrevSibling >= 0)
- {
- m_Tags[PrevSibling].m_NextSibling = m_Tags.size() - 1;
- }
- else
- {
- m_Tags[ParentIdx].m_FirstChild = m_Tags.size() - 1;
- }
- PrevSibling = m_Tags.size() - 1;
- RETURN_FALSE_IF_FALSE(ReadTag());
- } // for (i)
- m_Tags[ParentIdx].m_LastChild = PrevSibling;
- return true;
-}
-
-
-
-
-
-#define CASE_SIMPLE_TAG(TAGTYPE, LEN) \
- case TAG_##TAGTYPE: \
- { \
- NEEDBYTES(LEN); \
- Tag.m_DataStart = m_Pos; \
- Tag.m_DataLength = LEN; \
- m_Pos += LEN; \
- return true; \
- }
-
-bool cParsedNBT::ReadTag(void)
-{
- cFastNBTTag & Tag = m_Tags.back();
- switch (Tag.m_Type)
- {
- CASE_SIMPLE_TAG(Byte, 1)
- CASE_SIMPLE_TAG(Short, 2)
- CASE_SIMPLE_TAG(Int, 4)
- CASE_SIMPLE_TAG(Long, 8)
- CASE_SIMPLE_TAG(Float, 4)
- CASE_SIMPLE_TAG(Double, 8)
-
- case TAG_String:
- {
- return ReadString(Tag.m_DataStart, Tag.m_DataLength);
- }
-
- case TAG_ByteArray:
- {
- NEEDBYTES(4);
- int len = ntohl(*((int *)(m_Data + m_Pos)));
- m_Pos += 4;
- if (len < 0)
- {
- // Invalid length
- return false;
- }
- NEEDBYTES(len);
- Tag.m_DataLength = len;
- Tag.m_DataStart = m_Pos;
- m_Pos += len;
- return true;
- }
-
- case TAG_List:
- {
- NEEDBYTES(1);
- eTagType ItemType = (eTagType)m_Data[m_Pos];
- m_Pos++;
- RETURN_FALSE_IF_FALSE(ReadList(ItemType));
- return true;
- }
-
- case TAG_Compound:
- {
- RETURN_FALSE_IF_FALSE(ReadCompound());
- return true;
- }
-
- case TAG_IntArray:
- {
- NEEDBYTES(4);
- int len = ntohl(*((int *)(m_Data + m_Pos)));
- m_Pos += 4;
- if (len < 0)
- {
- // Invalid length
- return false;
- }
- len *= 4;
- NEEDBYTES(len);
- Tag.m_DataLength = len;
- Tag.m_DataStart = m_Pos;
- m_Pos += len;
- return true;
- }
-
- default:
- {
- ASSERT(!"Unhandled NBT tag type");
- return false;
- }
- } // switch (iType)
-}
-
-#undef CASE_SIMPLE_TAG
-
-
-
-
-
-int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength) const
-{
- if (a_Tag < 0)
- {
- return -1;
- }
- if (m_Tags[a_Tag].m_Type != TAG_Compound)
- {
- return -1;
- }
-
- if (a_NameLength == 0)
- {
- a_NameLength = strlen(a_Name);
- }
- for (int Child = m_Tags[a_Tag].m_FirstChild; Child != -1; Child = m_Tags[Child].m_NextSibling)
- {
- if (
- (m_Tags[Child].m_NameLength == a_NameLength) &&
- (memcmp(m_Data + m_Tags[Child].m_NameStart, a_Name, a_NameLength) == 0)
- )
- {
- return Child;
- }
- } // for Child - children of a_Tag
- return -1;
-}
-
-
-
-
-
-int cParsedNBT::FindTagByPath(int a_Tag, const AString & a_Path) const
-{
- if (a_Tag < 0)
- {
- return -1;
- }
- size_t Begin = 0;
- size_t Length = a_Path.length();
- int Tag = a_Tag;
- for (size_t i = 0; i < Length; i++)
- {
- if (a_Path[i] != '\\')
- {
- continue;
- }
- Tag = FindChildByName(Tag, a_Path.c_str() + Begin, i - Begin - 1);
- if (Tag < 0)
- {
- return -1;
- }
- Begin = i + 1;
- } // for i - a_Path[]
-
- if (Begin < Length)
- {
- Tag = FindChildByName(Tag, a_Path.c_str() + Begin, Length - Begin);
- }
- return Tag;
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cFastNBTWriter:
-
-cFastNBTWriter::cFastNBTWriter(void) :
- m_CurrentStack(0)
-{
- m_Stack[0].m_Type = TAG_Compound;
- m_Result.reserve(100 * 1024);
- m_Result.push_back(TAG_Compound);
- WriteString("", 0);
-}
-
-
-
-
-
-void cFastNBTWriter::BeginCompound(const AString & a_Name)
-{
- if (m_CurrentStack >= MAX_STACK)
- {
- ASSERT(!"Stack overflow");
- return;
- }
-
- TagCommon(a_Name, TAG_Compound);
-
- ++m_CurrentStack;
- m_Stack[m_CurrentStack].m_Type = TAG_Compound;
-}
-
-
-
-
-
-void cFastNBTWriter::EndCompound(void)
-{
- ASSERT(m_CurrentStack > 0);
- ASSERT(IsStackTopCompound());
-
- m_Result.push_back(TAG_End);
- --m_CurrentStack;
-}
-
-
-
-
-
-void cFastNBTWriter::BeginList(const AString & a_Name, eTagType a_ChildrenType)
-{
- if (m_CurrentStack >= MAX_STACK)
- {
- ASSERT(!"Stack overflow");
- return;
- }
-
- TagCommon(a_Name, TAG_List);
-
- m_Result.push_back((char)a_ChildrenType);
- m_Result.append(4, (char)0);
-
- ++m_CurrentStack;
- m_Stack[m_CurrentStack].m_Type = TAG_List;
- m_Stack[m_CurrentStack].m_Pos = m_Result.size() - 4;
- m_Stack[m_CurrentStack].m_Count = 0;
-}
-
-
-
-
-
-void cFastNBTWriter::EndList(void)
-{
- ASSERT(m_CurrentStack > 0);
- ASSERT(m_Stack[m_CurrentStack].m_Type == TAG_List);
-
- // Update the list count:
- *((int *)(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos)) = htonl(m_Stack[m_CurrentStack].m_Count);
-
- --m_CurrentStack;
-}
-
-
-
-
-
-void cFastNBTWriter::AddByte(const AString & a_Name, unsigned char a_Value)
-{
- TagCommon(a_Name, TAG_Byte);
- m_Result.push_back(a_Value);
-}
-
-
-
-
-
-void cFastNBTWriter::AddShort(const AString & a_Name, Int16 a_Value)
-{
- TagCommon(a_Name, TAG_Short);
- Int16 Value = htons(a_Value);
- m_Result.append((const char *)&Value, 2);
-}
-
-
-
-
-
-void cFastNBTWriter::AddInt(const AString & a_Name, Int32 a_Value)
-{
- TagCommon(a_Name, TAG_Int);
- Int32 Value = htonl(a_Value);
- m_Result.append((const char *)&Value, 4);
-}
-
-
-
-
-
-void cFastNBTWriter::AddLong(const AString & a_Name, Int64 a_Value)
-{
- TagCommon(a_Name, TAG_Long);
- Int64 Value = HostToNetwork8(&a_Value);
- m_Result.append((const char *)&Value, 8);
-}
-
-
-
-
-
-void cFastNBTWriter::AddFloat(const AString & a_Name, float a_Value)
-{
- TagCommon(a_Name, TAG_Float);
- Int32 Value = HostToNetwork4(&a_Value);
- m_Result.append((const char *)&Value, 4);
-}
-
-
-
-
-
-void cFastNBTWriter::AddDouble(const AString & a_Name, double a_Value)
-{
- TagCommon(a_Name, TAG_Double);
- Int64 Value = HostToNetwork8(&a_Value);
- m_Result.append((const char *)&Value, 8);
-}
-
-
-
-
-
-void cFastNBTWriter::AddString(const AString & a_Name, const AString & a_Value)
-{
- TagCommon(a_Name, TAG_String);
- Int16 len = htons((short)(a_Value.size()));
- m_Result.append((const char *)&len, 2);
- m_Result.append(a_Value.c_str(), a_Value.size());
-}
-
-
-
-
-
-void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements)
-{
- TagCommon(a_Name, TAG_ByteArray);
- Int32 len = htonl(a_NumElements);
- m_Result.append((const char *)&len, 4);
- m_Result.append(a_Value, a_NumElements);
-}
-
-
-
-
-
-void cFastNBTWriter::AddIntArray(const AString & a_Name, const int * a_Value, size_t a_NumElements)
-{
- TagCommon(a_Name, TAG_IntArray);
- Int32 len = htonl(a_NumElements);
- m_Result.append((const char *)&len, 2);
- int * Elements = (int *)(m_Result.data() + m_Result.size());
- m_Result.append(a_NumElements * 4, (char)0);
- for (size_t i = 0; i < a_NumElements; i++)
- {
- Elements[i] = htonl(a_Value[i]);
- }
-}
-
-
-
-
-void cFastNBTWriter::Finish(void)
-{
- ASSERT(m_CurrentStack == 0);
- m_Result.push_back(TAG_End);
-}
-
-
-
-
-
-void cFastNBTWriter::WriteString(const char * a_Data, short a_Length)
-{
- Int16 Len = htons(a_Length);
- m_Result.append((const char *)&Len, 2);
- m_Result.append(a_Data, a_Length);
-}
-
-
-
-
+ +// FastNBT.cpp + +// Implements the fast NBT parser and writer + +#include "Globals.h" +#include "FastNBT.h" + + + + + +#define RETURN_FALSE_IF_FALSE(X) do { if (!X) return false; } while (0) + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cParsedNBT: + +#define NEEDBYTES(N) \ + if (m_Length - m_Pos < N) \ + { \ + return false; \ + } + + + + + +cParsedNBT::cParsedNBT(const char * a_Data, int a_Length) : + m_Data(a_Data), + m_Length(a_Length), + m_Pos(0) +{ + m_IsValid = Parse(); +} + + + + + +bool cParsedNBT::Parse(void) +{ + if (m_Length < 3) + { + // Data too short + return false; + } + if (m_Data[0] != TAG_Compound) + { + // The top-level tag must be a Compound + return false; + } + + m_Tags.reserve(200); + + m_Tags.push_back(cFastNBTTag(TAG_Compound, -1)); + + m_Pos = 1; + + RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength)); + RETURN_FALSE_IF_FALSE(ReadCompound()); + + return true; +} + + + + + +bool cParsedNBT::ReadString(int & a_StringStart, int & a_StringLen) +{ + NEEDBYTES(2); + a_StringStart = m_Pos + 2; + a_StringLen = ntohs(*((short *)(m_Data + m_Pos))); + if (a_StringLen < 0) + { + // Invalid string length + return false; + } + m_Pos += 2 + a_StringLen; + return true; +} + + + + + +bool cParsedNBT::ReadCompound(void) +{ + // Reads the latest tag as a compound + int ParentIdx = m_Tags.size() - 1; + int PrevSibling = -1; + while (true) + { + NEEDBYTES(1); + eTagType TagType = (eTagType)(m_Data[m_Pos]); + m_Pos++; + if (TagType == TAG_End) + { + break; + } + m_Tags.push_back(cFastNBTTag(TagType, ParentIdx, PrevSibling)); + if (PrevSibling >= 0) + { + m_Tags[PrevSibling].m_NextSibling = m_Tags.size() - 1; + } + else + { + m_Tags[ParentIdx].m_FirstChild = m_Tags.size() - 1; + } + PrevSibling = m_Tags.size() - 1; + RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength)); + RETURN_FALSE_IF_FALSE(ReadTag()); + } // while (true) + m_Tags[ParentIdx].m_LastChild = PrevSibling; + return true; +} + + + + + +bool cParsedNBT::ReadList(eTagType a_ChildrenType) +{ + // Reads the latest tag as a list of items of type a_ChildrenType + + // Read the count: + NEEDBYTES(4); + int Count = ntohl(*((int *)(m_Data + m_Pos))); + m_Pos += 4; + if (Count < 0) + { + return false; + } + + // Read items: + int ParentIdx = m_Tags.size() - 1; + int PrevSibling = -1; + for (int i = 0; i < Count; i++) + { + m_Tags.push_back(cFastNBTTag(a_ChildrenType, ParentIdx, PrevSibling)); + if (PrevSibling >= 0) + { + m_Tags[PrevSibling].m_NextSibling = m_Tags.size() - 1; + } + else + { + m_Tags[ParentIdx].m_FirstChild = m_Tags.size() - 1; + } + PrevSibling = m_Tags.size() - 1; + RETURN_FALSE_IF_FALSE(ReadTag()); + } // for (i) + m_Tags[ParentIdx].m_LastChild = PrevSibling; + return true; +} + + + + + +#define CASE_SIMPLE_TAG(TAGTYPE, LEN) \ + case TAG_##TAGTYPE: \ + { \ + NEEDBYTES(LEN); \ + Tag.m_DataStart = m_Pos; \ + Tag.m_DataLength = LEN; \ + m_Pos += LEN; \ + return true; \ + } + +bool cParsedNBT::ReadTag(void) +{ + cFastNBTTag & Tag = m_Tags.back(); + switch (Tag.m_Type) + { + CASE_SIMPLE_TAG(Byte, 1) + CASE_SIMPLE_TAG(Short, 2) + CASE_SIMPLE_TAG(Int, 4) + CASE_SIMPLE_TAG(Long, 8) + CASE_SIMPLE_TAG(Float, 4) + CASE_SIMPLE_TAG(Double, 8) + + case TAG_String: + { + return ReadString(Tag.m_DataStart, Tag.m_DataLength); + } + + case TAG_ByteArray: + { + NEEDBYTES(4); + int len = ntohl(*((int *)(m_Data + m_Pos))); + m_Pos += 4; + if (len < 0) + { + // Invalid length + return false; + } + NEEDBYTES(len); + Tag.m_DataLength = len; + Tag.m_DataStart = m_Pos; + m_Pos += len; + return true; + } + + case TAG_List: + { + NEEDBYTES(1); + eTagType ItemType = (eTagType)m_Data[m_Pos]; + m_Pos++; + RETURN_FALSE_IF_FALSE(ReadList(ItemType)); + return true; + } + + case TAG_Compound: + { + RETURN_FALSE_IF_FALSE(ReadCompound()); + return true; + } + + case TAG_IntArray: + { + NEEDBYTES(4); + int len = ntohl(*((int *)(m_Data + m_Pos))); + m_Pos += 4; + if (len < 0) + { + // Invalid length + return false; + } + len *= 4; + NEEDBYTES(len); + Tag.m_DataLength = len; + Tag.m_DataStart = m_Pos; + m_Pos += len; + return true; + } + + default: + { + ASSERT(!"Unhandled NBT tag type"); + return false; + } + } // switch (iType) +} + +#undef CASE_SIMPLE_TAG + + + + + +int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength) const +{ + if (a_Tag < 0) + { + return -1; + } + if (m_Tags[a_Tag].m_Type != TAG_Compound) + { + return -1; + } + + if (a_NameLength == 0) + { + a_NameLength = strlen(a_Name); + } + for (int Child = m_Tags[a_Tag].m_FirstChild; Child != -1; Child = m_Tags[Child].m_NextSibling) + { + if ( + (m_Tags[Child].m_NameLength == a_NameLength) && + (memcmp(m_Data + m_Tags[Child].m_NameStart, a_Name, a_NameLength) == 0) + ) + { + return Child; + } + } // for Child - children of a_Tag + return -1; +} + + + + + +int cParsedNBT::FindTagByPath(int a_Tag, const AString & a_Path) const +{ + if (a_Tag < 0) + { + return -1; + } + size_t Begin = 0; + size_t Length = a_Path.length(); + int Tag = a_Tag; + for (size_t i = 0; i < Length; i++) + { + if (a_Path[i] != '\\') + { + continue; + } + Tag = FindChildByName(Tag, a_Path.c_str() + Begin, i - Begin - 1); + if (Tag < 0) + { + return -1; + } + Begin = i + 1; + } // for i - a_Path[] + + if (Begin < Length) + { + Tag = FindChildByName(Tag, a_Path.c_str() + Begin, Length - Begin); + } + return Tag; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cFastNBTWriter: + +cFastNBTWriter::cFastNBTWriter(void) : + m_CurrentStack(0) +{ + m_Stack[0].m_Type = TAG_Compound; + m_Result.reserve(100 * 1024); + m_Result.push_back(TAG_Compound); + WriteString("", 0); +} + + + + + +void cFastNBTWriter::BeginCompound(const AString & a_Name) +{ + if (m_CurrentStack >= MAX_STACK) + { + ASSERT(!"Stack overflow"); + return; + } + + TagCommon(a_Name, TAG_Compound); + + ++m_CurrentStack; + m_Stack[m_CurrentStack].m_Type = TAG_Compound; +} + + + + + +void cFastNBTWriter::EndCompound(void) +{ + ASSERT(m_CurrentStack > 0); + ASSERT(IsStackTopCompound()); + + m_Result.push_back(TAG_End); + --m_CurrentStack; +} + + + + + +void cFastNBTWriter::BeginList(const AString & a_Name, eTagType a_ChildrenType) +{ + if (m_CurrentStack >= MAX_STACK) + { + ASSERT(!"Stack overflow"); + return; + } + + TagCommon(a_Name, TAG_List); + + m_Result.push_back((char)a_ChildrenType); + m_Result.append(4, (char)0); + + ++m_CurrentStack; + m_Stack[m_CurrentStack].m_Type = TAG_List; + m_Stack[m_CurrentStack].m_Pos = m_Result.size() - 4; + m_Stack[m_CurrentStack].m_Count = 0; +} + + + + + +void cFastNBTWriter::EndList(void) +{ + ASSERT(m_CurrentStack > 0); + ASSERT(m_Stack[m_CurrentStack].m_Type == TAG_List); + + // Update the list count: + *((int *)(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos)) = htonl(m_Stack[m_CurrentStack].m_Count); + + --m_CurrentStack; +} + + + + + +void cFastNBTWriter::AddByte(const AString & a_Name, unsigned char a_Value) +{ + TagCommon(a_Name, TAG_Byte); + m_Result.push_back(a_Value); +} + + + + + +void cFastNBTWriter::AddShort(const AString & a_Name, Int16 a_Value) +{ + TagCommon(a_Name, TAG_Short); + Int16 Value = htons(a_Value); + m_Result.append((const char *)&Value, 2); +} + + + + + +void cFastNBTWriter::AddInt(const AString & a_Name, Int32 a_Value) +{ + TagCommon(a_Name, TAG_Int); + Int32 Value = htonl(a_Value); + m_Result.append((const char *)&Value, 4); +} + + + + + +void cFastNBTWriter::AddLong(const AString & a_Name, Int64 a_Value) +{ + TagCommon(a_Name, TAG_Long); + Int64 Value = HostToNetwork8(&a_Value); + m_Result.append((const char *)&Value, 8); +} + + + + + +void cFastNBTWriter::AddFloat(const AString & a_Name, float a_Value) +{ + TagCommon(a_Name, TAG_Float); + Int32 Value = HostToNetwork4(&a_Value); + m_Result.append((const char *)&Value, 4); +} + + + + + +void cFastNBTWriter::AddDouble(const AString & a_Name, double a_Value) +{ + TagCommon(a_Name, TAG_Double); + Int64 Value = HostToNetwork8(&a_Value); + m_Result.append((const char *)&Value, 8); +} + + + + + +void cFastNBTWriter::AddString(const AString & a_Name, const AString & a_Value) +{ + TagCommon(a_Name, TAG_String); + Int16 len = htons((short)(a_Value.size())); + m_Result.append((const char *)&len, 2); + m_Result.append(a_Value.c_str(), a_Value.size()); +} + + + + + +void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements) +{ + TagCommon(a_Name, TAG_ByteArray); + Int32 len = htonl(a_NumElements); + m_Result.append((const char *)&len, 4); + m_Result.append(a_Value, a_NumElements); +} + + + + + +void cFastNBTWriter::AddIntArray(const AString & a_Name, const int * a_Value, size_t a_NumElements) +{ + TagCommon(a_Name, TAG_IntArray); + Int32 len = htonl(a_NumElements); + m_Result.append((const char *)&len, 2); + int * Elements = (int *)(m_Result.data() + m_Result.size()); + m_Result.append(a_NumElements * 4, (char)0); + for (size_t i = 0; i < a_NumElements; i++) + { + Elements[i] = htonl(a_Value[i]); + } +} + + + + +void cFastNBTWriter::Finish(void) +{ + ASSERT(m_CurrentStack == 0); + m_Result.push_back(TAG_End); +} + + + + + +void cFastNBTWriter::WriteString(const char * a_Data, short a_Length) +{ + Int16 Len = htons(a_Length); + m_Result.append((const char *)&Len, 2); + m_Result.append(a_Data, a_Length); +} + + + + diff --git a/source/FastNBT.h b/source/FastNBT.h index f38bfcdbd..ca801b36f 100644 --- a/source/FastNBT.h +++ b/source/FastNBT.h @@ -1,274 +1,274 @@ -
-// FastNBT.h
-
-// Interfaces to the fast NBT parser and writer
-
-/*
-The fast parser parses the data into a vector of cFastNBTTag structures. These structures describe the NBT tree,
-but themselves are allocated in a vector, thus minimizing reallocation.
-The structures have a minimal constructor, setting all member "pointers" to "invalid".
-
-The fast writer doesn't need a NBT tree structure built beforehand, it is commanded to open, append and close tags
-(just like XML); it keeps the internal tag stack and reports errors in usage.
-It directly outputs a string containing the serialized NBT data.
-*/
-
-
-
-
-
-#pragma once
-
-#include "Endianness.h"
-
-
-
-
-
-enum eTagType
-{
- TAG_Min = 0, // The minimum value for a tag type
- TAG_End = 0,
- TAG_Byte = 1,
- TAG_Short = 2,
- TAG_Int = 3,
- TAG_Long = 4,
- TAG_Float = 5,
- TAG_Double = 6,
- TAG_ByteArray = 7,
- TAG_String = 8,
- TAG_List = 9,
- TAG_Compound = 10,
- TAG_IntArray = 11,
- TAG_Max = 11, // The maximum value for a tag type
-} ;
-
-
-
-
-
-/** This structure is used for all NBT tags.
-It contains indices to the parent array of tags, building the NBT tree this way.
-Also contains indices into the data stream being parsed, used for values;
-NO dynamically allocated memory is used!
-Structure (all with the tree structure it describes) supports moving in memory (std::vector reallocation)
-*/
-struct cFastNBTTag
-{
-public:
-
- eTagType m_Type;
-
- // The following members are indices into the data stream. m_DataLength == 0 if no data available
- // They must not be pointers, because the datastream may be copied into another AString object in the meantime.
- int m_NameStart;
- int m_NameLength;
- int m_DataStart;
- int m_DataLength;
-
- // The following members are indices into the array returned; -1 if not valid
- // They must not be pointers, because pointers would not survive std::vector reallocation
- int m_Parent;
- int m_PrevSibling;
- int m_NextSibling;
- int m_FirstChild;
- int m_LastChild;
-
- cFastNBTTag(eTagType a_Type, int a_Parent) :
- m_Type(a_Type),
- m_NameLength(0),
- m_DataLength(0),
- m_Parent(a_Parent),
- m_PrevSibling(-1),
- m_NextSibling(-1),
- m_FirstChild(-1),
- m_LastChild(-1)
- {
- }
-
- cFastNBTTag(eTagType a_Type, int a_Parent, int a_PrevSibling) :
- m_Type(a_Type),
- m_NameLength(0),
- m_DataLength(0),
- m_Parent(a_Parent),
- m_PrevSibling(a_PrevSibling),
- m_NextSibling(-1),
- m_FirstChild(-1),
- m_LastChild(-1)
- {
- }
-} ;
-
-
-
-
-
-/** Parses and contains the parsed data
-Also implements data accessor functions for tree traversal and value getters
-The data pointer passed in the constructor is assumed to be valid throughout the object's life. Care must be taken not to initialize from a temporary.
-*/
-class cParsedNBT
-{
-public:
- cParsedNBT(const char * a_Data, int a_Length);
-
- bool IsValid(void) const {return m_IsValid; }
-
- int GetRoot(void) const {return 0; }
- int GetFirstChild (int a_Tag) const { return m_Tags[a_Tag].m_FirstChild; }
- int GetLastChild (int a_Tag) const { return m_Tags[a_Tag].m_LastChild; }
- int GetNextSibling(int a_Tag) const { return m_Tags[a_Tag].m_NextSibling; }
- int GetPrevSibling(int a_Tag) const { return m_Tags[a_Tag].m_PrevSibling; }
- int GetDataLength (int a_Tag) const { return m_Tags[a_Tag].m_DataLength; }
-
- const char * GetData(int a_Tag) const
- {
- ASSERT(m_Tags[a_Tag].m_Type != TAG_List);
- ASSERT(m_Tags[a_Tag].m_Type != TAG_Compound);
- return m_Data + m_Tags[a_Tag].m_DataStart;
- }
-
- int FindChildByName(int a_Tag, const AString & a_Name) const
- {
- return FindChildByName(a_Tag, a_Name.c_str(), a_Name.length());
- }
-
- int FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength = 0) const;
- int FindTagByPath (int a_Tag, const AString & a_Path) const;
-
- eTagType GetType(int a_Tag) const { return m_Tags[a_Tag].m_Type; }
-
- /// Returns the children type for a list tag; undefined on other tags. If list empty, returns TAG_End
- eTagType GetChildrenType(int a_Tag) const
- {
- ASSERT(m_Tags[a_Tag].m_Type == TAG_List);
- return (m_Tags[a_Tag].m_FirstChild < 0) ? TAG_End : m_Tags[m_Tags[a_Tag].m_FirstChild].m_Type;
- }
-
- inline unsigned char GetByte(int a_Tag) const
- {
- ASSERT(m_Tags[a_Tag].m_Type == TAG_Byte);
- return (unsigned char)(m_Data[m_Tags[a_Tag].m_DataStart]);
- }
-
- inline Int16 GetShort(int a_Tag) const
- {
- ASSERT(m_Tags[a_Tag].m_Type == TAG_Short);
- return ntohs(*((Int16 *)(m_Data + m_Tags[a_Tag].m_DataStart)));
- }
-
- inline Int32 GetInt(int a_Tag) const
- {
- ASSERT(m_Tags[a_Tag].m_Type == TAG_Int);
- return ntohl(*((Int32 *)(m_Data + m_Tags[a_Tag].m_DataStart)));
- }
-
- inline Int64 GetLong(int a_Tag) const
- {
- ASSERT(m_Tags[a_Tag].m_Type == TAG_Long);
- return NetworkToHostLong8(m_Data + m_Tags[a_Tag].m_DataStart);
- }
-
- inline float GetFloat(int a_Tag) const
- {
- ASSERT(m_Tags[a_Tag].m_Type == TAG_Float);
- Int32 tmp = ntohl(*((Int32 *)(m_Data + m_Tags[a_Tag].m_DataStart)));
- return *((float *)&tmp);
- }
-
- inline double GetDouble(int a_Tag) const
- {
- ASSERT(m_Tags[a_Tag].m_Type == TAG_Double);
- return NetworkToHostDouble8(m_Data + m_Tags[a_Tag].m_DataStart);
- }
-
-protected:
- const char * m_Data;
- int m_Length;
- std::vector<cFastNBTTag> m_Tags;
- bool m_IsValid; // True if parsing succeeded
-
- // Used while parsing:
- int m_Pos;
-
- bool Parse(void);
- bool ReadString(int & a_StringStart, int & a_StringLen); // Reads a simple string (2 bytes length + data), sets the string descriptors
- bool ReadCompound(void); // Reads the latest tag as a compound
- bool ReadList(eTagType a_ChildrenType); // Reads the latest tag as a list of items of type a_ChildrenType
- bool ReadTag(void); // Reads the latest tag, depending on its m_Type setting
-} ;
-
-
-
-
-
-class cFastNBTWriter
-{
-public:
- cFastNBTWriter(void);
-
- void BeginCompound(const AString & a_Name);
- void EndCompound(void);
-
- void BeginList(const AString & a_Name, eTagType a_ChildrenType);
- void EndList(void);
-
- void AddByte (const AString & a_Name, unsigned char a_Value);
- void AddShort (const AString & a_Name, Int16 a_Value);
- void AddInt (const AString & a_Name, Int32 a_Value);
- void AddLong (const AString & a_Name, Int64 a_Value);
- void AddFloat (const AString & a_Name, float a_Value);
- void AddDouble (const AString & a_Name, double a_Value);
- void AddString (const AString & a_Name, const AString & a_Value);
- void AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements);
- void AddIntArray (const AString & a_Name, const int * a_Value, size_t a_NumElements);
-
- void AddByteArray(const AString & a_Name, const AString & a_Value)
- {
- AddByteArray(a_Name, a_Value.data(), a_Value.size());
- }
-
- const AString & GetResult(void) const {return m_Result; }
-
- void Finish(void);
-
-protected:
-
- struct sParent
- {
- int m_Type; // TAG_Compound or TAG_List
- int m_Pos; // for TAG_List, the position of the list count
- int m_Count; // for TAG_List, the element count
- } ;
-
- static const int MAX_STACK = 50; // Highliy doubtful that an NBT would be constructed this many levels deep
-
- // These two fields emulate a stack. A raw array is used due to speed issues - no reallocations are allowed.
- sParent m_Stack[MAX_STACK];
- int m_CurrentStack;
-
- AString m_Result;
-
- bool IsStackTopCompound(void) const { return (m_Stack[m_CurrentStack].m_Type == TAG_Compound); }
-
- void WriteString(const char * a_Data, short a_Length);
-
- inline void TagCommon(const AString & a_Name, eTagType a_Type)
- {
- if (IsStackTopCompound())
- {
- // Compound: add the type and name:
- m_Result.push_back((char)a_Type);
- WriteString(a_Name.c_str(), (short)a_Name.length());
- }
- else
- {
- // List: add to the counter
- m_Stack[m_CurrentStack].m_Count++;
- }
- }
-} ;
-
-
-
-
+ +// FastNBT.h + +// Interfaces to the fast NBT parser and writer + +/* +The fast parser parses the data into a vector of cFastNBTTag structures. These structures describe the NBT tree, +but themselves are allocated in a vector, thus minimizing reallocation. +The structures have a minimal constructor, setting all member "pointers" to "invalid". + +The fast writer doesn't need a NBT tree structure built beforehand, it is commanded to open, append and close tags +(just like XML); it keeps the internal tag stack and reports errors in usage. +It directly outputs a string containing the serialized NBT data. +*/ + + + + + +#pragma once + +#include "Endianness.h" + + + + + +enum eTagType +{ + TAG_Min = 0, // The minimum value for a tag type + TAG_End = 0, + TAG_Byte = 1, + TAG_Short = 2, + TAG_Int = 3, + TAG_Long = 4, + TAG_Float = 5, + TAG_Double = 6, + TAG_ByteArray = 7, + TAG_String = 8, + TAG_List = 9, + TAG_Compound = 10, + TAG_IntArray = 11, + TAG_Max = 11, // The maximum value for a tag type +} ; + + + + + +/** This structure is used for all NBT tags. +It contains indices to the parent array of tags, building the NBT tree this way. +Also contains indices into the data stream being parsed, used for values; +NO dynamically allocated memory is used! +Structure (all with the tree structure it describes) supports moving in memory (std::vector reallocation) +*/ +struct cFastNBTTag +{ +public: + + eTagType m_Type; + + // The following members are indices into the data stream. m_DataLength == 0 if no data available + // They must not be pointers, because the datastream may be copied into another AString object in the meantime. + int m_NameStart; + int m_NameLength; + int m_DataStart; + int m_DataLength; + + // The following members are indices into the array returned; -1 if not valid + // They must not be pointers, because pointers would not survive std::vector reallocation + int m_Parent; + int m_PrevSibling; + int m_NextSibling; + int m_FirstChild; + int m_LastChild; + + cFastNBTTag(eTagType a_Type, int a_Parent) : + m_Type(a_Type), + m_NameLength(0), + m_DataLength(0), + m_Parent(a_Parent), + m_PrevSibling(-1), + m_NextSibling(-1), + m_FirstChild(-1), + m_LastChild(-1) + { + } + + cFastNBTTag(eTagType a_Type, int a_Parent, int a_PrevSibling) : + m_Type(a_Type), + m_NameLength(0), + m_DataLength(0), + m_Parent(a_Parent), + m_PrevSibling(a_PrevSibling), + m_NextSibling(-1), + m_FirstChild(-1), + m_LastChild(-1) + { + } +} ; + + + + + +/** Parses and contains the parsed data +Also implements data accessor functions for tree traversal and value getters +The data pointer passed in the constructor is assumed to be valid throughout the object's life. Care must be taken not to initialize from a temporary. +*/ +class cParsedNBT +{ +public: + cParsedNBT(const char * a_Data, int a_Length); + + bool IsValid(void) const {return m_IsValid; } + + int GetRoot(void) const {return 0; } + int GetFirstChild (int a_Tag) const { return m_Tags[a_Tag].m_FirstChild; } + int GetLastChild (int a_Tag) const { return m_Tags[a_Tag].m_LastChild; } + int GetNextSibling(int a_Tag) const { return m_Tags[a_Tag].m_NextSibling; } + int GetPrevSibling(int a_Tag) const { return m_Tags[a_Tag].m_PrevSibling; } + int GetDataLength (int a_Tag) const { return m_Tags[a_Tag].m_DataLength; } + + const char * GetData(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type != TAG_List); + ASSERT(m_Tags[a_Tag].m_Type != TAG_Compound); + return m_Data + m_Tags[a_Tag].m_DataStart; + } + + int FindChildByName(int a_Tag, const AString & a_Name) const + { + return FindChildByName(a_Tag, a_Name.c_str(), a_Name.length()); + } + + int FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength = 0) const; + int FindTagByPath (int a_Tag, const AString & a_Path) const; + + eTagType GetType(int a_Tag) const { return m_Tags[a_Tag].m_Type; } + + /// Returns the children type for a list tag; undefined on other tags. If list empty, returns TAG_End + eTagType GetChildrenType(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type == TAG_List); + return (m_Tags[a_Tag].m_FirstChild < 0) ? TAG_End : m_Tags[m_Tags[a_Tag].m_FirstChild].m_Type; + } + + inline unsigned char GetByte(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type == TAG_Byte); + return (unsigned char)(m_Data[m_Tags[a_Tag].m_DataStart]); + } + + inline Int16 GetShort(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type == TAG_Short); + return ntohs(*((Int16 *)(m_Data + m_Tags[a_Tag].m_DataStart))); + } + + inline Int32 GetInt(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type == TAG_Int); + return ntohl(*((Int32 *)(m_Data + m_Tags[a_Tag].m_DataStart))); + } + + inline Int64 GetLong(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type == TAG_Long); + return NetworkToHostLong8(m_Data + m_Tags[a_Tag].m_DataStart); + } + + inline float GetFloat(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type == TAG_Float); + Int32 tmp = ntohl(*((Int32 *)(m_Data + m_Tags[a_Tag].m_DataStart))); + return *((float *)&tmp); + } + + inline double GetDouble(int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type == TAG_Double); + return NetworkToHostDouble8(m_Data + m_Tags[a_Tag].m_DataStart); + } + +protected: + const char * m_Data; + int m_Length; + std::vector<cFastNBTTag> m_Tags; + bool m_IsValid; // True if parsing succeeded + + // Used while parsing: + int m_Pos; + + bool Parse(void); + bool ReadString(int & a_StringStart, int & a_StringLen); // Reads a simple string (2 bytes length + data), sets the string descriptors + bool ReadCompound(void); // Reads the latest tag as a compound + bool ReadList(eTagType a_ChildrenType); // Reads the latest tag as a list of items of type a_ChildrenType + bool ReadTag(void); // Reads the latest tag, depending on its m_Type setting +} ; + + + + + +class cFastNBTWriter +{ +public: + cFastNBTWriter(void); + + void BeginCompound(const AString & a_Name); + void EndCompound(void); + + void BeginList(const AString & a_Name, eTagType a_ChildrenType); + void EndList(void); + + void AddByte (const AString & a_Name, unsigned char a_Value); + void AddShort (const AString & a_Name, Int16 a_Value); + void AddInt (const AString & a_Name, Int32 a_Value); + void AddLong (const AString & a_Name, Int64 a_Value); + void AddFloat (const AString & a_Name, float a_Value); + void AddDouble (const AString & a_Name, double a_Value); + void AddString (const AString & a_Name, const AString & a_Value); + void AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements); + void AddIntArray (const AString & a_Name, const int * a_Value, size_t a_NumElements); + + void AddByteArray(const AString & a_Name, const AString & a_Value) + { + AddByteArray(a_Name, a_Value.data(), a_Value.size()); + } + + const AString & GetResult(void) const {return m_Result; } + + void Finish(void); + +protected: + + struct sParent + { + int m_Type; // TAG_Compound or TAG_List + int m_Pos; // for TAG_List, the position of the list count + int m_Count; // for TAG_List, the element count + } ; + + static const int MAX_STACK = 50; // Highliy doubtful that an NBT would be constructed this many levels deep + + // These two fields emulate a stack. A raw array is used due to speed issues - no reallocations are allowed. + sParent m_Stack[MAX_STACK]; + int m_CurrentStack; + + AString m_Result; + + bool IsStackTopCompound(void) const { return (m_Stack[m_CurrentStack].m_Type == TAG_Compound); } + + void WriteString(const char * a_Data, short a_Length); + + inline void TagCommon(const AString & a_Name, eTagType a_Type) + { + if (IsStackTopCompound()) + { + // Compound: add the type and name: + m_Result.push_back((char)a_Type); + WriteString(a_Name.c_str(), (short)a_Name.length()); + } + else + { + // List: add to the counter + m_Stack[m_CurrentStack].m_Count++; + } + } +} ; + + + + diff --git a/source/FileDefine.h b/source/FileDefine.h index 826d6dd75..c75fb3110 100644 --- a/source/FileDefine.h +++ b/source/FileDefine.h @@ -1,21 +1,21 @@ -#pragma once
-
-// So we don't have to include fstream :P
-#ifdef _WIN32
-#ifndef _FILE_DEFINED
-struct _iobuf {
- char *_ptr;
- int _cnt;
- char *_base;
- int _flag;
- int _file;
- int _charbuf;
- int _bufsiz;
- char *_tmpfname;
-};
-typedef struct _iobuf FILE;
-#define _FILE_DEFINED
-#endif
-#else
-#include <stdio.h>
+#pragma once + +// So we don't have to include fstream :P +#ifdef _WIN32 +#ifndef _FILE_DEFINED +struct _iobuf { + char *_ptr; + int _cnt; + char *_base; + int _flag; + int _file; + int _charbuf; + int _bufsiz; + char *_tmpfname; +}; +typedef struct _iobuf FILE; +#define _FILE_DEFINED +#endif +#else +#include <stdio.h> #endif
\ No newline at end of file diff --git a/source/FinishGen.cpp b/source/FinishGen.cpp index 9761d4373..eac4a6c02 100644 --- a/source/FinishGen.cpp +++ b/source/FinishGen.cpp @@ -1,285 +1,285 @@ -
-// FinishGen.cpp
-
-/* Implements the various finishing generators:
- - cFinishGenSnow
- - cFinishGenIce
- - cFinishGenSprinkleFoliage
-*/
-
-#include "Globals.h"
-
-#include "FinishGen.h"
-#include "cNoise.h"
-#include "BlockID.h"
-
-
-
-
-
-static inline bool IsWater(BLOCKTYPE a_BlockType)
-{
- return (a_BlockType == E_BLOCK_STATIONARY_WATER) || (a_BlockType == E_BLOCK_WATER);
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cFinishGenSprinkleFoliage:
-
-bool cFinishGenSprinkleFoliage::TryAddSugarcane(
- int a_ChunkX, int a_ChunkZ,
- int a_RelX, int a_RelY, int a_RelZ,
- cChunkDef::BlockTypes & a_BlockTypes,
- cChunkDef::BlockNibbles & a_BlockMeta
-)
-{
- // We'll be doing comparison to neighbors, so require the coords to be 1 block away from the chunk edges:
- if (
- (a_RelX < 1) || (a_RelX >= cChunkDef::Width - 1) ||
- (a_RelY < 1) || (a_RelY >= cChunkDef::Height - 2) ||
- (a_RelZ < 1) || (a_RelZ >= cChunkDef::Width - 1)
- )
- {
- return false;
- }
-
- // Only allow dirt, grass or sand below sugarcane:
- switch (cChunkDef::GetBlock(a_BlockTypes, a_RelX, a_RelY, a_RelZ))
- {
- case E_BLOCK_DIRT:
- case E_BLOCK_GRASS:
- case E_BLOCK_SAND:
- {
- break;
- }
- default:
- {
- return false;
- }
- }
-
- // Water is required next to the block below the sugarcane:
- if (
- !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX - 1, a_RelY, a_RelZ)) &&
- !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX + 1, a_RelY, a_RelZ)) &&
- !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX , a_RelY, a_RelZ - 1)) &&
- !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX , a_RelY, a_RelZ + 1))
- )
- {
- return false;
- }
-
- // All conditions met, place a sugarcane here:
- cChunkDef::SetBlock(a_BlockTypes, a_RelX, a_RelY + 1, a_RelZ, E_BLOCK_SUGARCANE);
- return true;
-}
-
-
-
-
-
-void cFinishGenSprinkleFoliage::GenFinish(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change
- cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entities may be added or deleted
- cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
- )
-{
- // Generate small foliage (1-block):
-
- // TODO: Update heightmap with 1-block-tall foliage
- cNoise Noise(m_Seed);
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- int BlockZ = a_ChunkZ * cChunkDef::Width + z;
- const float zz = (float)BlockZ;
- for (int x = 0; x < cChunkDef::Width; x++)
- {
- int BlockX = a_ChunkX * cChunkDef::Width + x;
- if (((Noise.IntNoise2DInt(BlockX, BlockZ) / 8) % 128) < 124)
- {
- continue;
- }
- int Top = cChunkDef::GetHeight(a_HeightMap, x, z);
- if (Top > 250)
- {
- // Nothing grows above Y=250
- continue;
- }
- if (cChunkDef::GetBlock(a_BlockTypes, x, Top + 1, z) != E_BLOCK_AIR)
- {
- // Space already taken by something else, don't grow here
- // WEIRD, since we're using heightmap, so there should NOT be anything above it
- continue;
- }
-
- const float xx = (float)BlockX;
- float val1 = Noise.CubicNoise2D(xx * 0.1f, zz * 0.1f );
- float val2 = Noise.CubicNoise2D(xx * 0.01f, zz * 0.01f );
- switch (cChunkDef::GetBlock(a_BlockTypes, x, Top, z))
- {
- case E_BLOCK_GRASS:
- {
- float val3 = Noise.CubicNoise2D(xx * 0.01f + 10, zz * 0.01f + 10 );
- float val4 = Noise.CubicNoise2D(xx * 0.05f + 20, zz * 0.05f + 20 );
- if (val1 + val2 > 0.2f)
- {
- cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_YELLOW_FLOWER);
- }
- else if (val2 + val3 > 0.2f)
- {
- cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_RED_ROSE);
- }
- else if (val3 + val4 > 0.2f)
- {
- cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_RED_MUSHROOM);
- }
- else if (val1 + val4 > 0.2f)
- {
- cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_BROWN_MUSHROOM);
- }
- else if (val1 + val2 + val3 + val4 < -0.1)
- {
- cChunkDef::SetBlock (a_BlockTypes, x, ++Top, z, E_BLOCK_TALL_GRASS);
- cChunkDef::SetNibble(a_BlockMeta, x, Top, z, E_META_TALL_GRASS_GRASS);
- }
- else if (TryAddSugarcane(a_ChunkX, a_ChunkZ, x, Top, z, a_BlockTypes, a_BlockMeta))
- {
- ++Top;
- }
- else if ((val1 > 0.5) && (val2 < -0.5))
- {
- cChunkDef::SetBlock (a_BlockTypes, x, ++Top, z, E_BLOCK_PUMPKIN);
- cChunkDef::SetNibble(a_BlockMeta, x, Top, z, (int)(val3 * 8) % 4);
- }
- break;
- } // case E_BLOCK_GRASS
-
- case E_BLOCK_SAND:
- {
- int y = Top + 1;
- if (
- (x > 0) && (x < cChunkDef::Width - 1) &&
- (z > 0) && (z < cChunkDef::Width - 1) &&
- (val1 + val2 > 0.5f) &&
- (cChunkDef::GetBlock(a_BlockTypes, x + 1, y, z) == E_BLOCK_AIR) &&
- (cChunkDef::GetBlock(a_BlockTypes, x - 1, y, z) == E_BLOCK_AIR) &&
- (cChunkDef::GetBlock(a_BlockTypes, x, y, z + 1) == E_BLOCK_AIR) &&
- (cChunkDef::GetBlock(a_BlockTypes, x, y, z - 1) == E_BLOCK_AIR)
- )
- {
- cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_CACTUS);
- }
- else if (TryAddSugarcane(a_ChunkX, a_ChunkZ, x, Top, z, a_BlockTypes, a_BlockMeta))
- {
- ++Top;
- }
- break;
- }
- } // switch (TopBlock)
- cChunkDef::SetHeight(a_HeightMap, x, z, Top);
- } // for y
- } // for z
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cFinishGenSnow:
-
-void cFinishGenSnow::GenFinish(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change
- cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entities may be added or deleted
- cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
- )
-{
- // Add a snow block in snowy biomes onto blocks that can be snowed over
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- for (int x = 0; x < cChunkDef::Width; x++)
- {
- switch (cChunkDef::GetBiome(a_BiomeMap, x, z))
- {
- case biIcePlains:
- case biIceMountains:
- case biTaiga:
- case biTaigaHills:
- case biFrozenRiver:
- case biFrozenOcean:
- {
- int Height = cChunkDef::GetHeight(a_HeightMap, x, z);
- if (g_BlockIsSnowable[cChunkDef::GetBlock(a_BlockTypes, x, Height, z)])
- {
- cChunkDef::SetBlock(a_BlockTypes, x, Height + 1, z, E_BLOCK_SNOW);
- cChunkDef::SetHeight(a_HeightMap, x, z, Height + 1);
- }
- break;
- }
- }
- }
- } // for z
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cFinishGenIce:
-
-void cFinishGenIce::GenFinish(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change
- cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entities may be added or deleted
- cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
- )
-{
- // Turn surface water into ice in icy biomes
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- for (int x = 0; x < cChunkDef::Width; x++)
- {
- switch (cChunkDef::GetBiome(a_BiomeMap, x, z))
- {
- case biIcePlains:
- case biIceMountains:
- case biTaiga:
- case biTaigaHills:
- case biFrozenRiver:
- case biFrozenOcean:
- {
- int Height = cChunkDef::GetHeight(a_HeightMap, x, z);
- switch (cChunkDef::GetBlock(a_BlockTypes, x, Height, z))
- {
- case E_BLOCK_WATER:
- case E_BLOCK_STATIONARY_WATER:
- {
- cChunkDef::SetBlock(a_BlockTypes, x, Height, z, E_BLOCK_ICE);
- break;
- }
- }
- break;
- }
- }
- }
- } // for z
-}
-
-
-
-
+ +// FinishGen.cpp + +/* Implements the various finishing generators: + - cFinishGenSnow + - cFinishGenIce + - cFinishGenSprinkleFoliage +*/ + +#include "Globals.h" + +#include "FinishGen.h" +#include "cNoise.h" +#include "BlockID.h" + + + + + +static inline bool IsWater(BLOCKTYPE a_BlockType) +{ + return (a_BlockType == E_BLOCK_STATIONARY_WATER) || (a_BlockType == E_BLOCK_WATER); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cFinishGenSprinkleFoliage: + +bool cFinishGenSprinkleFoliage::TryAddSugarcane( + int a_ChunkX, int a_ChunkZ, + int a_RelX, int a_RelY, int a_RelZ, + cChunkDef::BlockTypes & a_BlockTypes, + cChunkDef::BlockNibbles & a_BlockMeta +) +{ + // We'll be doing comparison to neighbors, so require the coords to be 1 block away from the chunk edges: + if ( + (a_RelX < 1) || (a_RelX >= cChunkDef::Width - 1) || + (a_RelY < 1) || (a_RelY >= cChunkDef::Height - 2) || + (a_RelZ < 1) || (a_RelZ >= cChunkDef::Width - 1) + ) + { + return false; + } + + // Only allow dirt, grass or sand below sugarcane: + switch (cChunkDef::GetBlock(a_BlockTypes, a_RelX, a_RelY, a_RelZ)) + { + case E_BLOCK_DIRT: + case E_BLOCK_GRASS: + case E_BLOCK_SAND: + { + break; + } + default: + { + return false; + } + } + + // Water is required next to the block below the sugarcane: + if ( + !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX - 1, a_RelY, a_RelZ)) && + !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX + 1, a_RelY, a_RelZ)) && + !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX , a_RelY, a_RelZ - 1)) && + !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX , a_RelY, a_RelZ + 1)) + ) + { + return false; + } + + // All conditions met, place a sugarcane here: + cChunkDef::SetBlock(a_BlockTypes, a_RelX, a_RelY + 1, a_RelZ, E_BLOCK_SUGARCANE); + return true; +} + + + + + +void cFinishGenSprinkleFoliage::GenFinish( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) +{ + // Generate small foliage (1-block): + + // TODO: Update heightmap with 1-block-tall foliage + cNoise Noise(m_Seed); + for (int z = 0; z < cChunkDef::Width; z++) + { + int BlockZ = a_ChunkZ * cChunkDef::Width + z; + const float zz = (float)BlockZ; + for (int x = 0; x < cChunkDef::Width; x++) + { + int BlockX = a_ChunkX * cChunkDef::Width + x; + if (((Noise.IntNoise2DInt(BlockX, BlockZ) / 8) % 128) < 124) + { + continue; + } + int Top = cChunkDef::GetHeight(a_HeightMap, x, z); + if (Top > 250) + { + // Nothing grows above Y=250 + continue; + } + if (cChunkDef::GetBlock(a_BlockTypes, x, Top + 1, z) != E_BLOCK_AIR) + { + // Space already taken by something else, don't grow here + // WEIRD, since we're using heightmap, so there should NOT be anything above it + continue; + } + + const float xx = (float)BlockX; + float val1 = Noise.CubicNoise2D(xx * 0.1f, zz * 0.1f ); + float val2 = Noise.CubicNoise2D(xx * 0.01f, zz * 0.01f ); + switch (cChunkDef::GetBlock(a_BlockTypes, x, Top, z)) + { + case E_BLOCK_GRASS: + { + float val3 = Noise.CubicNoise2D(xx * 0.01f + 10, zz * 0.01f + 10 ); + float val4 = Noise.CubicNoise2D(xx * 0.05f + 20, zz * 0.05f + 20 ); + if (val1 + val2 > 0.2f) + { + cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_YELLOW_FLOWER); + } + else if (val2 + val3 > 0.2f) + { + cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_RED_ROSE); + } + else if (val3 + val4 > 0.2f) + { + cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_RED_MUSHROOM); + } + else if (val1 + val4 > 0.2f) + { + cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_BROWN_MUSHROOM); + } + else if (val1 + val2 + val3 + val4 < -0.1) + { + cChunkDef::SetBlock (a_BlockTypes, x, ++Top, z, E_BLOCK_TALL_GRASS); + cChunkDef::SetNibble(a_BlockMeta, x, Top, z, E_META_TALL_GRASS_GRASS); + } + else if (TryAddSugarcane(a_ChunkX, a_ChunkZ, x, Top, z, a_BlockTypes, a_BlockMeta)) + { + ++Top; + } + else if ((val1 > 0.5) && (val2 < -0.5)) + { + cChunkDef::SetBlock (a_BlockTypes, x, ++Top, z, E_BLOCK_PUMPKIN); + cChunkDef::SetNibble(a_BlockMeta, x, Top, z, (int)(val3 * 8) % 4); + } + break; + } // case E_BLOCK_GRASS + + case E_BLOCK_SAND: + { + int y = Top + 1; + if ( + (x > 0) && (x < cChunkDef::Width - 1) && + (z > 0) && (z < cChunkDef::Width - 1) && + (val1 + val2 > 0.5f) && + (cChunkDef::GetBlock(a_BlockTypes, x + 1, y, z) == E_BLOCK_AIR) && + (cChunkDef::GetBlock(a_BlockTypes, x - 1, y, z) == E_BLOCK_AIR) && + (cChunkDef::GetBlock(a_BlockTypes, x, y, z + 1) == E_BLOCK_AIR) && + (cChunkDef::GetBlock(a_BlockTypes, x, y, z - 1) == E_BLOCK_AIR) + ) + { + cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_CACTUS); + } + else if (TryAddSugarcane(a_ChunkX, a_ChunkZ, x, Top, z, a_BlockTypes, a_BlockMeta)) + { + ++Top; + } + break; + } + } // switch (TopBlock) + cChunkDef::SetHeight(a_HeightMap, x, z, Top); + } // for y + } // for z +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cFinishGenSnow: + +void cFinishGenSnow::GenFinish( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) +{ + // Add a snow block in snowy biomes onto blocks that can be snowed over + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + switch (cChunkDef::GetBiome(a_BiomeMap, x, z)) + { + case biIcePlains: + case biIceMountains: + case biTaiga: + case biTaigaHills: + case biFrozenRiver: + case biFrozenOcean: + { + int Height = cChunkDef::GetHeight(a_HeightMap, x, z); + if (g_BlockIsSnowable[cChunkDef::GetBlock(a_BlockTypes, x, Height, z)]) + { + cChunkDef::SetBlock(a_BlockTypes, x, Height + 1, z, E_BLOCK_SNOW); + cChunkDef::SetHeight(a_HeightMap, x, z, Height + 1); + } + break; + } + } + } + } // for z +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cFinishGenIce: + +void cFinishGenIce::GenFinish( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) +{ + // Turn surface water into ice in icy biomes + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + switch (cChunkDef::GetBiome(a_BiomeMap, x, z)) + { + case biIcePlains: + case biIceMountains: + case biTaiga: + case biTaigaHills: + case biFrozenRiver: + case biFrozenOcean: + { + int Height = cChunkDef::GetHeight(a_HeightMap, x, z); + switch (cChunkDef::GetBlock(a_BlockTypes, x, Height, z)) + { + case E_BLOCK_WATER: + case E_BLOCK_STATIONARY_WATER: + { + cChunkDef::SetBlock(a_BlockTypes, x, Height, z, E_BLOCK_ICE); + break; + } + } + break; + } + } + } + } // for z +} + + + + diff --git a/source/FinishGen.h b/source/FinishGen.h index 816e2ca7c..1684e5eea 100644 --- a/source/FinishGen.h +++ b/source/FinishGen.h @@ -1,90 +1,90 @@ -
-// FinishGen.h
-
-/* Interfaces to the various finishing generators:
- - cFinishGenSnow
- - cFinishGenIce
- - cFinishGenSprinkleFoliage
-*/
-
-
-
-
-
-#include "cChunkGenerator.h"
-
-
-
-
-
-class cFinishGenSnow :
- public cFinishGen
-{
-protected:
- // cFinishGen override:
- virtual void GenFinish(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change
- cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entities may be added or deleted
- cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
- ) override;
-} ;
-
-
-
-
-
-class cFinishGenIce :
- public cFinishGen
-{
-protected:
- // cFinishGen override:
- virtual void GenFinish(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change
- cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entities may be added or deleted
- cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
- ) override;
-} ;
-
-
-
-
-class cFinishGenSprinkleFoliage :
- public cFinishGen
-{
-public:
- cFinishGenSprinkleFoliage(int a_Seed) : m_Seed(a_Seed) {}
-
-protected:
- int m_Seed;
-
- /// Tries to place sugarcane at the coords specified, returns true if successful
- bool TryAddSugarcane(
- int a_ChunkX, int a_ChunkZ,
- int a_RelX, int a_RelY, int a_RelZ, // relative block coords of the sugarcane's base
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMeta // Block meta to read and change
- );
-
- // cFinishGen override:
- virtual void GenFinish(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change
- cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entities may be added or deleted
- cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
- ) override;
-} ;
-
-
-
-
+ +// FinishGen.h + +/* Interfaces to the various finishing generators: + - cFinishGenSnow + - cFinishGenIce + - cFinishGenSprinkleFoliage +*/ + + + + + +#include "cChunkGenerator.h" + + + + + +class cFinishGenSnow : + public cFinishGen +{ +protected: + // cFinishGen override: + virtual void GenFinish( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) override; +} ; + + + + + +class cFinishGenIce : + public cFinishGen +{ +protected: + // cFinishGen override: + virtual void GenFinish( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) override; +} ; + + + + +class cFinishGenSprinkleFoliage : + public cFinishGen +{ +public: + cFinishGenSprinkleFoliage(int a_Seed) : m_Seed(a_Seed) {} + +protected: + int m_Seed; + + /// Tries to place sugarcane at the coords specified, returns true if successful + bool TryAddSugarcane( + int a_ChunkX, int a_ChunkZ, + int a_RelX, int a_RelY, int a_RelZ, // relative block coords of the sugarcane's base + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta // Block meta to read and change + ); + + // cFinishGen override: + virtual void GenFinish( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) override; +} ; + + + + diff --git a/source/Globals.cpp b/source/Globals.cpp index 2c60fd698..13c6ae709 100644 --- a/source/Globals.cpp +++ b/source/Globals.cpp @@ -1,10 +1,10 @@ -
-// Globals.cpp
-
-// This file is used for precompiled header generation in MSVC environments
-
-#include "Globals.h"
-
-
-
-
+ +// Globals.cpp + +// This file is used for precompiled header generation in MSVC environments + +#include "Globals.h" + + + + diff --git a/source/Globals.h b/source/Globals.h index 78f847e2e..65db1b436 100644 --- a/source/Globals.h +++ b/source/Globals.h @@ -1,202 +1,202 @@ -
-// Globals.h
-
-// This file gets included from every module in the project, so that global symbols may be introduced easily
-// Also used for precompiled header generation in MSVC environments
-
-
-
-
-
-// Compiler-dependent stuff:
-#if defined(_MSC_VER)
- // MSVC produces warning C4481 on the override keyword usage, so disable the warning altogether
- #pragma warning(disable:4481)
-
- // Disable some warnings that we don't care about:
- #pragma warning(disable:4100)
-
- #define OBSOLETE __declspec(deprecated)
-
- // No alignment needed in MSVC
- #define ALIGN_8
- #define ALIGN_16
-
-#elif defined(__GNUC__)
-
- // TODO: Can GCC explicitly mark classes as abstract (no instances can be created)?
- #define abstract
-
- // TODO: Can GCC mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class)
- #define override
-
- #define OBSOLETE __attribute__((deprecated))
-
- #define ALIGN_8 __attribute__((aligned(8)))
- #define ALIGN_16 __attribute__((aligned(16)))
-
- // Some portability macros :)
- #define stricmp strcasecmp
-
-#else
-
- #error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler"
-
- /*
- // Copy and uncomment this into another #elif section based on your compiler identification
-
- // Explicitly mark classes as abstract (no instances can be created)
- #define abstract
-
- // Mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class)
- #define override
-
- // Mark functions as obsolete, so that their usage results in a compile-time warning
- #define OBSOLETE
-
- // Mark types / variables for alignment. Do the platforms need it?
- #define ALIGN_8
- #define ALIGN_16
- */
-
-#endif
-
-
-
-
-
-// Integral types with predefined sizes:
-typedef long long Int64;
-typedef int Int32;
-typedef short Int16;
-
-
-
-
-
-// A macro to disallow the copy constructor and operator= functions
-// This should be used in the private: declarations for any class that shouldn't allow copying itself
-#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
- TypeName(const TypeName &); \
- void operator=(const TypeName &)
-
-
-
-
-
-// OS-dependent stuff:
-#ifdef _WIN32
- #define WIN32_LEAN_AND_MEAN
- #include <Windows.h>
- #include <winsock2.h>
-
- // Windows SDK defines min and max macros, messing up with our std::min and std::max usage
- #undef min
- #undef max
-#else
- #include <sys/types.h>
- #include <sys/stat.h> // for mkdir
- #include <sys/time.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <time.h>
- #include <dirent.h>
- #include <errno.h>
- #include <iostream>
-
- #include <cstdio>
- #include <cstring>
- #include <pthread.h>
- #include <semaphore.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <tr1/memory>
-#endif
-
-
-
-
-
-// CRT stuff:
-#include <assert.h>
-#include <stdio.h>
-#include <math.h>
-#include <stdarg.h>
-
-
-
-
-
-// STL stuff:
-#include <vector>
-#include <list>
-#include <deque>
-#include <string>
-#include <map>
-#include <algorithm>
-#include <memory>
-
-
-
-
-
-// Common headers (part 1, without macros):
-#include "StringUtils.h"
-#include "cSleep.h"
-#include "cCriticalSection.h"
-#include "cSemaphore.h"
-#include "cEvent.h"
-#include "cThread.h"
-#include "cFile.h"
-#include "cMCLogger.h"
-
-
-
-
-
-// Common definitions:
-
-/// Evaluates to the number of elements in an array (compile-time!)
-#define ARRAYCOUNT(X) (sizeof(X) / sizeof(*(X)))
-
-/// Allows arithmetic expressions like "32 KiB" (but consider using parenthesis around it, "(32 KiB)" )
-#define KiB * 1024
-
-/// Faster than (int)floorf((float)x / (float)div)
-#define FAST_FLOOR_DIV( x, div ) ( (x) < 0 ? (((int)x / div) - 1) : ((int)x / div) )
-
-// Own version of assert() that writes failed assertions to the log for review
-#ifdef NDEBUG
- #define ASSERT(x) ((void)0)
-#else
- #define ASSERT( x ) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), assert(0), 0 ) )
-#endif
-
-// Pretty much the same as ASSERT() but stays in Release builds
-#define VERIFY( x ) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), exit(1), 0 ) )
-
-
-
-
-
-/// A generic interface used mainly in ForEach() functions
-template <typename Type> class cItemCallback
-{
-public:
- /// Called for each item in the internal list; return true to stop the loop, or false to continue enumerating
- virtual bool Item(Type * a_Type) = 0;
-} ;
-
-
-
-
-
-// Common headers (part 2, with macros):
-#include "ChunkDef.h"
-#include "BlockID.h"
-
-
-
-
+ +// Globals.h + +// This file gets included from every module in the project, so that global symbols may be introduced easily +// Also used for precompiled header generation in MSVC environments + + + + + +// Compiler-dependent stuff: +#if defined(_MSC_VER) + // MSVC produces warning C4481 on the override keyword usage, so disable the warning altogether + #pragma warning(disable:4481) + + // Disable some warnings that we don't care about: + #pragma warning(disable:4100) + + #define OBSOLETE __declspec(deprecated) + + // No alignment needed in MSVC + #define ALIGN_8 + #define ALIGN_16 + +#elif defined(__GNUC__) + + // TODO: Can GCC explicitly mark classes as abstract (no instances can be created)? + #define abstract + + // TODO: Can GCC mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class) + #define override + + #define OBSOLETE __attribute__((deprecated)) + + #define ALIGN_8 __attribute__((aligned(8))) + #define ALIGN_16 __attribute__((aligned(16))) + + // Some portability macros :) + #define stricmp strcasecmp + +#else + + #error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler" + + /* + // Copy and uncomment this into another #elif section based on your compiler identification + + // Explicitly mark classes as abstract (no instances can be created) + #define abstract + + // Mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class) + #define override + + // Mark functions as obsolete, so that their usage results in a compile-time warning + #define OBSOLETE + + // Mark types / variables for alignment. Do the platforms need it? + #define ALIGN_8 + #define ALIGN_16 + */ + +#endif + + + + + +// Integral types with predefined sizes: +typedef long long Int64; +typedef int Int32; +typedef short Int16; + + + + + +// A macro to disallow the copy constructor and operator= functions +// This should be used in the private: declarations for any class that shouldn't allow copying itself +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName &); \ + void operator=(const TypeName &) + + + + + +// OS-dependent stuff: +#ifdef _WIN32 + #define WIN32_LEAN_AND_MEAN + #include <Windows.h> + #include <winsock2.h> + + // Windows SDK defines min and max macros, messing up with our std::min and std::max usage + #undef min + #undef max +#else + #include <sys/types.h> + #include <sys/stat.h> // for mkdir + #include <sys/time.h> + #include <sys/socket.h> + #include <netinet/in.h> + #include <arpa/inet.h> + #include <netdb.h> + #include <time.h> + #include <dirent.h> + #include <errno.h> + #include <iostream> + + #include <cstdio> + #include <cstring> + #include <pthread.h> + #include <semaphore.h> + #include <errno.h> + #include <fcntl.h> + #include <tr1/memory> +#endif + + + + + +// CRT stuff: +#include <assert.h> +#include <stdio.h> +#include <math.h> +#include <stdarg.h> + + + + + +// STL stuff: +#include <vector> +#include <list> +#include <deque> +#include <string> +#include <map> +#include <algorithm> +#include <memory> + + + + + +// Common headers (part 1, without macros): +#include "StringUtils.h" +#include "cSleep.h" +#include "cCriticalSection.h" +#include "cSemaphore.h" +#include "cEvent.h" +#include "cThread.h" +#include "cFile.h" +#include "cMCLogger.h" + + + + + +// Common definitions: + +/// Evaluates to the number of elements in an array (compile-time!) +#define ARRAYCOUNT(X) (sizeof(X) / sizeof(*(X))) + +/// Allows arithmetic expressions like "32 KiB" (but consider using parenthesis around it, "(32 KiB)" ) +#define KiB * 1024 + +/// Faster than (int)floorf((float)x / (float)div) +#define FAST_FLOOR_DIV( x, div ) ( (x) < 0 ? (((int)x / div) - 1) : ((int)x / div) ) + +// Own version of assert() that writes failed assertions to the log for review +#ifdef NDEBUG + #define ASSERT(x) ((void)0) +#else + #define ASSERT( x ) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), assert(0), 0 ) ) +#endif + +// Pretty much the same as ASSERT() but stays in Release builds +#define VERIFY( x ) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), exit(1), 0 ) ) + + + + + +/// A generic interface used mainly in ForEach() functions +template <typename Type> class cItemCallback +{ +public: + /// Called for each item in the internal list; return true to stop the loop, or false to continue enumerating + virtual bool Item(Type * a_Type) = 0; +} ; + + + + + +// Common headers (part 2, with macros): +#include "ChunkDef.h" +#include "BlockID.h" + + + + diff --git a/source/HeiGen.cpp b/source/HeiGen.cpp index 551ae8804..ed353751c 100644 --- a/source/HeiGen.cpp +++ b/source/HeiGen.cpp @@ -1,302 +1,302 @@ -
-// HeiGen.cpp
-
-// Implements the various terrain height generators
-
-#include "Globals.h"
-#include "HeiGen.h"
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cHeiGenFlat:
-
-void cHeiGenFlat::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
-{
- for (int i = 0; i < ARRAYCOUNT(a_HeightMap); i++)
- {
- a_HeightMap[i] = m_Height;
- }
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cHeiGenCache:
-
-cHeiGenCache::cHeiGenCache(cTerrainHeightGen * a_HeiGenToCache, int a_CacheSize) :
- m_HeiGenToCache(a_HeiGenToCache),
- m_CacheSize(a_CacheSize),
- m_CacheOrder(new int[a_CacheSize]),
- m_CacheData(new sCacheData[a_CacheSize]),
- m_NumHits(0),
- m_NumMisses(0),
- m_TotalChain(0)
-{
- for (int i = 0; i < m_CacheSize; i++)
- {
- m_CacheOrder[i] = i;
- m_CacheData[i].m_ChunkX = 0x7fffffff;
- m_CacheData[i].m_ChunkZ = 0x7fffffff;
- }
-}
-
-
-
-
-
-cHeiGenCache::~cHeiGenCache()
-{
- delete m_CacheData;
- delete m_CacheOrder;
- delete m_HeiGenToCache;
-}
-
-
-
-
-
-void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
-{
- if (((m_NumHits + m_NumMisses) % 1024) == 10)
- {
- LOGD("HeiGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses));
- LOGD("HeiGenCache: Avg cache chain length: %.2f", (float)m_TotalChain / m_NumHits);
- }
-
- for (int i = 0; i < m_CacheSize; i++)
- {
- if (
- (m_CacheData[m_CacheOrder[i]].m_ChunkX != a_ChunkX) ||
- (m_CacheData[m_CacheOrder[i]].m_ChunkZ != a_ChunkZ)
- )
- {
- continue;
- }
- // Found it in the cache
- int Idx = m_CacheOrder[i];
-
- // Move to front:
- for (int j = i; j > 0; j--)
- {
- m_CacheOrder[j] = m_CacheOrder[j - 1];
- }
- m_CacheOrder[0] = Idx;
-
- // Use the cached data:
- memcpy(a_HeightMap, m_CacheData[Idx].m_HeightMap, sizeof(a_HeightMap));
-
- m_NumHits++;
- m_TotalChain += i;
- return;
- } // for i - cache
-
- // Not in the cache:
- m_NumMisses++;
- m_HeiGenToCache->GenHeightMap(a_ChunkX, a_ChunkZ, a_HeightMap);
-
- // Insert it as the first item in the MRU order:
- int Idx = m_CacheOrder[m_CacheSize - 1];
- for (int i = m_CacheSize - 1; i > 0; i--)
- {
- m_CacheOrder[i] = m_CacheOrder[i - 1];
- } // for i - m_CacheOrder[]
- m_CacheOrder[0] = Idx;
- memcpy(m_CacheData[Idx].m_HeightMap, a_HeightMap, sizeof(a_HeightMap));
- m_CacheData[Idx].m_ChunkX = a_ChunkX;
- m_CacheData[Idx].m_ChunkZ = a_ChunkZ;
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cHeiGenClassic:
-
-cHeiGenClassic::cHeiGenClassic(int a_Seed, float a_HeightFreq1, float a_HeightAmp1, float a_HeightFreq2, float a_HeightAmp2, float a_HeightFreq3, float a_HeightAmp3) :
- m_Seed(a_Seed),
- m_Noise(a_Seed),
- m_HeightFreq1(a_HeightFreq1),
- m_HeightAmp1 (a_HeightAmp1),
- m_HeightFreq2(a_HeightFreq2),
- m_HeightAmp2 (a_HeightAmp2),
- m_HeightFreq3(a_HeightFreq3),
- m_HeightAmp3 (a_HeightAmp3)
-{
- // Nothing needed yet
-}
-
-
-
-
-
-float cHeiGenClassic::GetNoise(float x, float y)
-{
- float oct1 = m_Noise.CubicNoise2D(x * m_HeightFreq1, y * m_HeightFreq1) * m_HeightAmp1;
- float oct2 = m_Noise.CubicNoise2D(x * m_HeightFreq2, y * m_HeightFreq2) * m_HeightAmp2;
- float oct3 = m_Noise.CubicNoise2D(x * m_HeightFreq3, y * m_HeightFreq3) * m_HeightAmp3;
-
- float height = m_Noise.CubicNoise2D(x * 0.1f, y * 0.1f ) * 2;
-
- float flatness = ((m_Noise.CubicNoise2D(x * 0.5f, y * 0.5f) + 1.f) * 0.5f) * 1.1f; // 0 ... 1.5
- flatness *= flatness * flatness;
-
- return (oct1 + oct2 + oct3) * flatness + height;
-}
-
-
-
-
-
-void cHeiGenClassic::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
-{
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- const float zz = (float)(a_ChunkZ * cChunkDef::Width + z);
- for (int x = 0; x < cChunkDef::Width; x++)
- {
- const float xx = (float)(a_ChunkX * cChunkDef::Width + x);
-
- int hei = 64 + (int)(GetNoise(xx * 0.05f, zz * 0.05f) * 16);
- if (hei < 10)
- {
- hei = 10;
- }
- if (hei > 250)
- {
- hei = 250;
- }
- cChunkDef::SetHeight(a_HeightMap, x , z, hei);
- } // for x
- } // for z
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cHeiGenBiomal:
-
-const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[biNumBiomes] =
-{
- /* Fast-changing | Middle-changing | Slow-changing |*/
- /* Biome | Freq1 | Amp1 | Freq2 | Amp2 | Freq3 | Amp3 | BaseHeight */
- /* biOcean */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // done
- /* biPlains */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done
- /* biDesert */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done
- /* biExtremeHills */ { 0.2f, 4.0f, 0.05f, 20.0f, 0.01f, 16.0f, 100}, // done
- /* biForest */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // done
- /* biTaiga */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // done
- /* biSwampland */ { 0.1f, 1.1f, 0.05f, 1.5f, 0.02f, 2.5f, 61.5}, // done
- /* biRiver */ { 0.2f, 3.0f, 0.05f, 1.0f, 0.01f, 1.0f, 56}, // done
- /* biNether */ { 0.1f, 0.0f, 0.01f, 0.0f, 0.01f, 0.0f, 0}, // Unused, but must be here due to indexing
- /* biSky */ { 0.1f, 0.0f, 0.01f, 0.0f, 0.01f, 0.0f, 0}, // Unused, but must be here due to indexing
- /* biFrozenOcean */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // done
- /* biFrozenRiver */ { 0.2f, 3.0f, 0.05f, 1.0f, 0.01f, 1.0f, 56}, // done
- /* biIcePlains */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done
- /* biIceMountains */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80}, // done
- /* biMushroomIsland */ { 0.1f, 2.0f, 0.05f, 8.0f, 0.01f, 6.0f, 80}, // done
- /* biMushroomShore */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 64}, // done
- /* biBeach */ { 0.1f, 0.5f, 0.05f, 1.0f, 0.01f, 1.0f, 64}, // done
- /* biDesertHills */ { 0.2f, 2.0f, 0.05f, 5.0f, 0.01f, 4.0f, 75}, // done
- /* biForestHills */ { 0.2f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done
- /* biTaigaHills */ { 0.2f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done
- /* biExtremeHillsEdge */ { 0.2f, 3.0f, 0.05f, 16.0f, 0.01f, 12.0f, 80}, // done
- /* biJungle */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // done
- /* biJungleHills */ { 0.2f, 3.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done
-} ;
-
-
-
-
-
-void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
-{
- // Generate a 3x3 chunk area of biomes around this chunk:
- BiomeNeighbors Biomes;
- for (int z = -1; z <= 1; z++)
- {
- for (int x = -1; x <= 1; x++)
- {
- m_BiomeGen.GenBiomes(a_ChunkX + x, a_ChunkZ + z, Biomes[x + 1][z + 1]);
- } // for x
- } // for z
-
- // For each height, go through neighboring biomes and add up their idea of height:
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- for (int x = 0; x < cChunkDef::Width; x++)
- {
- cChunkDef::SetHeight(a_HeightMap, x, z, GetHeightAt(x, z, a_ChunkX, a_ChunkZ, Biomes));
- } // for x
- }
-}
-
-
-
-
-
-HEIGHTTYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, int a_ChunkZ, const cHeiGenBiomal::BiomeNeighbors & a_BiomeNeighbors)
-{
- // Sum up how many biomes of each type there are in the neighborhood:
- int BiomeCounts[biNumBiomes];
- memset(BiomeCounts, 0, sizeof(BiomeCounts));
- int Sum = 0;
- for (int z = -8; z <= 8; z++)
- {
- int FinalZ = a_RelZ + z + cChunkDef::Width;
- int IdxZ = FinalZ / cChunkDef::Width;
- int ModZ = FinalZ % cChunkDef::Width;
- int WeightZ = 9 - abs(z);
- for (int x = -8; x <= 8; x++)
- {
- int FinalX = a_RelX + x + cChunkDef::Width;
- int IdxX = FinalX / cChunkDef::Width;
- int ModX = FinalX % cChunkDef::Width;
- EMCSBiome Biome = cChunkDef::GetBiome(a_BiomeNeighbors[IdxX][IdxZ], ModX, ModZ);
- if ((Biome < 0) || (Biome >= ARRAYCOUNT(BiomeCounts)))
- {
- continue;
- }
- int WeightX = 9 - abs(x);
- BiomeCounts[Biome] += WeightX + WeightZ;
- Sum += WeightX + WeightZ;
- } // for x
- } // for z
-
- // For each biome type that has a nonzero count, calc its height and add it:
- if (Sum > 0)
- {
- int Height = 0;
- int BlockX = a_ChunkX * cChunkDef::Width + a_RelX;
- int BlockZ = a_ChunkZ * cChunkDef::Width + a_RelZ;
- for (int i = 0; i < ARRAYCOUNT(BiomeCounts); i++)
- {
- if (BiomeCounts[i] == 0)
- {
- continue;
- }
- float oct1 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq1, BlockZ * m_GenParam[i].m_HeightFreq1) * m_GenParam[i].m_HeightAmp1;
- float oct2 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq2, BlockZ * m_GenParam[i].m_HeightFreq2) * m_GenParam[i].m_HeightAmp2;
- float oct3 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq3, BlockZ * m_GenParam[i].m_HeightFreq3) * m_GenParam[i].m_HeightAmp3;
- Height += BiomeCounts[i] * (int)(m_GenParam[i].m_BaseHeight + oct1 + oct2 + oct3);
- }
- int res = (HEIGHTTYPE)(Height / Sum);
- return std::min(250, std::max(res, 5));
- }
-
- // No known biome around? Weird. Return a bogus value:
- ASSERT(!"cHeiGenBiomal: Biome sum failed, no known biome around");
- return 5;
-}
-
-
-
-
-
+ +// HeiGen.cpp + +// Implements the various terrain height generators + +#include "Globals.h" +#include "HeiGen.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cHeiGenFlat: + +void cHeiGenFlat::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +{ + for (int i = 0; i < ARRAYCOUNT(a_HeightMap); i++) + { + a_HeightMap[i] = m_Height; + } +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cHeiGenCache: + +cHeiGenCache::cHeiGenCache(cTerrainHeightGen * a_HeiGenToCache, int a_CacheSize) : + m_HeiGenToCache(a_HeiGenToCache), + m_CacheSize(a_CacheSize), + m_CacheOrder(new int[a_CacheSize]), + m_CacheData(new sCacheData[a_CacheSize]), + m_NumHits(0), + m_NumMisses(0), + m_TotalChain(0) +{ + for (int i = 0; i < m_CacheSize; i++) + { + m_CacheOrder[i] = i; + m_CacheData[i].m_ChunkX = 0x7fffffff; + m_CacheData[i].m_ChunkZ = 0x7fffffff; + } +} + + + + + +cHeiGenCache::~cHeiGenCache() +{ + delete m_CacheData; + delete m_CacheOrder; + delete m_HeiGenToCache; +} + + + + + +void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +{ + if (((m_NumHits + m_NumMisses) % 1024) == 10) + { + LOGD("HeiGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses)); + LOGD("HeiGenCache: Avg cache chain length: %.2f", (float)m_TotalChain / m_NumHits); + } + + for (int i = 0; i < m_CacheSize; i++) + { + if ( + (m_CacheData[m_CacheOrder[i]].m_ChunkX != a_ChunkX) || + (m_CacheData[m_CacheOrder[i]].m_ChunkZ != a_ChunkZ) + ) + { + continue; + } + // Found it in the cache + int Idx = m_CacheOrder[i]; + + // Move to front: + for (int j = i; j > 0; j--) + { + m_CacheOrder[j] = m_CacheOrder[j - 1]; + } + m_CacheOrder[0] = Idx; + + // Use the cached data: + memcpy(a_HeightMap, m_CacheData[Idx].m_HeightMap, sizeof(a_HeightMap)); + + m_NumHits++; + m_TotalChain += i; + return; + } // for i - cache + + // Not in the cache: + m_NumMisses++; + m_HeiGenToCache->GenHeightMap(a_ChunkX, a_ChunkZ, a_HeightMap); + + // Insert it as the first item in the MRU order: + int Idx = m_CacheOrder[m_CacheSize - 1]; + for (int i = m_CacheSize - 1; i > 0; i--) + { + m_CacheOrder[i] = m_CacheOrder[i - 1]; + } // for i - m_CacheOrder[] + m_CacheOrder[0] = Idx; + memcpy(m_CacheData[Idx].m_HeightMap, a_HeightMap, sizeof(a_HeightMap)); + m_CacheData[Idx].m_ChunkX = a_ChunkX; + m_CacheData[Idx].m_ChunkZ = a_ChunkZ; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cHeiGenClassic: + +cHeiGenClassic::cHeiGenClassic(int a_Seed, float a_HeightFreq1, float a_HeightAmp1, float a_HeightFreq2, float a_HeightAmp2, float a_HeightFreq3, float a_HeightAmp3) : + m_Seed(a_Seed), + m_Noise(a_Seed), + m_HeightFreq1(a_HeightFreq1), + m_HeightAmp1 (a_HeightAmp1), + m_HeightFreq2(a_HeightFreq2), + m_HeightAmp2 (a_HeightAmp2), + m_HeightFreq3(a_HeightFreq3), + m_HeightAmp3 (a_HeightAmp3) +{ + // Nothing needed yet +} + + + + + +float cHeiGenClassic::GetNoise(float x, float y) +{ + float oct1 = m_Noise.CubicNoise2D(x * m_HeightFreq1, y * m_HeightFreq1) * m_HeightAmp1; + float oct2 = m_Noise.CubicNoise2D(x * m_HeightFreq2, y * m_HeightFreq2) * m_HeightAmp2; + float oct3 = m_Noise.CubicNoise2D(x * m_HeightFreq3, y * m_HeightFreq3) * m_HeightAmp3; + + float height = m_Noise.CubicNoise2D(x * 0.1f, y * 0.1f ) * 2; + + float flatness = ((m_Noise.CubicNoise2D(x * 0.5f, y * 0.5f) + 1.f) * 0.5f) * 1.1f; // 0 ... 1.5 + flatness *= flatness * flatness; + + return (oct1 + oct2 + oct3) * flatness + height; +} + + + + + +void cHeiGenClassic::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +{ + for (int z = 0; z < cChunkDef::Width; z++) + { + const float zz = (float)(a_ChunkZ * cChunkDef::Width + z); + for (int x = 0; x < cChunkDef::Width; x++) + { + const float xx = (float)(a_ChunkX * cChunkDef::Width + x); + + int hei = 64 + (int)(GetNoise(xx * 0.05f, zz * 0.05f) * 16); + if (hei < 10) + { + hei = 10; + } + if (hei > 250) + { + hei = 250; + } + cChunkDef::SetHeight(a_HeightMap, x , z, hei); + } // for x + } // for z +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cHeiGenBiomal: + +const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[biNumBiomes] = +{ + /* Fast-changing | Middle-changing | Slow-changing |*/ + /* Biome | Freq1 | Amp1 | Freq2 | Amp2 | Freq3 | Amp3 | BaseHeight */ + /* biOcean */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // done + /* biPlains */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done + /* biDesert */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done + /* biExtremeHills */ { 0.2f, 4.0f, 0.05f, 20.0f, 0.01f, 16.0f, 100}, // done + /* biForest */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // done + /* biTaiga */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // done + /* biSwampland */ { 0.1f, 1.1f, 0.05f, 1.5f, 0.02f, 2.5f, 61.5}, // done + /* biRiver */ { 0.2f, 3.0f, 0.05f, 1.0f, 0.01f, 1.0f, 56}, // done + /* biNether */ { 0.1f, 0.0f, 0.01f, 0.0f, 0.01f, 0.0f, 0}, // Unused, but must be here due to indexing + /* biSky */ { 0.1f, 0.0f, 0.01f, 0.0f, 0.01f, 0.0f, 0}, // Unused, but must be here due to indexing + /* biFrozenOcean */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // done + /* biFrozenRiver */ { 0.2f, 3.0f, 0.05f, 1.0f, 0.01f, 1.0f, 56}, // done + /* biIcePlains */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done + /* biIceMountains */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80}, // done + /* biMushroomIsland */ { 0.1f, 2.0f, 0.05f, 8.0f, 0.01f, 6.0f, 80}, // done + /* biMushroomShore */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 64}, // done + /* biBeach */ { 0.1f, 0.5f, 0.05f, 1.0f, 0.01f, 1.0f, 64}, // done + /* biDesertHills */ { 0.2f, 2.0f, 0.05f, 5.0f, 0.01f, 4.0f, 75}, // done + /* biForestHills */ { 0.2f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done + /* biTaigaHills */ { 0.2f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done + /* biExtremeHillsEdge */ { 0.2f, 3.0f, 0.05f, 16.0f, 0.01f, 12.0f, 80}, // done + /* biJungle */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // done + /* biJungleHills */ { 0.2f, 3.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done +} ; + + + + + +void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) +{ + // Generate a 3x3 chunk area of biomes around this chunk: + BiomeNeighbors Biomes; + for (int z = -1; z <= 1; z++) + { + for (int x = -1; x <= 1; x++) + { + m_BiomeGen.GenBiomes(a_ChunkX + x, a_ChunkZ + z, Biomes[x + 1][z + 1]); + } // for x + } // for z + + // For each height, go through neighboring biomes and add up their idea of height: + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x++) + { + cChunkDef::SetHeight(a_HeightMap, x, z, GetHeightAt(x, z, a_ChunkX, a_ChunkZ, Biomes)); + } // for x + } +} + + + + + +HEIGHTTYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, int a_ChunkZ, const cHeiGenBiomal::BiomeNeighbors & a_BiomeNeighbors) +{ + // Sum up how many biomes of each type there are in the neighborhood: + int BiomeCounts[biNumBiomes]; + memset(BiomeCounts, 0, sizeof(BiomeCounts)); + int Sum = 0; + for (int z = -8; z <= 8; z++) + { + int FinalZ = a_RelZ + z + cChunkDef::Width; + int IdxZ = FinalZ / cChunkDef::Width; + int ModZ = FinalZ % cChunkDef::Width; + int WeightZ = 9 - abs(z); + for (int x = -8; x <= 8; x++) + { + int FinalX = a_RelX + x + cChunkDef::Width; + int IdxX = FinalX / cChunkDef::Width; + int ModX = FinalX % cChunkDef::Width; + EMCSBiome Biome = cChunkDef::GetBiome(a_BiomeNeighbors[IdxX][IdxZ], ModX, ModZ); + if ((Biome < 0) || (Biome >= ARRAYCOUNT(BiomeCounts))) + { + continue; + } + int WeightX = 9 - abs(x); + BiomeCounts[Biome] += WeightX + WeightZ; + Sum += WeightX + WeightZ; + } // for x + } // for z + + // For each biome type that has a nonzero count, calc its height and add it: + if (Sum > 0) + { + int Height = 0; + int BlockX = a_ChunkX * cChunkDef::Width + a_RelX; + int BlockZ = a_ChunkZ * cChunkDef::Width + a_RelZ; + for (int i = 0; i < ARRAYCOUNT(BiomeCounts); i++) + { + if (BiomeCounts[i] == 0) + { + continue; + } + float oct1 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq1, BlockZ * m_GenParam[i].m_HeightFreq1) * m_GenParam[i].m_HeightAmp1; + float oct2 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq2, BlockZ * m_GenParam[i].m_HeightFreq2) * m_GenParam[i].m_HeightAmp2; + float oct3 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq3, BlockZ * m_GenParam[i].m_HeightFreq3) * m_GenParam[i].m_HeightAmp3; + Height += BiomeCounts[i] * (int)(m_GenParam[i].m_BaseHeight + oct1 + oct2 + oct3); + } + int res = (HEIGHTTYPE)(Height / Sum); + return std::min(250, std::max(res, 5)); + } + + // No known biome around? Weird. Return a bogus value: + ASSERT(!"cHeiGenBiomal: Biome sum failed, no known biome around"); + return 5; +} + + + + + diff --git a/source/HeiGen.h b/source/HeiGen.h index d3074487f..e5b20c334 100644 --- a/source/HeiGen.h +++ b/source/HeiGen.h @@ -1,137 +1,137 @@ -
-// HeiGen.h
-
-/*
-Interfaces to the various height generators:
- - cHeiGenFlat
- - cHeiGenClassic
- - cHeiGenBiomal
-*/
-
-
-
-
-
-#pragma once
-
-#include "cChunkGenerator.h"
-#include "cNoise.h"
-
-
-
-
-
-class cHeiGenFlat :
- public cTerrainHeightGen
-{
-public:
- cHeiGenFlat(int a_Height) : m_Height(a_Height) {}
-
-protected:
-
- int m_Height;
-
- // cTerrainHeightGen override:
- virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
-} ;
-
-
-
-
-
-/// A simple cache that stores N most recently generated chunks' heightmaps; N being settable upon creation
-class cHeiGenCache :
- public cTerrainHeightGen
-{
-public:
- cHeiGenCache(cTerrainHeightGen * a_HeiGenToCache, int a_CacheSize); // Takes ownership of a_HeiGenToCache
- ~cHeiGenCache();
-
-protected:
-
- cTerrainHeightGen * m_HeiGenToCache;
-
- struct sCacheData
- {
- int m_ChunkX;
- int m_ChunkZ;
- cChunkDef::HeightMap m_HeightMap;
- } ;
-
- // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data
- int m_CacheSize;
- int * m_CacheOrder; // MRU-ized order, indices into m_CacheData array
- sCacheData * m_CacheData; // m_CacheData[m_CacheOrder[0]] is the most recently used
-
- // Cache statistics
- int m_NumHits;
- int m_NumMisses;
- int m_TotalChain; // Number of cache items walked to get to a hit (only added for hits)
-
- virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
-} ;
-
-
-
-
-
-class cHeiGenClassic :
- public cTerrainHeightGen
-{
-public:
- cHeiGenClassic(int a_Seed, float a_HeightFreq1, float a_HeightAmp1, float a_HeightFreq2, float a_HeightAmp2, float a_HeightFreq3, float a_HeightAmp3);
-
-protected:
-
- int m_Seed;
- cNoise m_Noise;
- float m_HeightFreq1, m_HeightAmp1;
- float m_HeightFreq2, m_HeightAmp2;
- float m_HeightFreq3, m_HeightAmp3;
-
- float GetNoise(float x, float y);
-
- // cTerrainHeightGen override:
- virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
-} ;
-
-
-
-
-
-class cHeiGenBiomal :
- public cTerrainHeightGen
-{
-public:
- cHeiGenBiomal(int a_Seed, cBiomeGen & a_BiomeGen) :
- m_Noise(a_Seed),
- m_BiomeGen(a_BiomeGen)
- {
- }
-
-protected:
-
- typedef cChunkDef::BiomeMap BiomeNeighbors[3][3];
-
- cNoise m_Noise;
- cBiomeGen & m_BiomeGen;
-
- // Per-biome terrain generator parameters:
- struct sGenParam
- {
- float m_HeightFreq1, m_HeightAmp1;
- float m_HeightFreq2, m_HeightAmp2;
- float m_HeightFreq3, m_HeightAmp3;
- float m_BaseHeight;
- } ;
- static const sGenParam m_GenParam[biNumBiomes];
-
- // cTerrainHeightGen override:
- virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
-
- HEIGHTTYPE GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, int a_ChunkZ, const BiomeNeighbors & a_BiomeNeighbors);
-} ;
-
-
-
-
+ +// HeiGen.h + +/* +Interfaces to the various height generators: + - cHeiGenFlat + - cHeiGenClassic + - cHeiGenBiomal +*/ + + + + + +#pragma once + +#include "cChunkGenerator.h" +#include "cNoise.h" + + + + + +class cHeiGenFlat : + public cTerrainHeightGen +{ +public: + cHeiGenFlat(int a_Height) : m_Height(a_Height) {} + +protected: + + int m_Height; + + // cTerrainHeightGen override: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; +} ; + + + + + +/// A simple cache that stores N most recently generated chunks' heightmaps; N being settable upon creation +class cHeiGenCache : + public cTerrainHeightGen +{ +public: + cHeiGenCache(cTerrainHeightGen * a_HeiGenToCache, int a_CacheSize); // Takes ownership of a_HeiGenToCache + ~cHeiGenCache(); + +protected: + + cTerrainHeightGen * m_HeiGenToCache; + + struct sCacheData + { + int m_ChunkX; + int m_ChunkZ; + cChunkDef::HeightMap m_HeightMap; + } ; + + // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data + int m_CacheSize; + int * m_CacheOrder; // MRU-ized order, indices into m_CacheData array + sCacheData * m_CacheData; // m_CacheData[m_CacheOrder[0]] is the most recently used + + // Cache statistics + int m_NumHits; + int m_NumMisses; + int m_TotalChain; // Number of cache items walked to get to a hit (only added for hits) + + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; +} ; + + + + + +class cHeiGenClassic : + public cTerrainHeightGen +{ +public: + cHeiGenClassic(int a_Seed, float a_HeightFreq1, float a_HeightAmp1, float a_HeightFreq2, float a_HeightAmp2, float a_HeightFreq3, float a_HeightAmp3); + +protected: + + int m_Seed; + cNoise m_Noise; + float m_HeightFreq1, m_HeightAmp1; + float m_HeightFreq2, m_HeightAmp2; + float m_HeightFreq3, m_HeightAmp3; + + float GetNoise(float x, float y); + + // cTerrainHeightGen override: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; +} ; + + + + + +class cHeiGenBiomal : + public cTerrainHeightGen +{ +public: + cHeiGenBiomal(int a_Seed, cBiomeGen & a_BiomeGen) : + m_Noise(a_Seed), + m_BiomeGen(a_BiomeGen) + { + } + +protected: + + typedef cChunkDef::BiomeMap BiomeNeighbors[3][3]; + + cNoise m_Noise; + cBiomeGen & m_BiomeGen; + + // Per-biome terrain generator parameters: + struct sGenParam + { + float m_HeightFreq1, m_HeightAmp1; + float m_HeightFreq2, m_HeightAmp2; + float m_HeightFreq3, m_HeightAmp3; + float m_BaseHeight; + } ; + static const sGenParam m_GenParam[biNumBiomes]; + + // cTerrainHeightGen override: + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; + + HEIGHTTYPE GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, int a_ChunkZ, const BiomeNeighbors & a_BiomeNeighbors); +} ; + + + + diff --git a/source/LeakFinder.cpp b/source/LeakFinder.cpp index 1490025f8..769b52222 100644 --- a/source/LeakFinder.cpp +++ b/source/LeakFinder.cpp @@ -1,1040 +1,1040 @@ -
-// LeakFinder.cpp
-
-// Finds memory leaks rather effectively
-
-// _X: downloaded from http://www.codeproject.com/Articles/3134/Memory-Leak-and-Exception-Trace-CRT-and-COM-Leaks - the real link is in the comments, RC11 version
-
-
-
-
-
-/**********************************************************************
- *
- * LEAKFINDER.CPP
- *
- *
- *
- * History:
- * 2010-04-15 RC10 - Updated to VC10 RTM
- * Fixed Bug: Application Verifier, thanks to handsinmypocket!
- * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=3439751#xx3439751xx
- * 2008-08-04 RC6 - Updated to VC9 RTM
- * Fixed Bug: Missing "ole32.lib" LIB
- * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2253980#xx2253980xx
- * Fixed Bug: Compiled with "WIN32_LEAN_AND_MEAN"
- * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=1824718#xx1824718xx
- * Fixed Bug: Compiling with "/Wall"
- * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2638243#xx2638243xx
- * Removed "#pragma init_seg (compiler)" from h-file
- *
- * 2005-12-30 RC5 - Now again VC8 RTM compatible
- * - Added Xml-Output (like in the old Leakfinder)
- * YOu need to define XML_LEAK_FINDER to activate it
- * So you can use the LeakAnalyseTool from
- * http://www.codeproject.com/tools/leakfinder.asp
- *
- * 2005-12-13 RC4 - Merged with the new "StackWalker"-project on
- * http://www.codeproject.com/threads/StackWalker.asp
- *
- * 2005-08-01 RC3 - Merged with the new "StackWalker"-project on
- * http://www.codeproject.com/threads/StackWalker.asp
- *
- * 2005-07-05 RC2 - First version with x86, IA64 and x64 support
- *
- * 2005-07-04 RC1 - Added "OutputOptions"
- * - New define "INIT_LEAK_FINDER_VERBOSE" to
- * display more info (for error reporting)
- *
- * 2005-07-01 Beta3 - Workaround for a bug in the new dbghelp.dll
- * (version 6.5.3.7 from 2005-05-30; StakWalk64 no
- * refused to produce an callstack on x86 systems
- * if the context is NULL or has some registers set
- * to 0 (for example Esp). This is against the
- * documented behaviour of StackWalk64...)
- * - First version with x64-support
- *
- * 2005-06-16 Beta1 First public release with the following features:
- * - Completely rewritten in C++ (object oriented)
- * - CRT-Leak-Report
- * - COM-Leak-Report
- * - Report is done via "OutputDebugString" so
- * the line can directly selected in the debugger
- * and is opening the corresponding file/line of
- * the allocation
- * - Tried to support x64 systems, bud had some
- * trouble wih StackWalk64
- * See: http://blog.kalmbachnet.de/?postid=43
- *
- * LICENSE (http://www.opensource.org/licenses/bsd-license.php)
- *
- * Copyright (c) 2005-2010, Jochen Kalmbach
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * Neither the name of Jochen Kalmbach nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **********************************************************************/
-
-#include <windows.h>
-#include <objidl.h> // Needed if compiled with "WIN32_LEAN_AND_MEAN"
-#include <tchar.h>
-#include <crtdbg.h>
-#include <stdio.h>
-
-#include <string>
-#include <vector>
-
-
-#include "LeakFinder.h"
-
-// Currently only tested with MS VC++ 5 to 10
-#if (_MSC_VER < 1100) || (_MSC_VER > 1600)
-#error Only MS VC++ 5/6/7/7.1/8/9 supported. Check if the '_CrtMemBlockHeader' has not changed with this compiler!
-#endif
-
-
-// Controlling the callstack depth
-#define MAX_CALLSTACK_LEN_BUF 0x2000
-
-#define IGNORE_CRT_ALLOC
-
-// disable 64-bit compatibility-checks (because we explicite have here either x86 or x64!)
-#pragma warning(disable:4312) // warning C4312: 'type cast' : conversion from 'DWORD' to 'LPCVOID' of greater size
-#pragma warning(disable:4826)
-
-
-// secure-CRT_functions are only available starting with VC8
-#if _MSC_VER < 1400
-#define _snprintf_s _snprintf
-#define _tcscat_s _tcscat
-#endif
-
-static std::string SimpleXMLEncode(LPCSTR szText)
-{
- std::string szRet;
- for (size_t i=0; i<strlen(szText); i++)
- {
- switch(szText[i])
- {
- case '&':
- szRet.append("&");
- break;
- case '<':
- szRet.append("<");
- break;
- case '>':
- szRet.append(">");
- break;
- case '"':
- szRet.append(""");
- break;
- case '\'':
- szRet.append("'");
- break;
- default:
- szRet += szText[i];
- }
- }
- return szRet;
-}
-
-
-LeakFinderOutput::LeakFinderOutput(int options, LPCSTR szSymPath)
- : StackWalker(options, szSymPath)
-{
-}
-void LeakFinderOutput::OnLeakSearchStart(LPCSTR szLeakFinderName)
-{
- CHAR buffer[1024];
- _snprintf_s(buffer, 1024, "######## %s ########\n", szLeakFinderName);
- this->OnOutput(buffer);
-}
-void LeakFinderOutput::OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize)
-{
- CHAR buffer[1024];
- _snprintf_s(buffer, 1024, "--------------- Key: %s, %d bytes ---------\n", szKeyName, nDataSize);
- this->OnOutput(buffer);
-}
-void LeakFinderOutput::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry)
-{
- if ( (eType != lastEntry) && (entry.offset != 0) )
- {
- if ( ((this->m_options & LeakFinderShowCompleteCallstack) == 0) && (
- (strstr(entry.lineFileName, "afxmem.cpp") != NULL) ||
- (strstr(entry.lineFileName, "dbgheap.c") != NULL) ||
- (strstr(entry.lineFileName, "new.cpp") != NULL) ||
- (strstr(entry.lineFileName, "newop.cpp") != NULL) ||
- (strstr(entry.lineFileName, "leakfinder.cpp") != NULL) ||
- (strstr(entry.lineFileName, "stackwalker.cpp") != NULL)
- ) )
- {
- return;
- }
- }
- StackWalker::OnCallstackEntry(eType, entry);
-}
-
-
-// ####################################################################
-// XML-Output
-LeakFinderXmlOutput::LeakFinderXmlOutput()
-{
- TCHAR szXMLFileName[1024];
-
- GetModuleFileName(NULL, szXMLFileName, sizeof(szXMLFileName) / sizeof(TCHAR));
- _tcscat_s(szXMLFileName, _T(".mem.xml-leaks"));
-#if _MSC_VER < 1400
- m_fXmlFile = _tfopen(szXMLFileName, _T("w"));
-#else
- m_fXmlFile = NULL;
- _tfopen_s(&m_fXmlFile, szXMLFileName, _T("w"));
-#endif
- if (m_fXmlFile != NULL)
- {
- SYSTEMTIME st;
- GetLocalTime(&st);
- fprintf(m_fXmlFile, "<MEMREPORT date=\"%.2d/%.2d/%.4d\" time=\"%.2d:%.2d:%.2d\">\n",
- st.wMonth, st.wDay, st.wYear,
- st.wHour, st.wMinute, st.wSecond);
- }
- else
- {
- MessageBox(NULL, _T("Could not open xml-logfile for leakfinder!"), _T("Warning"), MB_ICONHAND);
- }
-}
-LeakFinderXmlOutput::LeakFinderXmlOutput(LPCTSTR szFileName)
-{
-#if _MSC_VER < 1400
- m_fXmlFile = _tfopen(szFileName, _T("w"));
-#else
- m_fXmlFile = NULL;
- _tfopen_s(&m_fXmlFile, szFileName, _T("w"));
-#endif
- if (m_fXmlFile == NULL)
- {
- MessageBox(NULL, _T("Could not open xml-logfile for leakfinder!"), _T("Warning"), MB_ICONHAND);
- }
-}
-LeakFinderXmlOutput::~LeakFinderXmlOutput()
-{
- if (m_fXmlFile != NULL)
- {
- // Write the ending-tags and close the file
- fprintf(m_fXmlFile, "</MEMREPORT>\n");
- fclose(m_fXmlFile);
- }
- m_fXmlFile = NULL;
-}
-void LeakFinderXmlOutput::OnLeakSearchStart(LPCSTR sszLeakFinderName)
-{
-}
-void LeakFinderXmlOutput::OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize)
-{
- if (m_fXmlFile != NULL)
- {
- fprintf(m_fXmlFile, " <LEAK requestID=\"%s\" size=\"%d\">\n", SimpleXMLEncode(szKeyName).c_str(), nDataSize);
- }
-}
-void LeakFinderXmlOutput::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry)
-{
- if (m_fXmlFile != NULL)
- {
- if (eType != lastEntry)
- {
- fprintf(m_fXmlFile, " <STACKENTRY decl=\"%s\" decl_offset=\"%+ld\" ", SimpleXMLEncode(entry.undName).c_str(), entry.offsetFromSmybol);
- fprintf(m_fXmlFile, "srcfile=\"%s\" line=\"%d\" line_offset=\"%+ld\" ", SimpleXMLEncode(entry.lineFileName).c_str(), entry.lineNumber, entry.offsetFromLine);
- fprintf(m_fXmlFile, "module=\"%s\" base=\"%08lx\" ", SimpleXMLEncode(entry.moduleName).c_str(), entry.baseOfImage);
- fprintf(m_fXmlFile, "/>\n");
- }
- else
- {
- fprintf(m_fXmlFile, " </LEAK>\n");
- }
- }
-}
-
-// ##########################################################################
-// ##########################################################################
-// ##########################################################################
-// Base class for storing contexts in a hashtable
-template <typename HASHTABLE_KEY> class ContextHashtableBase
-{
-public:
- ContextHashtableBase(SIZE_T sizeOfHastable, LPCSTR finderName)
- {
- SIZE_T s = sizeOfHastable*sizeof(AllocHashEntryType);
- m_hHeap = HeapCreate(0, 10*1024 + s, 0);
- if (m_hHeap == NULL)
- throw;
- pAllocHashTable = (AllocHashEntryType*) own_malloc(s);
- sAllocEntries = sizeOfHastable;
- m_finderName = own_strdup(finderName);
- }
-
-protected:
- virtual ~ContextHashtableBase()
- {
- if (pAllocHashTable != NULL)
- own_free(pAllocHashTable);
- pAllocHashTable = NULL;
-
- own_free(m_finderName);
- m_finderName = NULL;
-
- if (m_hHeap != NULL)
- HeapDestroy(m_hHeap);
- }
-
- __inline LPVOID own_malloc(SIZE_T size)
- {
- return HeapAlloc(m_hHeap, HEAP_ZERO_MEMORY, size);
- }
- __inline VOID own_free(LPVOID memblock)
- {
- HeapFree(m_hHeap, 0, memblock);
- }
- __inline CHAR *own_strdup(const char *str)
- {
- size_t len = strlen(str)+1;
- CHAR *c = (CHAR*)own_malloc(len);
-#if _MSC_VER >= 1400
- strcpy_s(c, len, str);
-#else
- strcpy(c, str);
-#endif
- return c;
- }
-
- // Disables this leak-finder
- virtual LONG Disable() = 0;
- // enables the leak-finder again...
- virtual LONG Enable() = 0;
-
-private:
- // Entry for each allocation
- typedef struct AllocHashEntryType {
- HASHTABLE_KEY key;
- SIZE_T nDataSize; // Size of the allocated memory
- struct AllocHashEntryType *Next;
- CONTEXT c;
- PVOID pStackBaseAddr;
- SIZE_T nMaxStackSize;
-
- PVOID pCallstackOffset;
- SIZE_T nCallstackLen;
- char pcCallstackAddr[MAX_CALLSTACK_LEN_BUF]; // min of both values...
- } AllocHashEntryType;
-
-protected:
- virtual SIZE_T HashFunction(HASHTABLE_KEY &key) = 0;
- virtual BOOL IsKeyEmpty(HASHTABLE_KEY &key) = 0;
- virtual VOID SetEmptyKey(HASHTABLE_KEY &key) = 0;
- virtual VOID GetKeyAsString(HASHTABLE_KEY &key, CHAR *szName, SIZE_T nBufferLen) = 0;
- //virtual SIZE_T GetNativeBytes(HASHTABLE_KEY &key, CHAR *szName, SIZE_T nBufferLen) { return 0; }
-
-public:
- VOID Insert(HASHTABLE_KEY &key, CONTEXT &context, SIZE_T nDataSize)
- {
- SIZE_T HashIdx;
- AllocHashEntryType *pHashEntry;
-
- // generate hash-value
- HashIdx = HashFunction(key);
-
- pHashEntry = &pAllocHashTable[HashIdx];
- if (IsKeyEmpty(pHashEntry->key) != FALSE) {
- // Entry is empty...
- }
- else {
- // Entry is not empy! make a list of entries for this hash value...
- while(pHashEntry->Next != NULL) {
- pHashEntry = pHashEntry->Next;
- }
-
- pHashEntry->Next = (AllocHashEntryType*) own_malloc(sizeof(AllocHashEntryType));
- pHashEntry = pHashEntry->Next;
- }
- pHashEntry->key = key;
- pHashEntry->nDataSize = nDataSize;
- pHashEntry->Next = NULL;
-#ifdef _M_IX86
- pHashEntry->pCallstackOffset = (LPVOID) min(context.Ebp, context.Esp);
-#elif _M_X64
- pHashEntry->pCallstackOffset = (LPVOID) min(context.Rdi, context.Rsp);
-#elif _M_IA64
- pHashEntry->pCallstackOffset = (LPVOID) min(context.IntSp, context.RsBSP);
-#else
-#error "Platform not supported!"
-#endif
- pHashEntry->c = context;
-
- // Query the max. stack-area:
- MEMORY_BASIC_INFORMATION MemBuffer;
- if(VirtualQuery((LPCVOID) pHashEntry->pCallstackOffset, &MemBuffer, sizeof(MemBuffer)) > 0)
- {
- pHashEntry->pStackBaseAddr = MemBuffer.BaseAddress;
- pHashEntry->nMaxStackSize = MemBuffer.RegionSize;
- }
- else
- {
- pHashEntry->pStackBaseAddr = 0;
- pHashEntry->nMaxStackSize = 0;
- }
-
- SIZE_T bytesToRead = MAX_CALLSTACK_LEN_BUF;
- if (pHashEntry->nMaxStackSize > 0)
- {
- SIZE_T len = ((SIZE_T) pHashEntry->pStackBaseAddr + pHashEntry->nMaxStackSize) - (SIZE_T)pHashEntry->pCallstackOffset;
- bytesToRead = min(len, MAX_CALLSTACK_LEN_BUF);
- }
- // Now read the callstack:
- if (ReadProcessMemory(GetCurrentProcess(), (LPCVOID) pHashEntry->pCallstackOffset, &(pHashEntry->pcCallstackAddr), bytesToRead, &(pHashEntry->nCallstackLen)) == 0)
- {
- // Could not read memory...
- pHashEntry->nCallstackLen = 0;
- pHashEntry->pCallstackOffset = 0;
- } // read callstack
- } // Insert
-
- BOOL Remove(HASHTABLE_KEY &key)
- {
- SIZE_T HashIdx;
- AllocHashEntryType *pHashEntry, *pHashEntryLast;
-
- // get the Hash-Value
- HashIdx = HashFunction(key);
-
- pHashEntryLast = NULL;
- pHashEntry = &pAllocHashTable[HashIdx];
- while(pHashEntry != NULL) {
- if (pHashEntry->key == key) {
- // release my memory
- if (pHashEntryLast == NULL) {
- // It is an entry in the table, so do not release this memory
- if (pHashEntry->Next == NULL) {
- // It was the last entry, so empty the table entry
- SetEmptyKey(pAllocHashTable[HashIdx].key);
- //memset(&pAllocHashTable[HashIdx], 0, sizeof(pAllocHashTable[HashIdx]));
- }
- else {
- // There are some more entries, so shorten the list
- AllocHashEntryType *pTmp = pHashEntry->Next;
- *pHashEntry = *(pHashEntry->Next);
- own_free(pTmp);
- }
- return TRUE;
- }
- else {
- // now, I am in an dynamic allocated entry (it was a collision)
- pHashEntryLast->Next = pHashEntry->Next;
- own_free(pHashEntry);
- return TRUE;
- }
- }
- pHashEntryLast = pHashEntry;
- pHashEntry = pHashEntry->Next;
- }
-
- // if we are here, we could not find the RequestID
- return FALSE;
- }
-
- AllocHashEntryType *Find(HASHTABLE_KEY &key)
- {
- SIZE_T HashIdx;
- AllocHashEntryType *pHashEntry;
-
- // get the Hash-Value
- HashIdx = HashFunction(key);
-
- pHashEntry = &pAllocHashTable[HashIdx];
- while(pHashEntry != NULL) {
- if (pHashEntry->key == key) {
- return pHashEntry;
- }
- pHashEntry = pHashEntry->Next;
- }
-
- // entry was not found!
- return NULL;
- }
-
- // For the followong static-var See comment in "ShowCallstack"...
- static BOOL CALLBACK ReadProcessMemoryFromHashEntry64(
- HANDLE hProcess, // hProcess must be a pointer to an hash-entry!
- DWORD64 lpBaseAddress,
- PVOID lpBuffer,
- DWORD nSize,
- LPDWORD lpNumberOfBytesRead,
- LPVOID pUserData // optional data, which was passed in "ShowCallstack"
- )
- {
- *lpNumberOfBytesRead = 0;
- AllocHashEntryType *pHashEntry = (AllocHashEntryType*) pUserData;
- if (pHashEntry == NULL)
- {
- return FALSE;
- }
-
- if ( ( (DWORD64)lpBaseAddress >= (DWORD64)pHashEntry->pCallstackOffset) && ((DWORD64)lpBaseAddress <= ((DWORD64)pHashEntry->pCallstackOffset+pHashEntry->nCallstackLen)) ) {
- // Memory is located in saved Callstack:
- // Calculate the offset
- DWORD dwOffset = (DWORD) ((DWORD64)lpBaseAddress - (DWORD64)pHashEntry->pCallstackOffset);
- DWORD dwSize = __min(nSize, MAX_CALLSTACK_LEN_BUF-dwOffset);
- memcpy(lpBuffer, &(pHashEntry->pcCallstackAddr[dwOffset]), dwSize);
- *lpNumberOfBytesRead = dwSize;
- if (dwSize != nSize)
- {
- return FALSE;
- }
- *lpNumberOfBytesRead = nSize;
- return TRUE;
- }
-
- if (*lpNumberOfBytesRead == 0) // Memory could not be found
- {
- if ( ( (DWORD64)lpBaseAddress < (DWORD64)pHashEntry->pStackBaseAddr) || ((DWORD64)lpBaseAddress > ((DWORD64)pHashEntry->pStackBaseAddr+pHashEntry->nMaxStackSize)) )
- {
- // Stackwalking is done by reading the "real memory" (normally this happens when the StackWalk64 tries to read some code)
- SIZE_T st = 0;
- BOOL bRet = ReadProcessMemory(hProcess, (LPCVOID) lpBaseAddress, lpBuffer, nSize, &st);
- *lpNumberOfBytesRead = (DWORD) st;
- return bRet;
- }
- }
-
- return TRUE;
- }
-
- VOID ShowLeaks(LeakFinderOutput &leakFinderOutput)
- {
- SIZE_T ulTemp;
- AllocHashEntryType *pHashEntry;
- ULONG ulCount = 0;
- SIZE_T ulLeaksByte = 0;
-
- leakFinderOutput.OnLeakSearchStart(this->m_finderName);
-
- // Move throu every entry
- CHAR keyName[1024];
- for(ulTemp = 0; ulTemp < this->sAllocEntries; ulTemp++) {
- pHashEntry = &pAllocHashTable[ulTemp];
- if (IsKeyEmpty(pHashEntry->key) == FALSE) {
- while(pHashEntry != NULL) {
- ulCount++;
- CONTEXT c;
- memcpy(&c, &(pHashEntry->c), sizeof(CONTEXT));
-
- this->GetKeyAsString(pHashEntry->key, keyName, 1024);
-
- leakFinderOutput.OnLeakStartEntry(keyName, pHashEntry->nDataSize);
- leakFinderOutput.ShowCallstack(GetCurrentThread(), &c, ReadProcessMemoryFromHashEntry64, pHashEntry);
-
- // Count the number of leaky bytes
- ulLeaksByte += pHashEntry->nDataSize;
-
- pHashEntry = pHashEntry->Next;
- } // while
- }
- }
- }
-
- AllocHashEntryType *pAllocHashTable;
- SIZE_T sAllocEntries;
- HANDLE m_hHeap;
- LPSTR m_finderName;
- bool m_bSupressUselessLines;
-}; // template <typename HASHTABLE_KEY> class ContextHashtableBase
-
-
-// ##########################################################################
-// ##########################################################################
-// ##########################################################################
-// Specialization for CRT-Leaks:
-// VC5 has excluded all types in release-builds
-#ifdef _DEBUG
-
-// The follwoing is copied from dbgint.h:
-// <CRT_INTERNALS>
-/*
-* For diagnostic purpose, blocks are allocated with extra information and
-* stored in a doubly-linked list. This makes all blocks registered with
-* how big they are, when they were allocated, and what they are used for.
-*/
-
-// forward declaration:
-#ifndef _M_CEE_PURE
-#define MyAllocHookCallingConvention __cdecl
-#endif
-#if _MSC_VER >= 1400
-#ifdef _M_CEE
-#define MyAllocHookCallingConvention __clrcall
-#endif
-#endif
-
-static int MyAllocHookCallingConvention MyAllocHook(int nAllocType, void *pvData,
- size_t nSize, int nBlockUse, long lRequest,
-#if _MSC_VER <= 1100 // Special case for VC 5 and before
- const char * szFileName,
-#else
- const unsigned char * szFileName,
-#endif
- int nLine);
-
-static _CRT_ALLOC_HOOK s_pfnOldCrtAllocHook = NULL;
-static LONG s_CrtDisableCount = 0;
-static LONG s_lMallocCalled = 0;
-
-
-class CRTTable : public ContextHashtableBase<LONG>
-{
-public:
- CRTTable() : ContextHashtableBase<LONG>(1021, "CRT-Leaks")
- {
- // save the previous alloc hook
- s_pfnOldCrtAllocHook = _CrtSetAllocHook(MyAllocHook);
- }
-
- virtual ~CRTTable()
- {
- _CrtSetAllocHook(s_pfnOldCrtAllocHook);
- }
-
- virtual LONG Disable()
- {
- return InterlockedIncrement(&s_CrtDisableCount);
- }
- virtual LONG Enable()
- {
- return InterlockedDecrement(&s_CrtDisableCount);
- }
-
- virtual SIZE_T HashFunction(LONG &key)
- {
- // I couldn´t find any better and faster
- return key % sAllocEntries;
- }
- virtual BOOL IsKeyEmpty(LONG &key)
- {
- if (key == 0)
- return TRUE;
- return FALSE;
- }
- virtual VOID SetEmptyKey(LONG &key)
- {
- key = 0;
- }
- virtual VOID GetKeyAsString(LONG &key, CHAR *szName, SIZE_T nBufferLen)
- {
-#if _MSC_VER < 1400
- _snprintf_s(szName, nBufferLen, "%d", key);
-#else
- _snprintf_s(szName, nBufferLen, nBufferLen, "%d", key);
-#endif
- }
-
-protected:
- CHAR *m_pBuffer;
- SIZE_T m_maxBufferLen;
- SIZE_T m_bufferLen;
-}; // class CRTTable
-
-
-#define nNoMansLandSize 4
-
-typedef struct _CrtMemBlockHeader
-{
- struct _CrtMemBlockHeader * pBlockHeaderNext;
- struct _CrtMemBlockHeader * pBlockHeaderPrev;
- char * szFileName;
- int nLine;
-#ifdef _WIN64
- /* These items are reversed on Win64 to eliminate gaps in the struct
- * and ensure that sizeof(struct)%16 == 0, so 16-byte alignment is
- * maintained in the debug heap.
- */
- int nBlockUse;
- size_t nDataSize;
-#else /* _WIN64 */
- size_t nDataSize;
- int nBlockUse;
-#endif /* _WIN64 */
- long lRequest;
- unsigned char gap[nNoMansLandSize];
- /* followed by:
- * unsigned char data[nDataSize];
- * unsigned char anotherGap[nNoMansLandSize];
- */
-} _CrtMemBlockHeader;
-#define pbData(pblock) ((unsigned char *)((_CrtMemBlockHeader *)pblock + 1))
-#define pHdr(pbData) (((_CrtMemBlockHeader *)pbData)-1)
-// </CRT_INTERNALS>
-
-static CRTTable *g_pCRTTable = NULL;
-
-
-// MyAllocHook is Single-Threaded, that means the the calls are serialized in the calling function!
-static int MyAllocHook(int nAllocType, void *pvData,
- size_t nSize, int nBlockUse, long lRequest,
-#if _MSC_VER <= 1100 // Special case for VC 5
- const char * szFileName,
-#else
- const unsigned char * szFileName,
-#endif
- int nLine)
-{
- //static TCHAR *operation[] = { _T(""), _T("ALLOCATIONG"), _T("RE-ALLOCATING"), _T("FREEING") };
- //static TCHAR *blockType[] = { _T("Free"), _T("Normal"), _T("CRT"), _T("Ignore"), _T("Client") };
-
-#ifdef IGNORE_CRT_ALLOC
- if (_BLOCK_TYPE(nBlockUse) == _CRT_BLOCK) // Ignore internal C runtime library allocations
- return TRUE;
-#endif
- extern int _crtDbgFlag;
- if ( ((_CRTDBG_ALLOC_MEM_DF & _crtDbgFlag) == 0) && ( (nAllocType == _HOOK_ALLOC) || (nAllocType == _HOOK_REALLOC) ) )
- {
- // Someone has disabled that the runtime should log this allocation
- // so we do not log this allocation
- if (s_pfnOldCrtAllocHook != NULL)
- s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine);
- return TRUE;
- }
-
- // Handle the Disable/Enable setting
- if (InterlockedExchangeAdd(&s_CrtDisableCount, 0) != 0)
- return TRUE;
-
- // Prevent from reentrat calls
- if (InterlockedIncrement(&s_lMallocCalled) > 1) { // I was already called
- InterlockedDecrement(&s_lMallocCalled);
- // call the previous alloc hook
- if (s_pfnOldCrtAllocHook != NULL)
- s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine);
- return TRUE;
- }
-
- _ASSERT( (nAllocType == _HOOK_ALLOC) || (nAllocType == _HOOK_REALLOC) || (nAllocType == _HOOK_FREE) );
- _ASSERT( ( _BLOCK_TYPE(nBlockUse) >= 0 ) && ( _BLOCK_TYPE(nBlockUse) < 5 ) );
-
- if (nAllocType == _HOOK_FREE) { // freeing
- // Try to get the header information
- if (_CrtIsValidHeapPointer(pvData)) { // it is a valid Heap-Pointer
- // get the ID
- _CrtMemBlockHeader *pHead;
- // get a pointer to memory block header
- pHead = pHdr(pvData);
- nSize = pHead->nDataSize;
- lRequest = pHead->lRequest; // This is the ID!
-
- if (pHead->nBlockUse == _IGNORE_BLOCK)
- {
- InterlockedDecrement(&s_lMallocCalled);
- if (s_pfnOldCrtAllocHook != NULL)
- s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine);
- return TRUE;
- }
- }
- if (lRequest != 0) { // RequestID was found
- g_pCRTTable->Remove(lRequest);
- }
- } // freeing
-
- if (nAllocType == _HOOK_REALLOC) { // re-allocating
- // Try to get the header information
- if (_CrtIsValidHeapPointer(pvData)) { // it is a valid Heap-Pointer
- BOOL bRet;
- LONG lReallocRequest;
- // get the ID
- _CrtMemBlockHeader *pHead;
- // get a pointer to memory block header
- pHead = pHdr(pvData);
- // Try to find the RequestID in the Hash-Table, mark it that it was freed
- lReallocRequest = pHead->lRequest;
- bRet = g_pCRTTable->Remove(lReallocRequest);
- } // ValidHeapPointer
- } // re-allocating
-
- //if ( (g_ulShowStackAtAlloc < 3) && (nAllocType == _HOOK_FREE) ) {
- if (nAllocType == _HOOK_FREE) {
- InterlockedDecrement(&s_lMallocCalled);
- // call the previous alloc hook
- if (s_pfnOldCrtAllocHook != NULL)
- s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine);
- return TRUE;
- }
-
- CONTEXT c;
- GET_CURRENT_CONTEXT(c, CONTEXT_FULL);
-
- // Only insert in the Hash-Table if it is not a "freeing"
- if (nAllocType != _HOOK_FREE) {
- if(lRequest != 0) // Always a valid RequestID should be provided (see comments in the header)
- g_pCRTTable->Insert(lRequest, c, nSize);
- }
-
- InterlockedDecrement(&s_lMallocCalled);
- // call the previous alloc hook
- if (s_pfnOldCrtAllocHook != NULL)
- s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine);
- return TRUE; // allow the memory operation to proceed
-} // MyAllocHook
-
-#endif // _DEBUG
-
-
-// ##########################################################################
-// ##########################################################################
-// ##########################################################################
-// Specialization for COM-Leaks:
-
-// forwards:
-class COMTable;
-class CMallocSpy : public IMallocSpy
-{
-public:
- CMallocSpy() { m_cbRequest = 0; m_cRef = 0; m_disableCount = 0; }
- virtual ~CMallocSpy() {}
- // IUnknown methods
- STDMETHOD(QueryInterface) (REFIID riid, LPVOID *ppUnk);
- STDMETHOD_(ULONG, AddRef) ();
- STDMETHOD_(ULONG, Release) ();
- // IMallocSpy methods
- STDMETHOD_(SIZE_T, PreAlloc) (SIZE_T cbRequest);
- STDMETHOD_(void *, PostAlloc) (void *pActual);
- STDMETHOD_(void *, PreFree) (void *pRequest, BOOL fSpyed);
- STDMETHOD_(void, PostFree) (BOOL fSpyed) { return; };
- STDMETHOD_(SIZE_T, PreRealloc) (void *pRequest, SIZE_T cbRequest, void **ppNewRequest, BOOL fSpyed);
- STDMETHOD_(void *, PostRealloc) (void *pActual, BOOL fSpyed);
- STDMETHOD_(void *, PreGetSize) (void *pRequest, BOOL fSpyed) { return pRequest; }
- STDMETHOD_(SIZE_T, PostGetSize) (SIZE_T cbActual, BOOL fSpyed) { return cbActual; }
- STDMETHOD_(void *, PreDidAlloc) (void *pRequest, BOOL fSpyed) { return pRequest; }
- STDMETHOD_(BOOL, PostDidAlloc) (void *pRequest, BOOL fSpyed, BOOL fActual) { return fActual; }
- STDMETHOD_(void, PreHeapMinimize) (void) { return; }
- STDMETHOD_(void, PostHeapMinimize) (void) { return; }
-private:
- LONG m_cRef;
- SIZE_T m_cbRequest;
-protected:
- COMTable *m_pComTable;
- LONG m_disableCount;
- friend COMTable;
-};
-
-class COMTable : public ContextHashtableBase<LPVOID>
-{
-public:
- COMTable() : ContextHashtableBase<LPVOID>(1021, "COM-Leaks")
- {
- m_pMallocSpy = new CMallocSpy(); // wird später durch Release freigegeben
- if (m_pMallocSpy != NULL)
- {
- m_pMallocSpy->m_pComTable = this;
- // CoInitilize(); // ??? Is this necessary ?
- HRESULT hr = CoRegisterMallocSpy(m_pMallocSpy);
- if FAILED(hr)
- {
- _tprintf(_T("\nCoRegisterMallocSpay failed with %.8x"), hr);
- }
- }
- }
-
- virtual ~COMTable()
- {
- if (m_pMallocSpy != NULL)
- m_pMallocSpy->m_pComTable = NULL;
- CoRevokeMallocSpy();
- }
-
- virtual LONG Disable()
- {
- return InterlockedIncrement(&(m_pMallocSpy->m_disableCount));
- }
- virtual LONG Enable()
- {
- return InterlockedDecrement(&(m_pMallocSpy->m_disableCount));
- }
-
- virtual SIZE_T HashFunction(LPVOID &key)
- {
- // I couldn´t find any better and faster
-#ifdef _M_IX86
-#if _MSC_VER > 1100
-#pragma warning (push)
-#endif
-#pragma warning (disable: 4311)
- DWORD llP = (DWORD) key;
-#if _MSC_VER > 1100
-#pragma warning (pop)
-#endif
-#else
- ULONGLONG llP = (ULONGLONG) key;
-#endif
- return (SIZE_T) llP % sAllocEntries;
- }
- virtual BOOL IsKeyEmpty(LPVOID &key)
- {
- if (key == 0)
- return TRUE;
- return FALSE;
- }
- virtual VOID SetEmptyKey(LPVOID &key)
- {
- key = 0;
- }
- virtual VOID GetKeyAsString(LPVOID &key, CHAR *szName, SIZE_T nBufferLen)
- {
-#if _MSC_VER < 1400
- _snprintf_s(szName, nBufferLen, "%p", key);
-#else
- _snprintf_s(szName, nBufferLen, nBufferLen, "%p", key);
-#endif
- }
-
- CMallocSpy *m_pMallocSpy;
- friend CMallocSpy;
-}; // class COMTable
-
-
-STDMETHODIMP CMallocSpy::QueryInterface(REFIID riid, LPVOID *ppUnk) {
- HRESULT hr = S_OK;
- if (IsEqualIID(riid, IID_IUnknown)) {
- *ppUnk = (IUnknown *) this;
- }
- else if (IsEqualIID(riid, IID_IMallocSpy)) {
- *ppUnk = (IMalloc *) this;
- }
- else {
- *ppUnk = NULL;
- hr = E_NOINTERFACE;
- }
- AddRef();
- return hr;
-}
-STDMETHODIMP_(ULONG) CMallocSpy::AddRef(void) {
- return (ULONG) InterlockedIncrement(&m_cRef);
-}
-STDMETHODIMP_(ULONG) CMallocSpy::Release(void) {
- LONG cRef;
- cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- {
- delete this;
- }
- return (ULONG) cRef;
-}
-// IMallocSpy methods
-STDMETHODIMP_(SIZE_T) CMallocSpy::PreAlloc(SIZE_T cbRequest) {
- m_cbRequest = cbRequest;
- return cbRequest;
-}
-STDMETHODIMP_(void *) CMallocSpy::PostAlloc(void *pActual) {
- if (m_pComTable != NULL)
- {
- CONTEXT c;
- GET_CURRENT_CONTEXT(c, CONTEXT_FULL);
- m_pComTable->Insert(pActual, c, m_cbRequest);
- }
- return pActual;
-}
-STDMETHODIMP_(void *) CMallocSpy::PreFree(void *pRequest, BOOL fSpyed) {
- if (m_pComTable != NULL)
- {
- m_pComTable->Remove(pRequest);
- }
- return pRequest;
-}
-STDMETHODIMP_(SIZE_T) CMallocSpy::PreRealloc(void *pRequest, SIZE_T cbRequest,
- void **ppNewRequest, BOOL fSpyed) {
- if (m_pComTable != NULL)
- {
- m_pComTable->Remove(pRequest);
- }
- *ppNewRequest = pRequest; // Bug fixed. Thanx to Christoph Weber
- return cbRequest;
-}
-STDMETHODIMP_(void *) CMallocSpy::PostRealloc(void *pActual, BOOL fSpyed) {
- if (m_pComTable != NULL)
- {
- CONTEXT c;
- GET_CURRENT_CONTEXT(c, CONTEXT_FULL);
- m_pComTable->Insert(pActual, c, m_cbRequest);
- }
- return pActual;
-}
-
-
-
-
-// ##########################################################################
-// ##########################################################################
-// ##########################################################################
-// Init/Deinit functions
-
-
-static COMTable *g_pCOMTable;
-HRESULT InitLeakFinder()
-{
- // _X: Disabled COM monitoring: g_pCOMTable = new COMTable();
-#ifdef _DEBUG
- g_pCRTTable = new CRTTable();
-#endif
- return S_OK;
-}
-
-void DeinitLeakFinder(LeakFinderOutput *output)
-{
- LeakFinderOutput *pLeakFinderOutput = output;
-
-#ifdef _DEBUG
- g_pCRTTable->Disable();
-#endif
- // _X: Disabled COM monitoring: g_pCOMTable->Disable();
-
- if (pLeakFinderOutput == NULL)
- pLeakFinderOutput = new LeakFinderOutput();
-
- // explicite load the modules:
- pLeakFinderOutput->LoadModules();
-
-#ifdef _DEBUG
- g_pCRTTable->ShowLeaks(*pLeakFinderOutput);
- if (g_pCRTTable != NULL)
- delete g_pCRTTable;
- g_pCRTTable = NULL;
-#endif
-
- /*
- // _X: Disabled COM monitoring:
- g_pCOMTable->ShowLeaks(*pLeakFinderOutput);
- if (g_pCOMTable != NULL)
- delete g_pCOMTable;
- g_pCOMTable = NULL;
- */
-
- if (output == NULL)
- delete pLeakFinderOutput;
-}
-void DeinitLeakFinder()
-{
- DeinitLeakFinder(NULL);
-}
+ +// LeakFinder.cpp + +// Finds memory leaks rather effectively + +// _X: downloaded from http://www.codeproject.com/Articles/3134/Memory-Leak-and-Exception-Trace-CRT-and-COM-Leaks - the real link is in the comments, RC11 version + + + + + +/********************************************************************** + * + * LEAKFINDER.CPP + * + * + * + * History: + * 2010-04-15 RC10 - Updated to VC10 RTM + * Fixed Bug: Application Verifier, thanks to handsinmypocket! + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=3439751#xx3439751xx + * 2008-08-04 RC6 - Updated to VC9 RTM + * Fixed Bug: Missing "ole32.lib" LIB + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2253980#xx2253980xx + * Fixed Bug: Compiled with "WIN32_LEAN_AND_MEAN" + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=1824718#xx1824718xx + * Fixed Bug: Compiling with "/Wall" + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2638243#xx2638243xx + * Removed "#pragma init_seg (compiler)" from h-file + * + * 2005-12-30 RC5 - Now again VC8 RTM compatible + * - Added Xml-Output (like in the old Leakfinder) + * YOu need to define XML_LEAK_FINDER to activate it + * So you can use the LeakAnalyseTool from + * http://www.codeproject.com/tools/leakfinder.asp + * + * 2005-12-13 RC4 - Merged with the new "StackWalker"-project on + * http://www.codeproject.com/threads/StackWalker.asp + * + * 2005-08-01 RC3 - Merged with the new "StackWalker"-project on + * http://www.codeproject.com/threads/StackWalker.asp + * + * 2005-07-05 RC2 - First version with x86, IA64 and x64 support + * + * 2005-07-04 RC1 - Added "OutputOptions" + * - New define "INIT_LEAK_FINDER_VERBOSE" to + * display more info (for error reporting) + * + * 2005-07-01 Beta3 - Workaround for a bug in the new dbghelp.dll + * (version 6.5.3.7 from 2005-05-30; StakWalk64 no + * refused to produce an callstack on x86 systems + * if the context is NULL or has some registers set + * to 0 (for example Esp). This is against the + * documented behaviour of StackWalk64...) + * - First version with x64-support + * + * 2005-06-16 Beta1 First public release with the following features: + * - Completely rewritten in C++ (object oriented) + * - CRT-Leak-Report + * - COM-Leak-Report + * - Report is done via "OutputDebugString" so + * the line can directly selected in the debugger + * and is opening the corresponding file/line of + * the allocation + * - Tried to support x64 systems, bud had some + * trouble wih StackWalk64 + * See: http://blog.kalmbachnet.de/?postid=43 + * + * LICENSE (http://www.opensource.org/licenses/bsd-license.php) + * + * Copyright (c) 2005-2010, Jochen Kalmbach + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of Jochen Kalmbach nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +#include <windows.h> +#include <objidl.h> // Needed if compiled with "WIN32_LEAN_AND_MEAN" +#include <tchar.h> +#include <crtdbg.h> +#include <stdio.h> + +#include <string> +#include <vector> + + +#include "LeakFinder.h" + +// Currently only tested with MS VC++ 5 to 10 +#if (_MSC_VER < 1100) || (_MSC_VER > 1600) +#error Only MS VC++ 5/6/7/7.1/8/9 supported. Check if the '_CrtMemBlockHeader' has not changed with this compiler! +#endif + + +// Controlling the callstack depth +#define MAX_CALLSTACK_LEN_BUF 0x2000 + +#define IGNORE_CRT_ALLOC + +// disable 64-bit compatibility-checks (because we explicite have here either x86 or x64!) +#pragma warning(disable:4312) // warning C4312: 'type cast' : conversion from 'DWORD' to 'LPCVOID' of greater size +#pragma warning(disable:4826) + + +// secure-CRT_functions are only available starting with VC8 +#if _MSC_VER < 1400 +#define _snprintf_s _snprintf +#define _tcscat_s _tcscat +#endif + +static std::string SimpleXMLEncode(LPCSTR szText) +{ + std::string szRet; + for (size_t i=0; i<strlen(szText); i++) + { + switch(szText[i]) + { + case '&': + szRet.append("&"); + break; + case '<': + szRet.append("<"); + break; + case '>': + szRet.append(">"); + break; + case '"': + szRet.append("""); + break; + case '\'': + szRet.append("'"); + break; + default: + szRet += szText[i]; + } + } + return szRet; +} + + +LeakFinderOutput::LeakFinderOutput(int options, LPCSTR szSymPath) + : StackWalker(options, szSymPath) +{ +} +void LeakFinderOutput::OnLeakSearchStart(LPCSTR szLeakFinderName) +{ + CHAR buffer[1024]; + _snprintf_s(buffer, 1024, "######## %s ########\n", szLeakFinderName); + this->OnOutput(buffer); +} +void LeakFinderOutput::OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize) +{ + CHAR buffer[1024]; + _snprintf_s(buffer, 1024, "--------------- Key: %s, %d bytes ---------\n", szKeyName, nDataSize); + this->OnOutput(buffer); +} +void LeakFinderOutput::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) +{ + if ( (eType != lastEntry) && (entry.offset != 0) ) + { + if ( ((this->m_options & LeakFinderShowCompleteCallstack) == 0) && ( + (strstr(entry.lineFileName, "afxmem.cpp") != NULL) || + (strstr(entry.lineFileName, "dbgheap.c") != NULL) || + (strstr(entry.lineFileName, "new.cpp") != NULL) || + (strstr(entry.lineFileName, "newop.cpp") != NULL) || + (strstr(entry.lineFileName, "leakfinder.cpp") != NULL) || + (strstr(entry.lineFileName, "stackwalker.cpp") != NULL) + ) ) + { + return; + } + } + StackWalker::OnCallstackEntry(eType, entry); +} + + +// #################################################################### +// XML-Output +LeakFinderXmlOutput::LeakFinderXmlOutput() +{ + TCHAR szXMLFileName[1024]; + + GetModuleFileName(NULL, szXMLFileName, sizeof(szXMLFileName) / sizeof(TCHAR)); + _tcscat_s(szXMLFileName, _T(".mem.xml-leaks")); +#if _MSC_VER < 1400 + m_fXmlFile = _tfopen(szXMLFileName, _T("w")); +#else + m_fXmlFile = NULL; + _tfopen_s(&m_fXmlFile, szXMLFileName, _T("w")); +#endif + if (m_fXmlFile != NULL) + { + SYSTEMTIME st; + GetLocalTime(&st); + fprintf(m_fXmlFile, "<MEMREPORT date=\"%.2d/%.2d/%.4d\" time=\"%.2d:%.2d:%.2d\">\n", + st.wMonth, st.wDay, st.wYear, + st.wHour, st.wMinute, st.wSecond); + } + else + { + MessageBox(NULL, _T("Could not open xml-logfile for leakfinder!"), _T("Warning"), MB_ICONHAND); + } +} +LeakFinderXmlOutput::LeakFinderXmlOutput(LPCTSTR szFileName) +{ +#if _MSC_VER < 1400 + m_fXmlFile = _tfopen(szFileName, _T("w")); +#else + m_fXmlFile = NULL; + _tfopen_s(&m_fXmlFile, szFileName, _T("w")); +#endif + if (m_fXmlFile == NULL) + { + MessageBox(NULL, _T("Could not open xml-logfile for leakfinder!"), _T("Warning"), MB_ICONHAND); + } +} +LeakFinderXmlOutput::~LeakFinderXmlOutput() +{ + if (m_fXmlFile != NULL) + { + // Write the ending-tags and close the file + fprintf(m_fXmlFile, "</MEMREPORT>\n"); + fclose(m_fXmlFile); + } + m_fXmlFile = NULL; +} +void LeakFinderXmlOutput::OnLeakSearchStart(LPCSTR sszLeakFinderName) +{ +} +void LeakFinderXmlOutput::OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize) +{ + if (m_fXmlFile != NULL) + { + fprintf(m_fXmlFile, " <LEAK requestID=\"%s\" size=\"%d\">\n", SimpleXMLEncode(szKeyName).c_str(), nDataSize); + } +} +void LeakFinderXmlOutput::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) +{ + if (m_fXmlFile != NULL) + { + if (eType != lastEntry) + { + fprintf(m_fXmlFile, " <STACKENTRY decl=\"%s\" decl_offset=\"%+ld\" ", SimpleXMLEncode(entry.undName).c_str(), entry.offsetFromSmybol); + fprintf(m_fXmlFile, "srcfile=\"%s\" line=\"%d\" line_offset=\"%+ld\" ", SimpleXMLEncode(entry.lineFileName).c_str(), entry.lineNumber, entry.offsetFromLine); + fprintf(m_fXmlFile, "module=\"%s\" base=\"%08lx\" ", SimpleXMLEncode(entry.moduleName).c_str(), entry.baseOfImage); + fprintf(m_fXmlFile, "/>\n"); + } + else + { + fprintf(m_fXmlFile, " </LEAK>\n"); + } + } +} + +// ########################################################################## +// ########################################################################## +// ########################################################################## +// Base class for storing contexts in a hashtable +template <typename HASHTABLE_KEY> class ContextHashtableBase +{ +public: + ContextHashtableBase(SIZE_T sizeOfHastable, LPCSTR finderName) + { + SIZE_T s = sizeOfHastable*sizeof(AllocHashEntryType); + m_hHeap = HeapCreate(0, 10*1024 + s, 0); + if (m_hHeap == NULL) + throw; + pAllocHashTable = (AllocHashEntryType*) own_malloc(s); + sAllocEntries = sizeOfHastable; + m_finderName = own_strdup(finderName); + } + +protected: + virtual ~ContextHashtableBase() + { + if (pAllocHashTable != NULL) + own_free(pAllocHashTable); + pAllocHashTable = NULL; + + own_free(m_finderName); + m_finderName = NULL; + + if (m_hHeap != NULL) + HeapDestroy(m_hHeap); + } + + __inline LPVOID own_malloc(SIZE_T size) + { + return HeapAlloc(m_hHeap, HEAP_ZERO_MEMORY, size); + } + __inline VOID own_free(LPVOID memblock) + { + HeapFree(m_hHeap, 0, memblock); + } + __inline CHAR *own_strdup(const char *str) + { + size_t len = strlen(str)+1; + CHAR *c = (CHAR*)own_malloc(len); +#if _MSC_VER >= 1400 + strcpy_s(c, len, str); +#else + strcpy(c, str); +#endif + return c; + } + + // Disables this leak-finder + virtual LONG Disable() = 0; + // enables the leak-finder again... + virtual LONG Enable() = 0; + +private: + // Entry for each allocation + typedef struct AllocHashEntryType { + HASHTABLE_KEY key; + SIZE_T nDataSize; // Size of the allocated memory + struct AllocHashEntryType *Next; + CONTEXT c; + PVOID pStackBaseAddr; + SIZE_T nMaxStackSize; + + PVOID pCallstackOffset; + SIZE_T nCallstackLen; + char pcCallstackAddr[MAX_CALLSTACK_LEN_BUF]; // min of both values... + } AllocHashEntryType; + +protected: + virtual SIZE_T HashFunction(HASHTABLE_KEY &key) = 0; + virtual BOOL IsKeyEmpty(HASHTABLE_KEY &key) = 0; + virtual VOID SetEmptyKey(HASHTABLE_KEY &key) = 0; + virtual VOID GetKeyAsString(HASHTABLE_KEY &key, CHAR *szName, SIZE_T nBufferLen) = 0; + //virtual SIZE_T GetNativeBytes(HASHTABLE_KEY &key, CHAR *szName, SIZE_T nBufferLen) { return 0; } + +public: + VOID Insert(HASHTABLE_KEY &key, CONTEXT &context, SIZE_T nDataSize) + { + SIZE_T HashIdx; + AllocHashEntryType *pHashEntry; + + // generate hash-value + HashIdx = HashFunction(key); + + pHashEntry = &pAllocHashTable[HashIdx]; + if (IsKeyEmpty(pHashEntry->key) != FALSE) { + // Entry is empty... + } + else { + // Entry is not empy! make a list of entries for this hash value... + while(pHashEntry->Next != NULL) { + pHashEntry = pHashEntry->Next; + } + + pHashEntry->Next = (AllocHashEntryType*) own_malloc(sizeof(AllocHashEntryType)); + pHashEntry = pHashEntry->Next; + } + pHashEntry->key = key; + pHashEntry->nDataSize = nDataSize; + pHashEntry->Next = NULL; +#ifdef _M_IX86 + pHashEntry->pCallstackOffset = (LPVOID) min(context.Ebp, context.Esp); +#elif _M_X64 + pHashEntry->pCallstackOffset = (LPVOID) min(context.Rdi, context.Rsp); +#elif _M_IA64 + pHashEntry->pCallstackOffset = (LPVOID) min(context.IntSp, context.RsBSP); +#else +#error "Platform not supported!" +#endif + pHashEntry->c = context; + + // Query the max. stack-area: + MEMORY_BASIC_INFORMATION MemBuffer; + if(VirtualQuery((LPCVOID) pHashEntry->pCallstackOffset, &MemBuffer, sizeof(MemBuffer)) > 0) + { + pHashEntry->pStackBaseAddr = MemBuffer.BaseAddress; + pHashEntry->nMaxStackSize = MemBuffer.RegionSize; + } + else + { + pHashEntry->pStackBaseAddr = 0; + pHashEntry->nMaxStackSize = 0; + } + + SIZE_T bytesToRead = MAX_CALLSTACK_LEN_BUF; + if (pHashEntry->nMaxStackSize > 0) + { + SIZE_T len = ((SIZE_T) pHashEntry->pStackBaseAddr + pHashEntry->nMaxStackSize) - (SIZE_T)pHashEntry->pCallstackOffset; + bytesToRead = min(len, MAX_CALLSTACK_LEN_BUF); + } + // Now read the callstack: + if (ReadProcessMemory(GetCurrentProcess(), (LPCVOID) pHashEntry->pCallstackOffset, &(pHashEntry->pcCallstackAddr), bytesToRead, &(pHashEntry->nCallstackLen)) == 0) + { + // Could not read memory... + pHashEntry->nCallstackLen = 0; + pHashEntry->pCallstackOffset = 0; + } // read callstack + } // Insert + + BOOL Remove(HASHTABLE_KEY &key) + { + SIZE_T HashIdx; + AllocHashEntryType *pHashEntry, *pHashEntryLast; + + // get the Hash-Value + HashIdx = HashFunction(key); + + pHashEntryLast = NULL; + pHashEntry = &pAllocHashTable[HashIdx]; + while(pHashEntry != NULL) { + if (pHashEntry->key == key) { + // release my memory + if (pHashEntryLast == NULL) { + // It is an entry in the table, so do not release this memory + if (pHashEntry->Next == NULL) { + // It was the last entry, so empty the table entry + SetEmptyKey(pAllocHashTable[HashIdx].key); + //memset(&pAllocHashTable[HashIdx], 0, sizeof(pAllocHashTable[HashIdx])); + } + else { + // There are some more entries, so shorten the list + AllocHashEntryType *pTmp = pHashEntry->Next; + *pHashEntry = *(pHashEntry->Next); + own_free(pTmp); + } + return TRUE; + } + else { + // now, I am in an dynamic allocated entry (it was a collision) + pHashEntryLast->Next = pHashEntry->Next; + own_free(pHashEntry); + return TRUE; + } + } + pHashEntryLast = pHashEntry; + pHashEntry = pHashEntry->Next; + } + + // if we are here, we could not find the RequestID + return FALSE; + } + + AllocHashEntryType *Find(HASHTABLE_KEY &key) + { + SIZE_T HashIdx; + AllocHashEntryType *pHashEntry; + + // get the Hash-Value + HashIdx = HashFunction(key); + + pHashEntry = &pAllocHashTable[HashIdx]; + while(pHashEntry != NULL) { + if (pHashEntry->key == key) { + return pHashEntry; + } + pHashEntry = pHashEntry->Next; + } + + // entry was not found! + return NULL; + } + + // For the followong static-var See comment in "ShowCallstack"... + static BOOL CALLBACK ReadProcessMemoryFromHashEntry64( + HANDLE hProcess, // hProcess must be a pointer to an hash-entry! + DWORD64 lpBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead, + LPVOID pUserData // optional data, which was passed in "ShowCallstack" + ) + { + *lpNumberOfBytesRead = 0; + AllocHashEntryType *pHashEntry = (AllocHashEntryType*) pUserData; + if (pHashEntry == NULL) + { + return FALSE; + } + + if ( ( (DWORD64)lpBaseAddress >= (DWORD64)pHashEntry->pCallstackOffset) && ((DWORD64)lpBaseAddress <= ((DWORD64)pHashEntry->pCallstackOffset+pHashEntry->nCallstackLen)) ) { + // Memory is located in saved Callstack: + // Calculate the offset + DWORD dwOffset = (DWORD) ((DWORD64)lpBaseAddress - (DWORD64)pHashEntry->pCallstackOffset); + DWORD dwSize = __min(nSize, MAX_CALLSTACK_LEN_BUF-dwOffset); + memcpy(lpBuffer, &(pHashEntry->pcCallstackAddr[dwOffset]), dwSize); + *lpNumberOfBytesRead = dwSize; + if (dwSize != nSize) + { + return FALSE; + } + *lpNumberOfBytesRead = nSize; + return TRUE; + } + + if (*lpNumberOfBytesRead == 0) // Memory could not be found + { + if ( ( (DWORD64)lpBaseAddress < (DWORD64)pHashEntry->pStackBaseAddr) || ((DWORD64)lpBaseAddress > ((DWORD64)pHashEntry->pStackBaseAddr+pHashEntry->nMaxStackSize)) ) + { + // Stackwalking is done by reading the "real memory" (normally this happens when the StackWalk64 tries to read some code) + SIZE_T st = 0; + BOOL bRet = ReadProcessMemory(hProcess, (LPCVOID) lpBaseAddress, lpBuffer, nSize, &st); + *lpNumberOfBytesRead = (DWORD) st; + return bRet; + } + } + + return TRUE; + } + + VOID ShowLeaks(LeakFinderOutput &leakFinderOutput) + { + SIZE_T ulTemp; + AllocHashEntryType *pHashEntry; + ULONG ulCount = 0; + SIZE_T ulLeaksByte = 0; + + leakFinderOutput.OnLeakSearchStart(this->m_finderName); + + // Move throu every entry + CHAR keyName[1024]; + for(ulTemp = 0; ulTemp < this->sAllocEntries; ulTemp++) { + pHashEntry = &pAllocHashTable[ulTemp]; + if (IsKeyEmpty(pHashEntry->key) == FALSE) { + while(pHashEntry != NULL) { + ulCount++; + CONTEXT c; + memcpy(&c, &(pHashEntry->c), sizeof(CONTEXT)); + + this->GetKeyAsString(pHashEntry->key, keyName, 1024); + + leakFinderOutput.OnLeakStartEntry(keyName, pHashEntry->nDataSize); + leakFinderOutput.ShowCallstack(GetCurrentThread(), &c, ReadProcessMemoryFromHashEntry64, pHashEntry); + + // Count the number of leaky bytes + ulLeaksByte += pHashEntry->nDataSize; + + pHashEntry = pHashEntry->Next; + } // while + } + } + } + + AllocHashEntryType *pAllocHashTable; + SIZE_T sAllocEntries; + HANDLE m_hHeap; + LPSTR m_finderName; + bool m_bSupressUselessLines; +}; // template <typename HASHTABLE_KEY> class ContextHashtableBase + + +// ########################################################################## +// ########################################################################## +// ########################################################################## +// Specialization for CRT-Leaks: +// VC5 has excluded all types in release-builds +#ifdef _DEBUG + +// The follwoing is copied from dbgint.h: +// <CRT_INTERNALS> +/* +* For diagnostic purpose, blocks are allocated with extra information and +* stored in a doubly-linked list. This makes all blocks registered with +* how big they are, when they were allocated, and what they are used for. +*/ + +// forward declaration: +#ifndef _M_CEE_PURE +#define MyAllocHookCallingConvention __cdecl +#endif +#if _MSC_VER >= 1400 +#ifdef _M_CEE +#define MyAllocHookCallingConvention __clrcall +#endif +#endif + +static int MyAllocHookCallingConvention MyAllocHook(int nAllocType, void *pvData, + size_t nSize, int nBlockUse, long lRequest, +#if _MSC_VER <= 1100 // Special case for VC 5 and before + const char * szFileName, +#else + const unsigned char * szFileName, +#endif + int nLine); + +static _CRT_ALLOC_HOOK s_pfnOldCrtAllocHook = NULL; +static LONG s_CrtDisableCount = 0; +static LONG s_lMallocCalled = 0; + + +class CRTTable : public ContextHashtableBase<LONG> +{ +public: + CRTTable() : ContextHashtableBase<LONG>(1021, "CRT-Leaks") + { + // save the previous alloc hook + s_pfnOldCrtAllocHook = _CrtSetAllocHook(MyAllocHook); + } + + virtual ~CRTTable() + { + _CrtSetAllocHook(s_pfnOldCrtAllocHook); + } + + virtual LONG Disable() + { + return InterlockedIncrement(&s_CrtDisableCount); + } + virtual LONG Enable() + { + return InterlockedDecrement(&s_CrtDisableCount); + } + + virtual SIZE_T HashFunction(LONG &key) + { + // I couldn´t find any better and faster + return key % sAllocEntries; + } + virtual BOOL IsKeyEmpty(LONG &key) + { + if (key == 0) + return TRUE; + return FALSE; + } + virtual VOID SetEmptyKey(LONG &key) + { + key = 0; + } + virtual VOID GetKeyAsString(LONG &key, CHAR *szName, SIZE_T nBufferLen) + { +#if _MSC_VER < 1400 + _snprintf_s(szName, nBufferLen, "%d", key); +#else + _snprintf_s(szName, nBufferLen, nBufferLen, "%d", key); +#endif + } + +protected: + CHAR *m_pBuffer; + SIZE_T m_maxBufferLen; + SIZE_T m_bufferLen; +}; // class CRTTable + + +#define nNoMansLandSize 4 + +typedef struct _CrtMemBlockHeader +{ + struct _CrtMemBlockHeader * pBlockHeaderNext; + struct _CrtMemBlockHeader * pBlockHeaderPrev; + char * szFileName; + int nLine; +#ifdef _WIN64 + /* These items are reversed on Win64 to eliminate gaps in the struct + * and ensure that sizeof(struct)%16 == 0, so 16-byte alignment is + * maintained in the debug heap. + */ + int nBlockUse; + size_t nDataSize; +#else /* _WIN64 */ + size_t nDataSize; + int nBlockUse; +#endif /* _WIN64 */ + long lRequest; + unsigned char gap[nNoMansLandSize]; + /* followed by: + * unsigned char data[nDataSize]; + * unsigned char anotherGap[nNoMansLandSize]; + */ +} _CrtMemBlockHeader; +#define pbData(pblock) ((unsigned char *)((_CrtMemBlockHeader *)pblock + 1)) +#define pHdr(pbData) (((_CrtMemBlockHeader *)pbData)-1) +// </CRT_INTERNALS> + +static CRTTable *g_pCRTTable = NULL; + + +// MyAllocHook is Single-Threaded, that means the the calls are serialized in the calling function! +static int MyAllocHook(int nAllocType, void *pvData, + size_t nSize, int nBlockUse, long lRequest, +#if _MSC_VER <= 1100 // Special case for VC 5 + const char * szFileName, +#else + const unsigned char * szFileName, +#endif + int nLine) +{ + //static TCHAR *operation[] = { _T(""), _T("ALLOCATIONG"), _T("RE-ALLOCATING"), _T("FREEING") }; + //static TCHAR *blockType[] = { _T("Free"), _T("Normal"), _T("CRT"), _T("Ignore"), _T("Client") }; + +#ifdef IGNORE_CRT_ALLOC + if (_BLOCK_TYPE(nBlockUse) == _CRT_BLOCK) // Ignore internal C runtime library allocations + return TRUE; +#endif + extern int _crtDbgFlag; + if ( ((_CRTDBG_ALLOC_MEM_DF & _crtDbgFlag) == 0) && ( (nAllocType == _HOOK_ALLOC) || (nAllocType == _HOOK_REALLOC) ) ) + { + // Someone has disabled that the runtime should log this allocation + // so we do not log this allocation + if (s_pfnOldCrtAllocHook != NULL) + s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); + return TRUE; + } + + // Handle the Disable/Enable setting + if (InterlockedExchangeAdd(&s_CrtDisableCount, 0) != 0) + return TRUE; + + // Prevent from reentrat calls + if (InterlockedIncrement(&s_lMallocCalled) > 1) { // I was already called + InterlockedDecrement(&s_lMallocCalled); + // call the previous alloc hook + if (s_pfnOldCrtAllocHook != NULL) + s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); + return TRUE; + } + + _ASSERT( (nAllocType == _HOOK_ALLOC) || (nAllocType == _HOOK_REALLOC) || (nAllocType == _HOOK_FREE) ); + _ASSERT( ( _BLOCK_TYPE(nBlockUse) >= 0 ) && ( _BLOCK_TYPE(nBlockUse) < 5 ) ); + + if (nAllocType == _HOOK_FREE) { // freeing + // Try to get the header information + if (_CrtIsValidHeapPointer(pvData)) { // it is a valid Heap-Pointer + // get the ID + _CrtMemBlockHeader *pHead; + // get a pointer to memory block header + pHead = pHdr(pvData); + nSize = pHead->nDataSize; + lRequest = pHead->lRequest; // This is the ID! + + if (pHead->nBlockUse == _IGNORE_BLOCK) + { + InterlockedDecrement(&s_lMallocCalled); + if (s_pfnOldCrtAllocHook != NULL) + s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); + return TRUE; + } + } + if (lRequest != 0) { // RequestID was found + g_pCRTTable->Remove(lRequest); + } + } // freeing + + if (nAllocType == _HOOK_REALLOC) { // re-allocating + // Try to get the header information + if (_CrtIsValidHeapPointer(pvData)) { // it is a valid Heap-Pointer + BOOL bRet; + LONG lReallocRequest; + // get the ID + _CrtMemBlockHeader *pHead; + // get a pointer to memory block header + pHead = pHdr(pvData); + // Try to find the RequestID in the Hash-Table, mark it that it was freed + lReallocRequest = pHead->lRequest; + bRet = g_pCRTTable->Remove(lReallocRequest); + } // ValidHeapPointer + } // re-allocating + + //if ( (g_ulShowStackAtAlloc < 3) && (nAllocType == _HOOK_FREE) ) { + if (nAllocType == _HOOK_FREE) { + InterlockedDecrement(&s_lMallocCalled); + // call the previous alloc hook + if (s_pfnOldCrtAllocHook != NULL) + s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); + return TRUE; + } + + CONTEXT c; + GET_CURRENT_CONTEXT(c, CONTEXT_FULL); + + // Only insert in the Hash-Table if it is not a "freeing" + if (nAllocType != _HOOK_FREE) { + if(lRequest != 0) // Always a valid RequestID should be provided (see comments in the header) + g_pCRTTable->Insert(lRequest, c, nSize); + } + + InterlockedDecrement(&s_lMallocCalled); + // call the previous alloc hook + if (s_pfnOldCrtAllocHook != NULL) + s_pfnOldCrtAllocHook(nAllocType, pvData, nSize, nBlockUse, lRequest, szFileName, nLine); + return TRUE; // allow the memory operation to proceed +} // MyAllocHook + +#endif // _DEBUG + + +// ########################################################################## +// ########################################################################## +// ########################################################################## +// Specialization for COM-Leaks: + +// forwards: +class COMTable; +class CMallocSpy : public IMallocSpy +{ +public: + CMallocSpy() { m_cbRequest = 0; m_cRef = 0; m_disableCount = 0; } + virtual ~CMallocSpy() {} + // IUnknown methods + STDMETHOD(QueryInterface) (REFIID riid, LPVOID *ppUnk); + STDMETHOD_(ULONG, AddRef) (); + STDMETHOD_(ULONG, Release) (); + // IMallocSpy methods + STDMETHOD_(SIZE_T, PreAlloc) (SIZE_T cbRequest); + STDMETHOD_(void *, PostAlloc) (void *pActual); + STDMETHOD_(void *, PreFree) (void *pRequest, BOOL fSpyed); + STDMETHOD_(void, PostFree) (BOOL fSpyed) { return; }; + STDMETHOD_(SIZE_T, PreRealloc) (void *pRequest, SIZE_T cbRequest, void **ppNewRequest, BOOL fSpyed); + STDMETHOD_(void *, PostRealloc) (void *pActual, BOOL fSpyed); + STDMETHOD_(void *, PreGetSize) (void *pRequest, BOOL fSpyed) { return pRequest; } + STDMETHOD_(SIZE_T, PostGetSize) (SIZE_T cbActual, BOOL fSpyed) { return cbActual; } + STDMETHOD_(void *, PreDidAlloc) (void *pRequest, BOOL fSpyed) { return pRequest; } + STDMETHOD_(BOOL, PostDidAlloc) (void *pRequest, BOOL fSpyed, BOOL fActual) { return fActual; } + STDMETHOD_(void, PreHeapMinimize) (void) { return; } + STDMETHOD_(void, PostHeapMinimize) (void) { return; } +private: + LONG m_cRef; + SIZE_T m_cbRequest; +protected: + COMTable *m_pComTable; + LONG m_disableCount; + friend COMTable; +}; + +class COMTable : public ContextHashtableBase<LPVOID> +{ +public: + COMTable() : ContextHashtableBase<LPVOID>(1021, "COM-Leaks") + { + m_pMallocSpy = new CMallocSpy(); // wird später durch Release freigegeben + if (m_pMallocSpy != NULL) + { + m_pMallocSpy->m_pComTable = this; + // CoInitilize(); // ??? Is this necessary ? + HRESULT hr = CoRegisterMallocSpy(m_pMallocSpy); + if FAILED(hr) + { + _tprintf(_T("\nCoRegisterMallocSpay failed with %.8x"), hr); + } + } + } + + virtual ~COMTable() + { + if (m_pMallocSpy != NULL) + m_pMallocSpy->m_pComTable = NULL; + CoRevokeMallocSpy(); + } + + virtual LONG Disable() + { + return InterlockedIncrement(&(m_pMallocSpy->m_disableCount)); + } + virtual LONG Enable() + { + return InterlockedDecrement(&(m_pMallocSpy->m_disableCount)); + } + + virtual SIZE_T HashFunction(LPVOID &key) + { + // I couldn´t find any better and faster +#ifdef _M_IX86 +#if _MSC_VER > 1100 +#pragma warning (push) +#endif +#pragma warning (disable: 4311) + DWORD llP = (DWORD) key; +#if _MSC_VER > 1100 +#pragma warning (pop) +#endif +#else + ULONGLONG llP = (ULONGLONG) key; +#endif + return (SIZE_T) llP % sAllocEntries; + } + virtual BOOL IsKeyEmpty(LPVOID &key) + { + if (key == 0) + return TRUE; + return FALSE; + } + virtual VOID SetEmptyKey(LPVOID &key) + { + key = 0; + } + virtual VOID GetKeyAsString(LPVOID &key, CHAR *szName, SIZE_T nBufferLen) + { +#if _MSC_VER < 1400 + _snprintf_s(szName, nBufferLen, "%p", key); +#else + _snprintf_s(szName, nBufferLen, nBufferLen, "%p", key); +#endif + } + + CMallocSpy *m_pMallocSpy; + friend CMallocSpy; +}; // class COMTable + + +STDMETHODIMP CMallocSpy::QueryInterface(REFIID riid, LPVOID *ppUnk) { + HRESULT hr = S_OK; + if (IsEqualIID(riid, IID_IUnknown)) { + *ppUnk = (IUnknown *) this; + } + else if (IsEqualIID(riid, IID_IMallocSpy)) { + *ppUnk = (IMalloc *) this; + } + else { + *ppUnk = NULL; + hr = E_NOINTERFACE; + } + AddRef(); + return hr; +} +STDMETHODIMP_(ULONG) CMallocSpy::AddRef(void) { + return (ULONG) InterlockedIncrement(&m_cRef); +} +STDMETHODIMP_(ULONG) CMallocSpy::Release(void) { + LONG cRef; + cRef = InterlockedDecrement(&m_cRef); + if (cRef == 0) + { + delete this; + } + return (ULONG) cRef; +} +// IMallocSpy methods +STDMETHODIMP_(SIZE_T) CMallocSpy::PreAlloc(SIZE_T cbRequest) { + m_cbRequest = cbRequest; + return cbRequest; +} +STDMETHODIMP_(void *) CMallocSpy::PostAlloc(void *pActual) { + if (m_pComTable != NULL) + { + CONTEXT c; + GET_CURRENT_CONTEXT(c, CONTEXT_FULL); + m_pComTable->Insert(pActual, c, m_cbRequest); + } + return pActual; +} +STDMETHODIMP_(void *) CMallocSpy::PreFree(void *pRequest, BOOL fSpyed) { + if (m_pComTable != NULL) + { + m_pComTable->Remove(pRequest); + } + return pRequest; +} +STDMETHODIMP_(SIZE_T) CMallocSpy::PreRealloc(void *pRequest, SIZE_T cbRequest, + void **ppNewRequest, BOOL fSpyed) { + if (m_pComTable != NULL) + { + m_pComTable->Remove(pRequest); + } + *ppNewRequest = pRequest; // Bug fixed. Thanx to Christoph Weber + return cbRequest; +} +STDMETHODIMP_(void *) CMallocSpy::PostRealloc(void *pActual, BOOL fSpyed) { + if (m_pComTable != NULL) + { + CONTEXT c; + GET_CURRENT_CONTEXT(c, CONTEXT_FULL); + m_pComTable->Insert(pActual, c, m_cbRequest); + } + return pActual; +} + + + + +// ########################################################################## +// ########################################################################## +// ########################################################################## +// Init/Deinit functions + + +static COMTable *g_pCOMTable; +HRESULT InitLeakFinder() +{ + // _X: Disabled COM monitoring: g_pCOMTable = new COMTable(); +#ifdef _DEBUG + g_pCRTTable = new CRTTable(); +#endif + return S_OK; +} + +void DeinitLeakFinder(LeakFinderOutput *output) +{ + LeakFinderOutput *pLeakFinderOutput = output; + +#ifdef _DEBUG + g_pCRTTable->Disable(); +#endif + // _X: Disabled COM monitoring: g_pCOMTable->Disable(); + + if (pLeakFinderOutput == NULL) + pLeakFinderOutput = new LeakFinderOutput(); + + // explicite load the modules: + pLeakFinderOutput->LoadModules(); + +#ifdef _DEBUG + g_pCRTTable->ShowLeaks(*pLeakFinderOutput); + if (g_pCRTTable != NULL) + delete g_pCRTTable; + g_pCRTTable = NULL; +#endif + + /* + // _X: Disabled COM monitoring: + g_pCOMTable->ShowLeaks(*pLeakFinderOutput); + if (g_pCOMTable != NULL) + delete g_pCOMTable; + g_pCOMTable = NULL; + */ + + if (output == NULL) + delete pLeakFinderOutput; +} +void DeinitLeakFinder() +{ + DeinitLeakFinder(NULL); +} diff --git a/source/LeakFinder.h b/source/LeakFinder.h index 77f221bca..6743adda0 100644 --- a/source/LeakFinder.h +++ b/source/LeakFinder.h @@ -1,145 +1,145 @@ -/**********************************************************************
- *
- * LEAKFINDER.H
- *
- *
- *
- * LICENSE (http://www.opensource.org/licenses/bsd-license.php)
- *
- * Copyright (c) 2005-2010, Jochen Kalmbach
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * Neither the name of Jochen Kalmbach nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **********************************************************************/
-
-// #pragma once is supported starting with _MCS_VER 1000,
-// so we need not to check the version (because we only support _MSC_VER >= 1100)!
-#pragma once
-
-#include <windows.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-HRESULT InitLeakFinder();
-void DeinitLeakFinder();
-
-#ifdef __cplusplus
-}
-#endif
-
-
-// The following is only available if the file is CPP
-#ifdef __cplusplus
-
-#include "StackWalker.h"
-
-// Interface for output...
-class LeakFinderOutput : public StackWalker
-{
-public:
- typedef enum LeakFinderOptions
- {
- // No addition info will be retrived
- // (only the address is available)
- LeakFinderNone = 0,
- LeakFinderShowCompleteCallstack = 0x1000
- } LeakFinderOptions;
-
- LeakFinderOutput(int options = OptionsAll, LPCSTR szSymPath = NULL);
- virtual void OnLeakSearchStart(LPCSTR sszLeakFinderName);
- virtual void OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize);
-protected:
- virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry);
- virtual void OnOutput(LPCSTR szText)
- {
- printf(szText);
- StackWalker::OnOutput(szText);
- }
- virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr)
- {
- if (strcmp(szFuncName, "SymGetLineFromAddr64") == 0) return;
- StackWalker::OnDbgHelpErr(szFuncName, gle, addr);
- }
-};
-
-class LeakFinderXmlOutput : public LeakFinderOutput
-{
-public:
- LeakFinderXmlOutput();
- virtual ~LeakFinderXmlOutput();
- LeakFinderXmlOutput(LPCTSTR szFileName);
- virtual void OnLeakSearchStart(LPCSTR sszLeakFinderName);
- virtual void OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize);
-protected:
- virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry);
- virtual void OnOutput(LPCSTR szText) { }
- virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) { }
-
- FILE *m_fXmlFile;
-};
-
-// C++ interface:
-void DeinitLeakFinder(LeakFinderOutput *output);
-
-class ZZZ_LeakFinder
-{
-public:
- ZZZ_LeakFinder()
- {
- m_pXml = NULL;
-#ifdef XML_LEAK_FINDER
- m_pXml = new LeakFinderXmlOutput();
-#endif
- InitLeakFinder();
- }
- ~ZZZ_LeakFinder()
- {
- DeinitLeakFinder(m_pXml);
- if (m_pXml != NULL) delete m_pXml;
- }
-protected:
- LeakFinderXmlOutput *m_pXml;
-};
-
-#if defined(INIT_LEAK_FINDER)
-#if _MSC_VER >= 1200
-#pragma warning(push)
-#endif
-#pragma warning (disable:4074)
-
-// WARNING: If you enable this option, the code might run without the CRT being initialized or after the CRT was deinitialized!!!
-// Currently the code is not designed to bypass the CRT...
-//#pragma init_seg (compiler)
-ZZZ_LeakFinder zzz_LeakFinder;
-
-#if _MSC_VER >= 1200
-#pragma warning(pop)
-#else
-#pragma warning(default:4074)
-#endif
-#endif
-
-#endif // __cplusplus
+/********************************************************************** + * + * LEAKFINDER.H + * + * + * + * LICENSE (http://www.opensource.org/licenses/bsd-license.php) + * + * Copyright (c) 2005-2010, Jochen Kalmbach + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of Jochen Kalmbach nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +// #pragma once is supported starting with _MCS_VER 1000, +// so we need not to check the version (because we only support _MSC_VER >= 1100)! +#pragma once + +#include <windows.h> + +#ifdef __cplusplus +extern "C" { +#endif + +HRESULT InitLeakFinder(); +void DeinitLeakFinder(); + +#ifdef __cplusplus +} +#endif + + +// The following is only available if the file is CPP +#ifdef __cplusplus + +#include "StackWalker.h" + +// Interface for output... +class LeakFinderOutput : public StackWalker +{ +public: + typedef enum LeakFinderOptions + { + // No addition info will be retrived + // (only the address is available) + LeakFinderNone = 0, + LeakFinderShowCompleteCallstack = 0x1000 + } LeakFinderOptions; + + LeakFinderOutput(int options = OptionsAll, LPCSTR szSymPath = NULL); + virtual void OnLeakSearchStart(LPCSTR sszLeakFinderName); + virtual void OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize); +protected: + virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry); + virtual void OnOutput(LPCSTR szText) + { + printf(szText); + StackWalker::OnOutput(szText); + } + virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) + { + if (strcmp(szFuncName, "SymGetLineFromAddr64") == 0) return; + StackWalker::OnDbgHelpErr(szFuncName, gle, addr); + } +}; + +class LeakFinderXmlOutput : public LeakFinderOutput +{ +public: + LeakFinderXmlOutput(); + virtual ~LeakFinderXmlOutput(); + LeakFinderXmlOutput(LPCTSTR szFileName); + virtual void OnLeakSearchStart(LPCSTR sszLeakFinderName); + virtual void OnLeakStartEntry(LPCSTR szKeyName, SIZE_T nDataSize); +protected: + virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry); + virtual void OnOutput(LPCSTR szText) { } + virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) { } + + FILE *m_fXmlFile; +}; + +// C++ interface: +void DeinitLeakFinder(LeakFinderOutput *output); + +class ZZZ_LeakFinder +{ +public: + ZZZ_LeakFinder() + { + m_pXml = NULL; +#ifdef XML_LEAK_FINDER + m_pXml = new LeakFinderXmlOutput(); +#endif + InitLeakFinder(); + } + ~ZZZ_LeakFinder() + { + DeinitLeakFinder(m_pXml); + if (m_pXml != NULL) delete m_pXml; + } +protected: + LeakFinderXmlOutput *m_pXml; +}; + +#if defined(INIT_LEAK_FINDER) +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif +#pragma warning (disable:4074) + +// WARNING: If you enable this option, the code might run without the CRT being initialized or after the CRT was deinitialized!!! +// Currently the code is not designed to bypass the CRT... +//#pragma init_seg (compiler) +ZZZ_LeakFinder zzz_LeakFinder; + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#else +#pragma warning(default:4074) +#endif +#endif + +#endif // __cplusplus diff --git a/source/LightingThread.cpp b/source/LightingThread.cpp index c2f876e32..67f3b4116 100644 --- a/source/LightingThread.cpp +++ b/source/LightingThread.cpp @@ -1,531 +1,531 @@ -
-// LightingThread.cpp
-
-// Implements the cLightingThread class representing the thread that processes requests for lighting
-
-#include "Globals.h"
-#include "LightingThread.h"
-#include "cChunkMap.h"
-#include "cWorld.h"
-
-
-
-
-
-/// If more than this many chunks are in the queue, a warning is printed to the log
-#define WARN_ON_QUEUE_SIZE 800
-
-
-
-
-
-/// Chunk data callback that takes the chunk data and puts them into cLightingThread's m_BlockTypes[] / m_HeightMap[]:
-class cReader :
- public cChunkDataCallback
-{
- virtual void BlockTypes(const BLOCKTYPE * a_Type) override
- {
- // ROW is a block of 16 Blocks, one whole row is copied at a time (hopefully the compiler will optimize that)
- // C++ doesn't permit copying arrays, but arrays as a part of a struct is ok :)
- typedef struct {BLOCKTYPE m_Row[16]; } ROW;
- ROW * InputRows = (ROW *)a_Type;
- ROW * OutputRows = (ROW *)m_BlockTypes;
- int InputIdx = 0;
- int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3;
- for (int y = 0; y < cChunkDef::Height; y++)
- {
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- OutputRows[OutputIdx] = InputRows[InputIdx++];
- OutputIdx += 3;
- } // for z
- // Skip into the next y-level in the 3x3 chunk blob; each level has cChunkDef::Width * 9 rows
- // We've already walked cChunkDef::Width * 3 in the "for z" cycle, that makes cChunkDef::Width * 6 rows left to skip
- OutputIdx += cChunkDef::Width * 6;
- } // for y
- } // BlockTypes()
-
-
- virtual void HeightMap(const cChunkDef::HeightMap * a_Heightmap) override
- {
- typedef struct {HEIGHTTYPE m_Row[16]; } ROW;
- ROW * InputRows = (ROW *)a_Heightmap;
- ROW * OutputRows = (ROW *)m_HeightMap;
- int InputIdx = 0;
- int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3;
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- OutputRows[OutputIdx] = InputRows[InputIdx++];
- OutputIdx += 3;
- } // for z
- }
-
-public:
- int m_ReadingChunkX; // 0, 1 or 2; x-offset of the chunk we're reading from the BlockTypes start
- int m_ReadingChunkZ; // 0, 1 or 2; z-offset of the chunk we're reading from the BlockTypes start
- BLOCKTYPE * m_BlockTypes; // 3x3 chunks of block types, organized as a single XZY blob of data (instead of 3x3 XZY blobs)
- HEIGHTTYPE * m_HeightMap; // 3x3 chunks of height map, organized as a single XZY blob of data (instead of 3x3 XZY blobs)
-} ;
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cLightingThread:
-
-cLightingThread::cLightingThread(void) :
- super("cLightingThread"),
- m_World(NULL)
-{
-}
-
-
-
-
-
-cLightingThread::~cLightingThread()
-{
- Stop();
-}
-
-
-
-
-
-bool cLightingThread::Start(cWorld * a_World)
-{
- ASSERT(m_World == NULL); // Not started yet
- m_World = a_World;
-
- return super::Start();
-}
-
-
-
-
-
-void cLightingThread::Stop(void)
-{
- {
- cCSLock Lock(m_CS);
- m_Queue.clear();
- }
- m_ShouldTerminate = true;
- m_evtItemAdded.Set();
-
- Wait();
-}
-
-
-
-
-
-void cLightingThread::QueueChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter)
-{
- ASSERT(m_World != NULL); // Did you call Start() properly?
-
- cChunkStay * ChunkStay = new cChunkStay(m_World);
- ChunkStay->Add(a_ChunkX + 1, ZERO_CHUNK_Y, a_ChunkZ + 1);
- ChunkStay->Add(a_ChunkX + 1, ZERO_CHUNK_Y, a_ChunkZ);
- ChunkStay->Add(a_ChunkX + 1, ZERO_CHUNK_Y, a_ChunkZ - 1);
- ChunkStay->Add(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ + 1);
- ChunkStay->Add(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
- ChunkStay->Add(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ - 1);
- ChunkStay->Add(a_ChunkX - 1, ZERO_CHUNK_Y, a_ChunkZ + 1);
- ChunkStay->Add(a_ChunkX - 1, ZERO_CHUNK_Y, a_ChunkZ);
- ChunkStay->Add(a_ChunkX - 1, ZERO_CHUNK_Y, a_ChunkZ - 1);
- ChunkStay->Enable();
- ChunkStay->Load();
- cCSLock Lock(m_CS);
- m_Queue.push_back(sItem(a_ChunkX, a_ChunkZ, ChunkStay, a_CallbackAfter));
- if (m_Queue.size() > WARN_ON_QUEUE_SIZE)
- {
- LOGINFO("Lighting thread overloaded, %d items in queue", m_Queue.size());
- }
- m_evtItemAdded.Set();
-}
-
-
-
-
-
-void cLightingThread::WaitForQueueEmpty(void)
-{
- cCSLock Lock(m_CS);
- while (!m_ShouldTerminate && (!m_Queue.empty() || !m_PostponedQueue.empty()))
- {
- cCSUnlock Unlock(Lock);
- m_evtQueueEmpty.Wait();
- }
-}
-
-
-
-
-
-size_t cLightingThread::GetQueueLength(void)
-{
- cCSLock Lock(m_CS);
- return m_Queue.size() + m_PostponedQueue.size();
-}
-
-
-
-
-
-void cLightingThread::ChunkReady(int a_ChunkX, int a_ChunkZ)
-{
- // Check all the items in the m_PostponedQueue, if the chunk is their neighbor, move the item to m_Queue
-
- bool NewlyAdded = false;
- {
- cCSLock Lock(m_CS);
- for (sItems::iterator itr = m_PostponedQueue.begin(); itr != m_PostponedQueue.end(); )
- {
- if (
- (itr->x - a_ChunkX >= -1) && (itr->x - a_ChunkX <= 1) &&
- (itr->x - a_ChunkX >= -1) && (itr->x - a_ChunkX <= 1)
- )
- {
- // It is a neighbor
- m_Queue.push_back(*itr);
- itr = m_PostponedQueue.erase(itr);
- NewlyAdded = true;
- }
- else
- {
- ++itr;
- }
- } // for itr - m_PostponedQueue[]
- } // Lock(m_CS)
-
- if (NewlyAdded)
- {
- m_evtItemAdded.Set(); // Notify the thread it has some work to do
- }
-}
-
-
-
-
-
-void cLightingThread::Execute(void)
-{
- while (true)
- {
- {
- cCSLock Lock(m_CS);
- if (m_Queue.size() == 0)
- {
- cCSUnlock Unlock(Lock);
- m_evtItemAdded.Wait();
- }
- }
-
- if (m_ShouldTerminate)
- {
- return;
- }
-
- // Process one items from the queue:
- sItem Item;
- {
- cCSLock Lock(m_CS);
- if (m_Queue.empty())
- {
- continue;
- }
- Item = m_Queue.front();
- m_Queue.pop_front();
- if (m_Queue.empty())
- {
- m_evtQueueEmpty.Set();
- }
- } // CSLock(m_CS)
-
- LightChunk(Item);
- }
-}
-
-
-
-
-
-
-void cLightingThread::LightChunk(cLightingThread::sItem & a_Item)
-{
- cChunkDef::BlockNibbles BlockLight, SkyLight;
-
- if (!ReadChunks(a_Item.x, a_Item.z))
- {
- // Neighbors not available. Re-queue in the postponed queue
- cCSLock Lock(m_CS);
- m_PostponedQueue.push_back(a_Item);
- return;
- }
-
- /*
- // DEBUG: torch somewhere:
- m_BlockTypes[19 + 24 * cChunkDef::Width * 3 + (m_HeightMap[24 + 24 * cChunkDef::Width * 3] / 2) * BlocksPerYLayer] = E_BLOCK_TORCH;
- // m_HeightMap[24 + 24 * cChunkDef::Width * 3]++;
- */
-
- PrepareBlockLight();
- CalcLight(m_BlockLight);
-
- PrepareSkyLight();
- CalcLight(m_SkyLight);
-
- CompressLight(m_BlockLight, BlockLight);
- CompressLight(m_SkyLight, SkyLight);
-
- /*
- // DEBUG:
- {
- cFile f("chunk_BlockTypes.dat", cFile::fmWrite);
- if (f.IsOpen())
- {
- f.Write(m_BlockTypes, sizeof(m_BlockTypes));
- }
- }
-
- // DEBUG:
- {
- cFile f("Chunk_SkyLight.dat", cFile::fmWrite);
- if (f.IsOpen())
- {
- f.Write(m_SkyLight, sizeof(m_SkyLight));
- }
- }
-
- // DEBUG:
- {
- cFile f("Chunk_BlockLight.dat", cFile::fmWrite);
- if (f.IsOpen())
- {
- f.Write(m_BlockLight, sizeof(m_BlockLight));
- }
- }
- */
-
- m_World->ChunkLighted(a_Item.x, a_Item.z, BlockLight, SkyLight);
-
- if (a_Item.m_Callback != NULL)
- {
- a_Item.m_Callback->Call(a_Item.x, a_Item.z);
- }
- delete a_Item.m_ChunkStay;
-}
-
-
-
-
-
-bool cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ)
-{
- cReader Reader;
- Reader.m_BlockTypes = m_BlockTypes;
- Reader.m_HeightMap = m_HeightMap;
-
- for (int z = 0; z < 3; z++)
- {
- Reader.m_ReadingChunkZ = z;
- for (int x = 0; x < 3; x++)
- {
- Reader.m_ReadingChunkX = x;
- if (!m_World->GetChunkData(a_ChunkX + x - 1, ZERO_CHUNK_Y, a_ChunkZ + z - 1, Reader))
- {
- return false;
- }
- } // for z
- } // for x
-
- memset(m_BlockLight, 0, sizeof(m_BlockLight));
- memset(m_SkyLight, 0, sizeof(m_SkyLight));
- return true;
-}
-
-
-
-
-
-void cLightingThread::PrepareSkyLight(void)
-{
- // Clear seeds:
- memset(m_IsSeed1, 0, sizeof(m_IsSeed1));
- m_NumSeeds = 0;
-
- // Walk every column that has all XZ neighbors
- for (int z = 1; z < cChunkDef::Width * 3 - 1; z++)
- {
- int BaseZ = z * cChunkDef::Width * 3;
- for (int x = 1; x < cChunkDef::Width * 3 - 1; x++)
- {
- int idx = BaseZ + x;
- int Current = m_HeightMap[idx] + 1;
- int Neighbor1 = m_HeightMap[idx + 1] + 1; // X + 1
- int Neighbor2 = m_HeightMap[idx - 1] + 1; // X - 1
- int Neighbor3 = m_HeightMap[idx + cChunkDef::Width * 3] + 1; // Z + 1
- int Neighbor4 = m_HeightMap[idx - cChunkDef::Width * 3] + 1; // Z - 1
- int MaxNeighbor = MAX(MAX(Neighbor1, Neighbor2), MAX(Neighbor3, Neighbor4)); // Maximum of the four neighbors
-
- // TODO: The following cycle can be transofrmed into two separate cycles with no condition inside them, one lighting and the other seeding
- for (int y = Current, Index = idx + y * BlocksPerYLayer; y < cChunkDef::Height; y++, Index += BlocksPerYLayer)
- {
- // If all the XZ neighbors are lower than y, abort for the current column (but light up the rest of it):
- if (y >= MaxNeighbor)
- {
- for (int y2 = y; y2 < cChunkDef::Height; y2++, Index += BlocksPerYLayer)
- {
- m_SkyLight[Index] = 15;
- } // for y2
- break; // for y
- }
-
- // Add current block as a seed:
- m_IsSeed1[Index] = true;
- m_SeedIdx1[m_NumSeeds++] = Index;
-
- // Light it up to full skylight:
- m_SkyLight[Index] = 15;
- }
- }
- }
-}
-
-
-
-
-
-void cLightingThread::PrepareBlockLight(void)
-{
- // Clear seeds:
- memset(m_IsSeed1, 0, sizeof(m_IsSeed1));
- m_NumSeeds = 0;
-
- // Walk every column that has all XZ neighbors, make a seed for each light-emitting block:
- for (int z = 1; z < cChunkDef::Width * 3 - 1; z++)
- {
- int BaseZ = z * cChunkDef::Width * 3;
- for (int x = 1; x < cChunkDef::Width * 3 - 1; x++)
- {
- int idx = BaseZ + x;
- for (int y = m_HeightMap[idx], Index = idx + y * BlocksPerYLayer; y >= 0; y--, Index -= BlocksPerYLayer)
- {
- if (g_BlockLightValue[m_BlockTypes[Index]] == 0)
- {
- continue;
- }
-
- // Add current block as a seed:
- m_IsSeed1[Index] = true;
- m_SeedIdx1[m_NumSeeds++] = Index;
-
- // Light it up:
- m_BlockLight[Index] = g_BlockLightValue[m_BlockTypes[Index]];
- }
- }
- }
-}
-
-
-
-
-
-void cLightingThread::CalcLight(NIBBLETYPE * a_Light)
-{
- int NumSeeds2 = 0;
- while (m_NumSeeds > 0)
- {
- // Buffer 1 -> buffer 2
- memset(m_IsSeed2, 0, sizeof(m_IsSeed2));
- NumSeeds2 = 0;
- CalcLightStep(a_Light, m_NumSeeds, m_IsSeed1, m_SeedIdx1, NumSeeds2, m_IsSeed2, m_SeedIdx2);
- if (NumSeeds2 == 0)
- {
- return;
- }
-
- // Buffer 2 -> buffer 1
- memset(m_IsSeed1, 0, sizeof(m_IsSeed1));
- m_NumSeeds = 0;
- CalcLightStep(a_Light, NumSeeds2, m_IsSeed2, m_SeedIdx2, m_NumSeeds, m_IsSeed1, m_SeedIdx1);
- }
-}
-
-
-
-
-
-void cLightingThread::CalcLightStep(
- NIBBLETYPE * a_Light,
- int a_NumSeedsIn, unsigned char * a_IsSeedIn, unsigned int * a_SeedIdxIn,
- int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut
-)
-{
- int NumSeedsOut = 0;
- for (int i = 0; i < a_NumSeedsIn; i++)
- {
- int SeedIdx = a_SeedIdxIn[i];
- int SeedX = SeedIdx % (cChunkDef::Width * 3);
- int SeedZ = (SeedIdx / (cChunkDef::Width * 3)) % (cChunkDef::Width * 3);
- int SeedY = SeedIdx / BlocksPerYLayer;
-
- // Propagate seed:
- if (SeedX < cChunkDef::Width * 3)
- {
- PropagateLight(a_Light, SeedIdx, SeedIdx + 1, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut);
- }
- if (SeedX > 0)
- {
- PropagateLight(a_Light, SeedIdx, SeedIdx - 1, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut);
- }
- if (SeedZ < cChunkDef::Width * 3)
- {
- PropagateLight(a_Light, SeedIdx, SeedIdx + cChunkDef::Width * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut);
- }
- if (SeedZ > 0)
- {
- PropagateLight(a_Light, SeedIdx, SeedIdx - cChunkDef::Width * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut);
- }
- if (SeedY < cChunkDef::Height)
- {
- PropagateLight(a_Light, SeedIdx, SeedIdx + cChunkDef::Width * cChunkDef::Width * 3 * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut);
- }
- if (SeedY > 0)
- {
- PropagateLight(a_Light, SeedIdx, SeedIdx - cChunkDef::Width * cChunkDef::Width * 3 * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut);
- }
- } // for i - a_SeedIdxIn[]
- a_NumSeedsOut = NumSeedsOut;
-}
-
-
-
-
-
-void cLightingThread::CompressLight(NIBBLETYPE * a_LightArray, NIBBLETYPE * a_ChunkLight)
-{
- int InIdx = cChunkDef::Width * 49; // Index to the first nibble of the middle chunk in the a_LightArray
- int OutIdx = 0;
- for (int y = 0; y < cChunkDef::Height; y++)
- {
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- for (int x = 0; x < cChunkDef::Width; x += 2)
- {
- a_ChunkLight[OutIdx++] = (a_LightArray[InIdx + 1] << 4) | a_LightArray[InIdx];
- InIdx += 2;
- }
- InIdx += cChunkDef::Width * 2;
- }
- // Skip into the next y-level in the 3x3 chunk blob; each level has cChunkDef::Width * 9 rows
- // We've already walked cChunkDef::Width * 3 in the "for z" cycle, that makes cChunkDef::Width * 6 rows left to skip
- InIdx += cChunkDef::Width * cChunkDef::Width * 6;
- }
-}
-
-
-
-
+ +// LightingThread.cpp + +// Implements the cLightingThread class representing the thread that processes requests for lighting + +#include "Globals.h" +#include "LightingThread.h" +#include "cChunkMap.h" +#include "cWorld.h" + + + + + +/// If more than this many chunks are in the queue, a warning is printed to the log +#define WARN_ON_QUEUE_SIZE 800 + + + + + +/// Chunk data callback that takes the chunk data and puts them into cLightingThread's m_BlockTypes[] / m_HeightMap[]: +class cReader : + public cChunkDataCallback +{ + virtual void BlockTypes(const BLOCKTYPE * a_Type) override + { + // ROW is a block of 16 Blocks, one whole row is copied at a time (hopefully the compiler will optimize that) + // C++ doesn't permit copying arrays, but arrays as a part of a struct is ok :) + typedef struct {BLOCKTYPE m_Row[16]; } ROW; + ROW * InputRows = (ROW *)a_Type; + ROW * OutputRows = (ROW *)m_BlockTypes; + int InputIdx = 0; + int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3; + for (int y = 0; y < cChunkDef::Height; y++) + { + for (int z = 0; z < cChunkDef::Width; z++) + { + OutputRows[OutputIdx] = InputRows[InputIdx++]; + OutputIdx += 3; + } // for z + // Skip into the next y-level in the 3x3 chunk blob; each level has cChunkDef::Width * 9 rows + // We've already walked cChunkDef::Width * 3 in the "for z" cycle, that makes cChunkDef::Width * 6 rows left to skip + OutputIdx += cChunkDef::Width * 6; + } // for y + } // BlockTypes() + + + virtual void HeightMap(const cChunkDef::HeightMap * a_Heightmap) override + { + typedef struct {HEIGHTTYPE m_Row[16]; } ROW; + ROW * InputRows = (ROW *)a_Heightmap; + ROW * OutputRows = (ROW *)m_HeightMap; + int InputIdx = 0; + int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3; + for (int z = 0; z < cChunkDef::Width; z++) + { + OutputRows[OutputIdx] = InputRows[InputIdx++]; + OutputIdx += 3; + } // for z + } + +public: + int m_ReadingChunkX; // 0, 1 or 2; x-offset of the chunk we're reading from the BlockTypes start + int m_ReadingChunkZ; // 0, 1 or 2; z-offset of the chunk we're reading from the BlockTypes start + BLOCKTYPE * m_BlockTypes; // 3x3 chunks of block types, organized as a single XZY blob of data (instead of 3x3 XZY blobs) + HEIGHTTYPE * m_HeightMap; // 3x3 chunks of height map, organized as a single XZY blob of data (instead of 3x3 XZY blobs) +} ; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cLightingThread: + +cLightingThread::cLightingThread(void) : + super("cLightingThread"), + m_World(NULL) +{ +} + + + + + +cLightingThread::~cLightingThread() +{ + Stop(); +} + + + + + +bool cLightingThread::Start(cWorld * a_World) +{ + ASSERT(m_World == NULL); // Not started yet + m_World = a_World; + + return super::Start(); +} + + + + + +void cLightingThread::Stop(void) +{ + { + cCSLock Lock(m_CS); + m_Queue.clear(); + } + m_ShouldTerminate = true; + m_evtItemAdded.Set(); + + Wait(); +} + + + + + +void cLightingThread::QueueChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter) +{ + ASSERT(m_World != NULL); // Did you call Start() properly? + + cChunkStay * ChunkStay = new cChunkStay(m_World); + ChunkStay->Add(a_ChunkX + 1, ZERO_CHUNK_Y, a_ChunkZ + 1); + ChunkStay->Add(a_ChunkX + 1, ZERO_CHUNK_Y, a_ChunkZ); + ChunkStay->Add(a_ChunkX + 1, ZERO_CHUNK_Y, a_ChunkZ - 1); + ChunkStay->Add(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ + 1); + ChunkStay->Add(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + ChunkStay->Add(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ - 1); + ChunkStay->Add(a_ChunkX - 1, ZERO_CHUNK_Y, a_ChunkZ + 1); + ChunkStay->Add(a_ChunkX - 1, ZERO_CHUNK_Y, a_ChunkZ); + ChunkStay->Add(a_ChunkX - 1, ZERO_CHUNK_Y, a_ChunkZ - 1); + ChunkStay->Enable(); + ChunkStay->Load(); + cCSLock Lock(m_CS); + m_Queue.push_back(sItem(a_ChunkX, a_ChunkZ, ChunkStay, a_CallbackAfter)); + if (m_Queue.size() > WARN_ON_QUEUE_SIZE) + { + LOGINFO("Lighting thread overloaded, %d items in queue", m_Queue.size()); + } + m_evtItemAdded.Set(); +} + + + + + +void cLightingThread::WaitForQueueEmpty(void) +{ + cCSLock Lock(m_CS); + while (!m_ShouldTerminate && (!m_Queue.empty() || !m_PostponedQueue.empty())) + { + cCSUnlock Unlock(Lock); + m_evtQueueEmpty.Wait(); + } +} + + + + + +size_t cLightingThread::GetQueueLength(void) +{ + cCSLock Lock(m_CS); + return m_Queue.size() + m_PostponedQueue.size(); +} + + + + + +void cLightingThread::ChunkReady(int a_ChunkX, int a_ChunkZ) +{ + // Check all the items in the m_PostponedQueue, if the chunk is their neighbor, move the item to m_Queue + + bool NewlyAdded = false; + { + cCSLock Lock(m_CS); + for (sItems::iterator itr = m_PostponedQueue.begin(); itr != m_PostponedQueue.end(); ) + { + if ( + (itr->x - a_ChunkX >= -1) && (itr->x - a_ChunkX <= 1) && + (itr->x - a_ChunkX >= -1) && (itr->x - a_ChunkX <= 1) + ) + { + // It is a neighbor + m_Queue.push_back(*itr); + itr = m_PostponedQueue.erase(itr); + NewlyAdded = true; + } + else + { + ++itr; + } + } // for itr - m_PostponedQueue[] + } // Lock(m_CS) + + if (NewlyAdded) + { + m_evtItemAdded.Set(); // Notify the thread it has some work to do + } +} + + + + + +void cLightingThread::Execute(void) +{ + while (true) + { + { + cCSLock Lock(m_CS); + if (m_Queue.size() == 0) + { + cCSUnlock Unlock(Lock); + m_evtItemAdded.Wait(); + } + } + + if (m_ShouldTerminate) + { + return; + } + + // Process one items from the queue: + sItem Item; + { + cCSLock Lock(m_CS); + if (m_Queue.empty()) + { + continue; + } + Item = m_Queue.front(); + m_Queue.pop_front(); + if (m_Queue.empty()) + { + m_evtQueueEmpty.Set(); + } + } // CSLock(m_CS) + + LightChunk(Item); + } +} + + + + + + +void cLightingThread::LightChunk(cLightingThread::sItem & a_Item) +{ + cChunkDef::BlockNibbles BlockLight, SkyLight; + + if (!ReadChunks(a_Item.x, a_Item.z)) + { + // Neighbors not available. Re-queue in the postponed queue + cCSLock Lock(m_CS); + m_PostponedQueue.push_back(a_Item); + return; + } + + /* + // DEBUG: torch somewhere: + m_BlockTypes[19 + 24 * cChunkDef::Width * 3 + (m_HeightMap[24 + 24 * cChunkDef::Width * 3] / 2) * BlocksPerYLayer] = E_BLOCK_TORCH; + // m_HeightMap[24 + 24 * cChunkDef::Width * 3]++; + */ + + PrepareBlockLight(); + CalcLight(m_BlockLight); + + PrepareSkyLight(); + CalcLight(m_SkyLight); + + CompressLight(m_BlockLight, BlockLight); + CompressLight(m_SkyLight, SkyLight); + + /* + // DEBUG: + { + cFile f("chunk_BlockTypes.dat", cFile::fmWrite); + if (f.IsOpen()) + { + f.Write(m_BlockTypes, sizeof(m_BlockTypes)); + } + } + + // DEBUG: + { + cFile f("Chunk_SkyLight.dat", cFile::fmWrite); + if (f.IsOpen()) + { + f.Write(m_SkyLight, sizeof(m_SkyLight)); + } + } + + // DEBUG: + { + cFile f("Chunk_BlockLight.dat", cFile::fmWrite); + if (f.IsOpen()) + { + f.Write(m_BlockLight, sizeof(m_BlockLight)); + } + } + */ + + m_World->ChunkLighted(a_Item.x, a_Item.z, BlockLight, SkyLight); + + if (a_Item.m_Callback != NULL) + { + a_Item.m_Callback->Call(a_Item.x, a_Item.z); + } + delete a_Item.m_ChunkStay; +} + + + + + +bool cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ) +{ + cReader Reader; + Reader.m_BlockTypes = m_BlockTypes; + Reader.m_HeightMap = m_HeightMap; + + for (int z = 0; z < 3; z++) + { + Reader.m_ReadingChunkZ = z; + for (int x = 0; x < 3; x++) + { + Reader.m_ReadingChunkX = x; + if (!m_World->GetChunkData(a_ChunkX + x - 1, ZERO_CHUNK_Y, a_ChunkZ + z - 1, Reader)) + { + return false; + } + } // for z + } // for x + + memset(m_BlockLight, 0, sizeof(m_BlockLight)); + memset(m_SkyLight, 0, sizeof(m_SkyLight)); + return true; +} + + + + + +void cLightingThread::PrepareSkyLight(void) +{ + // Clear seeds: + memset(m_IsSeed1, 0, sizeof(m_IsSeed1)); + m_NumSeeds = 0; + + // Walk every column that has all XZ neighbors + for (int z = 1; z < cChunkDef::Width * 3 - 1; z++) + { + int BaseZ = z * cChunkDef::Width * 3; + for (int x = 1; x < cChunkDef::Width * 3 - 1; x++) + { + int idx = BaseZ + x; + int Current = m_HeightMap[idx] + 1; + int Neighbor1 = m_HeightMap[idx + 1] + 1; // X + 1 + int Neighbor2 = m_HeightMap[idx - 1] + 1; // X - 1 + int Neighbor3 = m_HeightMap[idx + cChunkDef::Width * 3] + 1; // Z + 1 + int Neighbor4 = m_HeightMap[idx - cChunkDef::Width * 3] + 1; // Z - 1 + int MaxNeighbor = MAX(MAX(Neighbor1, Neighbor2), MAX(Neighbor3, Neighbor4)); // Maximum of the four neighbors + + // TODO: The following cycle can be transofrmed into two separate cycles with no condition inside them, one lighting and the other seeding + for (int y = Current, Index = idx + y * BlocksPerYLayer; y < cChunkDef::Height; y++, Index += BlocksPerYLayer) + { + // If all the XZ neighbors are lower than y, abort for the current column (but light up the rest of it): + if (y >= MaxNeighbor) + { + for (int y2 = y; y2 < cChunkDef::Height; y2++, Index += BlocksPerYLayer) + { + m_SkyLight[Index] = 15; + } // for y2 + break; // for y + } + + // Add current block as a seed: + m_IsSeed1[Index] = true; + m_SeedIdx1[m_NumSeeds++] = Index; + + // Light it up to full skylight: + m_SkyLight[Index] = 15; + } + } + } +} + + + + + +void cLightingThread::PrepareBlockLight(void) +{ + // Clear seeds: + memset(m_IsSeed1, 0, sizeof(m_IsSeed1)); + m_NumSeeds = 0; + + // Walk every column that has all XZ neighbors, make a seed for each light-emitting block: + for (int z = 1; z < cChunkDef::Width * 3 - 1; z++) + { + int BaseZ = z * cChunkDef::Width * 3; + for (int x = 1; x < cChunkDef::Width * 3 - 1; x++) + { + int idx = BaseZ + x; + for (int y = m_HeightMap[idx], Index = idx + y * BlocksPerYLayer; y >= 0; y--, Index -= BlocksPerYLayer) + { + if (g_BlockLightValue[m_BlockTypes[Index]] == 0) + { + continue; + } + + // Add current block as a seed: + m_IsSeed1[Index] = true; + m_SeedIdx1[m_NumSeeds++] = Index; + + // Light it up: + m_BlockLight[Index] = g_BlockLightValue[m_BlockTypes[Index]]; + } + } + } +} + + + + + +void cLightingThread::CalcLight(NIBBLETYPE * a_Light) +{ + int NumSeeds2 = 0; + while (m_NumSeeds > 0) + { + // Buffer 1 -> buffer 2 + memset(m_IsSeed2, 0, sizeof(m_IsSeed2)); + NumSeeds2 = 0; + CalcLightStep(a_Light, m_NumSeeds, m_IsSeed1, m_SeedIdx1, NumSeeds2, m_IsSeed2, m_SeedIdx2); + if (NumSeeds2 == 0) + { + return; + } + + // Buffer 2 -> buffer 1 + memset(m_IsSeed1, 0, sizeof(m_IsSeed1)); + m_NumSeeds = 0; + CalcLightStep(a_Light, NumSeeds2, m_IsSeed2, m_SeedIdx2, m_NumSeeds, m_IsSeed1, m_SeedIdx1); + } +} + + + + + +void cLightingThread::CalcLightStep( + NIBBLETYPE * a_Light, + int a_NumSeedsIn, unsigned char * a_IsSeedIn, unsigned int * a_SeedIdxIn, + int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut +) +{ + int NumSeedsOut = 0; + for (int i = 0; i < a_NumSeedsIn; i++) + { + int SeedIdx = a_SeedIdxIn[i]; + int SeedX = SeedIdx % (cChunkDef::Width * 3); + int SeedZ = (SeedIdx / (cChunkDef::Width * 3)) % (cChunkDef::Width * 3); + int SeedY = SeedIdx / BlocksPerYLayer; + + // Propagate seed: + if (SeedX < cChunkDef::Width * 3) + { + PropagateLight(a_Light, SeedIdx, SeedIdx + 1, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); + } + if (SeedX > 0) + { + PropagateLight(a_Light, SeedIdx, SeedIdx - 1, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); + } + if (SeedZ < cChunkDef::Width * 3) + { + PropagateLight(a_Light, SeedIdx, SeedIdx + cChunkDef::Width * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); + } + if (SeedZ > 0) + { + PropagateLight(a_Light, SeedIdx, SeedIdx - cChunkDef::Width * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); + } + if (SeedY < cChunkDef::Height) + { + PropagateLight(a_Light, SeedIdx, SeedIdx + cChunkDef::Width * cChunkDef::Width * 3 * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); + } + if (SeedY > 0) + { + PropagateLight(a_Light, SeedIdx, SeedIdx - cChunkDef::Width * cChunkDef::Width * 3 * 3, NumSeedsOut, a_IsSeedOut, a_SeedIdxOut); + } + } // for i - a_SeedIdxIn[] + a_NumSeedsOut = NumSeedsOut; +} + + + + + +void cLightingThread::CompressLight(NIBBLETYPE * a_LightArray, NIBBLETYPE * a_ChunkLight) +{ + int InIdx = cChunkDef::Width * 49; // Index to the first nibble of the middle chunk in the a_LightArray + int OutIdx = 0; + for (int y = 0; y < cChunkDef::Height; y++) + { + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int x = 0; x < cChunkDef::Width; x += 2) + { + a_ChunkLight[OutIdx++] = (a_LightArray[InIdx + 1] << 4) | a_LightArray[InIdx]; + InIdx += 2; + } + InIdx += cChunkDef::Width * 2; + } + // Skip into the next y-level in the 3x3 chunk blob; each level has cChunkDef::Width * 9 rows + // We've already walked cChunkDef::Width * 3 in the "for z" cycle, that makes cChunkDef::Width * 6 rows left to skip + InIdx += cChunkDef::Width * cChunkDef::Width * 6; + } +} + + + + diff --git a/source/LightingThread.h b/source/LightingThread.h index b1ff0d33f..96f7c009e 100644 --- a/source/LightingThread.h +++ b/source/LightingThread.h @@ -1,176 +1,176 @@ -
-// LightingThread.h
-
-// Interfaces to the cLightingThread class representing the thread that processes requests for lighting
-
-/*
-Lighting is done on whole chunks. For each chunk to be lighted, the whole 3x3 chunk area around it is read,
-then it is processed, so that the middle chunk area has valid lighting, and the lighting is copied into the ChunkMap.
-Lighting is calculated in full char arrays instead of nibbles, so that accessing the arrays is fast.
-Lighting is calculated in a flood-fill fashion:
-1. Generate seeds from where the light spreads (full skylight / light-emitting blocks)
-2. For each seed:
- - Spread the light 1 block in each of the 6 cardinal directions, if the blocktype allows
- - If the recipient block has had lower lighting value than that being spread, make it a new seed
-3. Repeat step 2, until there are no more seeds
-The seeds need two fast operations:
- - Check if a block at [x, y, z] is already a seed
- - Get the next seed in the row
-For that reason it is stored in two arrays, one stores a bool saying a seed is in that position,
-the other is an array of seed coords, encoded as a single int.
-Step 2 needs two separate storages for old seeds and new seeds, so there are two actual storages for that purpose,
-their content is swapped after each full step-2-cycle.
-
-The thread has two queues of chunks that are to be lighted.
-The first queue, m_Queue, is the only one that is publicly visible, chunks get queued there by external requests.
-The second one, m_PostponedQueue, is for chunks that have been taken out of m_Queue and didn't have neighbors ready.
-Chunks from m_PostponedQueue are moved back into m_Queue when their neighbors get valid, using the ChunkReady callback.
-*/
-
-
-
-#pragma once
-
-#include "cIsThread.h"
-#include "ChunkDef.h"
-
-
-
-
-
-// fwd: "cWorld.h"
-class cWorld;
-
-// fwd: "cChunkMap.h"
-class cChunkStay;
-
-
-
-
-
-class cLightingThread :
- public cIsThread
-{
- typedef cIsThread super;
-
-public:
-
- cLightingThread(void);
- ~cLightingThread();
-
- bool Start(cWorld * a_World);
-
- void Stop(void);
-
- /// Queues the entire chunk for lighting
- void QueueChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter = NULL);
-
- /// Blocks until the queue is empty or the thread is terminated
- void WaitForQueueEmpty(void);
-
- size_t GetQueueLength(void);
-
- /// Called from cWorld when a chunk gets valid. Chunks in m_PostponedQueue may need moving into m_Queue
- void ChunkReady(int a_ChunkX, int a_ChunkZ);
-
-protected:
-
- struct sItem
- {
- int x, z;
- cChunkStay * m_ChunkStay;
- cChunkCoordCallback * m_Callback;
-
- sItem(void) {} // empty default constructor needed
- sItem(int a_X, int a_Z, cChunkStay * a_ChunkStay, cChunkCoordCallback * a_Callback) :
- x(a_X),
- z(a_Z),
- m_ChunkStay(a_ChunkStay),
- m_Callback(a_Callback)
- {
- }
- } ;
-
- typedef std::list<sItem> sItems;
-
- cWorld * m_World;
- cCriticalSection m_CS;
- sItems m_Queue;
- sItems m_PostponedQueue; // Chunks that have been postponed due to missing neighbors
- cEvent m_evtItemAdded; // Set when queue is appended, or to stop the thread
- cEvent m_evtQueueEmpty; // Set when the queue gets empty
-
- // Buffers for the 3x3 chunk data
- // These buffers alone are 1.7 MiB in size, therefore they cannot be located on the stack safely - some architectures may have only 1 MiB for stack, or even less
- // Placing the buffers into the object means that this object can light chunks only in one thread!
- // The blobs are XZY organized as a whole, instead of 3x3 XZY-organized subarrays ->
- // -> This means data has to be scatterred when reading and gathered when writing!
- static const int BlocksPerYLayer = cChunkDef::Width * cChunkDef::Width * 3 * 3;
- BLOCKTYPE m_BlockTypes[BlocksPerYLayer * cChunkDef::Height];
- NIBBLETYPE m_BlockLight[BlocksPerYLayer * cChunkDef::Height];
- NIBBLETYPE m_SkyLight [BlocksPerYLayer * cChunkDef::Height];
- HEIGHTTYPE m_HeightMap [BlocksPerYLayer];
-
- // Seed management (5.7 MiB)
- // Two buffers, in each calc step one is set as input and the other as output, then in the next step they're swapped
- // Each seed is represented twice in this structure - both as a "list" and as a "position".
- // "list" allows fast traversal from seed to seed
- // "position" allows fast checking if a coord is already a seed
- unsigned char m_IsSeed1 [BlocksPerYLayer * cChunkDef::Height];
- unsigned int m_SeedIdx1[BlocksPerYLayer * cChunkDef::Height];
- unsigned char m_IsSeed2 [BlocksPerYLayer * cChunkDef::Height];
- unsigned int m_SeedIdx2[BlocksPerYLayer * cChunkDef::Height];
- int m_NumSeeds;
-
- virtual void Execute(void) override;
-
- /// Lights the entire chunk. If neighbor chunks don't exist, touches them and re-queues the chunk
- void LightChunk(sItem & a_Item);
-
- /// Prepares m_BlockTypes and m_HeightMap data; returns false if any of the chunks fail. Zeroes out the light arrays
- bool ReadChunks(int a_ChunkX, int a_ChunkZ);
-
- /// Uses m_HeightMap to initialize the m_SkyLight[] data; fills in seeds for the skylight
- void PrepareSkyLight(void);
-
- /// Uses m_BlockTypes to initialize the m_BlockLight[] data; fills in seeds for the blocklight
- void PrepareBlockLight(void);
-
- /// Calculates light in the light array specified, using stored seeds
- void CalcLight(NIBBLETYPE * a_Light);
-
- /// Does one step in the light calculation - one seed propagation and seed recalculation
- void CalcLightStep(
- NIBBLETYPE * a_Light,
- int a_NumSeedsIn, unsigned char * a_IsSeedIn, unsigned int * a_SeedIdxIn,
- int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut
- );
-
- /// Compresses from 1-byte-per-block into 2-bytes-per-block:
- void CompressLight(NIBBLETYPE * a_LightArray, NIBBLETYPE * a_ChunkLight);
-
- inline void PropagateLight(
- NIBBLETYPE * a_Light,
- int a_SrcIdx, int a_DstIdx,
- int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut
- )
- {
- if (a_Light[a_SrcIdx] <= a_Light[a_DstIdx] + g_BlockSpreadLightFalloff[m_BlockTypes[a_DstIdx]])
- {
- // We're not offering more light than the dest block already has
- return;
- }
-
- a_Light[a_DstIdx] = a_Light[a_SrcIdx] - g_BlockSpreadLightFalloff[m_BlockTypes[a_DstIdx]];
- if (!a_IsSeedOut[a_DstIdx])
- {
- a_IsSeedOut[a_DstIdx] = true;
- a_SeedIdxOut[a_NumSeedsOut++] = a_DstIdx;
- }
- }
-
-} ;
-
-
-
-
+ +// LightingThread.h + +// Interfaces to the cLightingThread class representing the thread that processes requests for lighting + +/* +Lighting is done on whole chunks. For each chunk to be lighted, the whole 3x3 chunk area around it is read, +then it is processed, so that the middle chunk area has valid lighting, and the lighting is copied into the ChunkMap. +Lighting is calculated in full char arrays instead of nibbles, so that accessing the arrays is fast. +Lighting is calculated in a flood-fill fashion: +1. Generate seeds from where the light spreads (full skylight / light-emitting blocks) +2. For each seed: + - Spread the light 1 block in each of the 6 cardinal directions, if the blocktype allows + - If the recipient block has had lower lighting value than that being spread, make it a new seed +3. Repeat step 2, until there are no more seeds +The seeds need two fast operations: + - Check if a block at [x, y, z] is already a seed + - Get the next seed in the row +For that reason it is stored in two arrays, one stores a bool saying a seed is in that position, +the other is an array of seed coords, encoded as a single int. +Step 2 needs two separate storages for old seeds and new seeds, so there are two actual storages for that purpose, +their content is swapped after each full step-2-cycle. + +The thread has two queues of chunks that are to be lighted. +The first queue, m_Queue, is the only one that is publicly visible, chunks get queued there by external requests. +The second one, m_PostponedQueue, is for chunks that have been taken out of m_Queue and didn't have neighbors ready. +Chunks from m_PostponedQueue are moved back into m_Queue when their neighbors get valid, using the ChunkReady callback. +*/ + + + +#pragma once + +#include "cIsThread.h" +#include "ChunkDef.h" + + + + + +// fwd: "cWorld.h" +class cWorld; + +// fwd: "cChunkMap.h" +class cChunkStay; + + + + + +class cLightingThread : + public cIsThread +{ + typedef cIsThread super; + +public: + + cLightingThread(void); + ~cLightingThread(); + + bool Start(cWorld * a_World); + + void Stop(void); + + /// Queues the entire chunk for lighting + void QueueChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter = NULL); + + /// Blocks until the queue is empty or the thread is terminated + void WaitForQueueEmpty(void); + + size_t GetQueueLength(void); + + /// Called from cWorld when a chunk gets valid. Chunks in m_PostponedQueue may need moving into m_Queue + void ChunkReady(int a_ChunkX, int a_ChunkZ); + +protected: + + struct sItem + { + int x, z; + cChunkStay * m_ChunkStay; + cChunkCoordCallback * m_Callback; + + sItem(void) {} // empty default constructor needed + sItem(int a_X, int a_Z, cChunkStay * a_ChunkStay, cChunkCoordCallback * a_Callback) : + x(a_X), + z(a_Z), + m_ChunkStay(a_ChunkStay), + m_Callback(a_Callback) + { + } + } ; + + typedef std::list<sItem> sItems; + + cWorld * m_World; + cCriticalSection m_CS; + sItems m_Queue; + sItems m_PostponedQueue; // Chunks that have been postponed due to missing neighbors + cEvent m_evtItemAdded; // Set when queue is appended, or to stop the thread + cEvent m_evtQueueEmpty; // Set when the queue gets empty + + // Buffers for the 3x3 chunk data + // These buffers alone are 1.7 MiB in size, therefore they cannot be located on the stack safely - some architectures may have only 1 MiB for stack, or even less + // Placing the buffers into the object means that this object can light chunks only in one thread! + // The blobs are XZY organized as a whole, instead of 3x3 XZY-organized subarrays -> + // -> This means data has to be scatterred when reading and gathered when writing! + static const int BlocksPerYLayer = cChunkDef::Width * cChunkDef::Width * 3 * 3; + BLOCKTYPE m_BlockTypes[BlocksPerYLayer * cChunkDef::Height]; + NIBBLETYPE m_BlockLight[BlocksPerYLayer * cChunkDef::Height]; + NIBBLETYPE m_SkyLight [BlocksPerYLayer * cChunkDef::Height]; + HEIGHTTYPE m_HeightMap [BlocksPerYLayer]; + + // Seed management (5.7 MiB) + // Two buffers, in each calc step one is set as input and the other as output, then in the next step they're swapped + // Each seed is represented twice in this structure - both as a "list" and as a "position". + // "list" allows fast traversal from seed to seed + // "position" allows fast checking if a coord is already a seed + unsigned char m_IsSeed1 [BlocksPerYLayer * cChunkDef::Height]; + unsigned int m_SeedIdx1[BlocksPerYLayer * cChunkDef::Height]; + unsigned char m_IsSeed2 [BlocksPerYLayer * cChunkDef::Height]; + unsigned int m_SeedIdx2[BlocksPerYLayer * cChunkDef::Height]; + int m_NumSeeds; + + virtual void Execute(void) override; + + /// Lights the entire chunk. If neighbor chunks don't exist, touches them and re-queues the chunk + void LightChunk(sItem & a_Item); + + /// Prepares m_BlockTypes and m_HeightMap data; returns false if any of the chunks fail. Zeroes out the light arrays + bool ReadChunks(int a_ChunkX, int a_ChunkZ); + + /// Uses m_HeightMap to initialize the m_SkyLight[] data; fills in seeds for the skylight + void PrepareSkyLight(void); + + /// Uses m_BlockTypes to initialize the m_BlockLight[] data; fills in seeds for the blocklight + void PrepareBlockLight(void); + + /// Calculates light in the light array specified, using stored seeds + void CalcLight(NIBBLETYPE * a_Light); + + /// Does one step in the light calculation - one seed propagation and seed recalculation + void CalcLightStep( + NIBBLETYPE * a_Light, + int a_NumSeedsIn, unsigned char * a_IsSeedIn, unsigned int * a_SeedIdxIn, + int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut + ); + + /// Compresses from 1-byte-per-block into 2-bytes-per-block: + void CompressLight(NIBBLETYPE * a_LightArray, NIBBLETYPE * a_ChunkLight); + + inline void PropagateLight( + NIBBLETYPE * a_Light, + int a_SrcIdx, int a_DstIdx, + int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut + ) + { + if (a_Light[a_SrcIdx] <= a_Light[a_DstIdx] + g_BlockSpreadLightFalloff[m_BlockTypes[a_DstIdx]]) + { + // We're not offering more light than the dest block already has + return; + } + + a_Light[a_DstIdx] = a_Light[a_SrcIdx] - g_BlockSpreadLightFalloff[m_BlockTypes[a_DstIdx]]; + if (!a_IsSeedOut[a_DstIdx]) + { + a_IsSeedOut[a_DstIdx] = true; + a_SeedIdxOut[a_NumSeedsOut++] = a_DstIdx; + } + } + +} ; + + + + diff --git a/source/LuaFunctions.h b/source/LuaFunctions.h index 04de7784f..66a505980 100644 --- a/source/LuaFunctions.h +++ b/source/LuaFunctions.h @@ -1,17 +1,17 @@ -#pragma once
-
-#include "cMCLogger.h"
-#include <time.h>
-// tolua_begin
-
-unsigned int GetTime()
-{
- return (unsigned int)time(0);
-}
-
-std::string GetChar( std::string & a_Str, unsigned int a_Idx )
-{
- return std::string(1, a_Str[ a_Idx ]);
-}
-
-// tolua_end
+#pragma once + +#include "cMCLogger.h" +#include <time.h> +// tolua_begin + +unsigned int GetTime() +{ + return (unsigned int)time(0); +} + +std::string GetChar( std::string & a_Str, unsigned int a_Idx ) +{ + return std::string(1, a_Str[ a_Idx ]); +} + +// tolua_end diff --git a/source/LuaItems.h b/source/LuaItems.h index 28ceb0d24..deec7f205 100644 --- a/source/LuaItems.h +++ b/source/LuaItems.h @@ -1,52 +1,52 @@ -
-// LuaItems.h
-
-// Interfaces to the cLuaItems class representing a wrapper class that allows Lua to access and manipulate cItems
-
-
-
-
-
-#pragma once
-
-#include "cItem.h"
-
-
-
-
-
-// tolua_begin
-class cLuaItems
-{
-public:
- // tolua_end
- // The constructor is not to be Lua-exported, Lua cannot make use of this object
- cLuaItems(cItems & a_Items) :
- m_Items(a_Items)
- {
- }
-
- // tolua_begin
- cItem & Get (int a_Idx) {return m_Items[a_Idx]; }
- void Set (int a_Idx, const cItem & a_Item) {m_Items[a_Idx] = a_Item; }
- void Add (const cItem & a_Item) {m_Items.push_back(a_Item); }
- void Delete(int a_Idx) {m_Items.erase(m_Items.begin() + a_Idx); }
- void Clear (void) {m_Items.clear(); }
- int Size (void) {return m_Items.size(); }
-
- void Add (ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth)
- {
- m_Items.push_back(cItem(a_ItemType, a_ItemCount, a_ItemHealth));
- }
-
- void Set (int a_Idx, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth)
- {
- m_Items[a_Idx] = cItem(a_ItemType, a_ItemCount, a_ItemHealth);
- }
-protected:
- cItems & m_Items;
-} ;
-// tolua_end
-
-
-
+ +// LuaItems.h + +// Interfaces to the cLuaItems class representing a wrapper class that allows Lua to access and manipulate cItems + + + + + +#pragma once + +#include "cItem.h" + + + + + +// tolua_begin +class cLuaItems +{ +public: + // tolua_end + // The constructor is not to be Lua-exported, Lua cannot make use of this object + cLuaItems(cItems & a_Items) : + m_Items(a_Items) + { + } + + // tolua_begin + cItem & Get (int a_Idx) {return m_Items[a_Idx]; } + void Set (int a_Idx, const cItem & a_Item) {m_Items[a_Idx] = a_Item; } + void Add (const cItem & a_Item) {m_Items.push_back(a_Item); } + void Delete(int a_Idx) {m_Items.erase(m_Items.begin() + a_Idx); } + void Clear (void) {m_Items.clear(); } + int Size (void) {return m_Items.size(); } + + void Add (ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth) + { + m_Items.push_back(cItem(a_ItemType, a_ItemCount, a_ItemHealth)); + } + + void Set (int a_Idx, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth) + { + m_Items[a_Idx] = cItem(a_ItemType, a_ItemCount, a_ItemHealth); + } +protected: + cItems & m_Items; +} ; +// tolua_end + + + diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index b6e1e9f72..8349f52f0 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -1,614 +1,614 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "ManualBindings.h"
-#include "tolua++.h"
-
-#include "cRoot.h"
-#include "cWorld.h"
-#include "cPlugin.h"
-#include "cPluginManager.h"
-#include "cWebPlugin_Lua.h"
-#include "cLuaCommandBinder.h"
-#include "cPlayer.h"
-#include "cWebAdmin.h"
-#include "cStringMap.h"
-#include "cClientHandle.h"
-#include "md5/md5.h"
-
-
-static bool report_errors(lua_State* lua, int status)
-{
- if ( status!=0 )
- {
- std::string s = lua_tostring(lua, -1);
- LOGERROR("-- %s", s.c_str() );
- lua_pop(lua, 1);
- return true;
- }
- return false;
-}
-
-
-/****************************
- * Lua bound functions with special return types
- **/
-
-static int tolua_StringSplit(lua_State* tolua_S)
-{
- std::string str = ((std::string) tolua_tocppstring(tolua_S,1,0));
- std::string delim = ((std::string) tolua_tocppstring(tolua_S,2,0));
-
- AStringVector Split = StringSplit( str, delim );
-
- lua_createtable(tolua_S, Split.size(), 0);
- int newTable = lua_gettop(tolua_S);
- int index = 1;
- std::vector<std::string>::const_iterator iter = Split.begin();
- while(iter != Split.end()) {
- tolua_pushstring( tolua_S, (*iter).c_str() );
- lua_rawseti(tolua_S, newTable, index);
- ++iter;
- ++index;
- }
- return 1;
-}
-
-
-
-
-
-static int tolua_LOG(lua_State* tolua_S)
-{
- const char* str = tolua_tocppstring(tolua_S,1,0);
- cMCLogger::GetInstance()->LogSimple( str, 0 );
- return 0;
-}
-
-
-
-
-
-static int tolua_LOGINFO(lua_State* tolua_S)
-{
- const char* str = tolua_tocppstring(tolua_S,1,0);
- cMCLogger::GetInstance()->LogSimple( str, 1 );
- return 0;
-}
-
-
-
-
-
-static int tolua_LOGWARN(lua_State* tolua_S)
-{
- const char* str = tolua_tocppstring(tolua_S,1,0);
- cMCLogger::GetInstance()->LogSimple( str, 2 );
- return 0;
-}
-
-
-
-
-
-static int tolua_LOGERROR(lua_State* tolua_S)
-{
- const char* str = tolua_tocppstring(tolua_S,1,0);
- cMCLogger::GetInstance()->LogSimple( str, 3 );
- return 0;
-}
-
-
-
-
-
-static int tolua_cRoot_ForEachWorld(lua_State * tolua_S)
-{
- int NumArgs = lua_gettop( tolua_S ) - 1; // This includes 'self'
- if ((NumArgs != 1) && (NumArgs != 2))
- {
- LOGWARN("Error in function call 'ForEachWorld': Requires 1 or 2 arguments, got %i", NumArgs);
- return 0;
- }
-
- cRoot * self = (cRoot *)tolua_tousertype(tolua_S, 1, 0);
-
- if (!lua_isfunction(tolua_S, 2))
- {
- LOGWARN("Error in function call 'ForEachWorld': Expected a function for parameter #1");
- return 0;
- }
-
- // luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top
- int TableRef = LUA_REFNIL;
- if( NumArgs == 2 )
- {
- TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
- if( TableRef == LUA_REFNIL )
- {
- LOGWARN("Error in function call 'ForEachWorld': Could not get value reference of parameter #2");
- return 0;
- }
- }
-
- // table value is popped, and now function is on top of the stack
- int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
- if( FuncRef == LUA_REFNIL )
- {
- LOGWARN("Error in function call 'ForEachWorld': Could not get function reference of parameter #1");
- return 0;
- }
-
- class cLuaWorldCallback : public cWorldListCallback
- {
- public:
- cLuaWorldCallback( lua_State* a_LuaState, int a_FuncRef, int a_TableRef )
- : LuaState( a_LuaState )
- , FuncRef( a_FuncRef )
- , TableRef( a_TableRef )
- {}
-
- private:
- virtual bool Item(cWorld * a_World) override
- {
- lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); // Push function reference
- tolua_pushusertype( LuaState, a_World, "cWorld" );
- if (TableRef != LUA_REFNIL)
- {
- lua_rawgeti(LuaState, LUA_REGISTRYINDEX, TableRef); // Push table reference
- }
-
- int s = lua_pcall( LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0);
- if (report_errors(LuaState, s))
- {
- return true; // break enumeration
- }
-
- if (lua_isboolean( LuaState, -1))
- {
- return (tolua_toboolean( LuaState, -1, 0) > 0);
- }
- return false; // continue enumeration
- }
- lua_State* LuaState;
- int FuncRef;
- int TableRef;
- } Callback( tolua_S, FuncRef, TableRef );
-
- bool bRetVal = self->ForEachWorld(Callback);
-
- // Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references
- luaL_unref( tolua_S, LUA_REGISTRYINDEX, TableRef );
- luaL_unref( tolua_S, LUA_REGISTRYINDEX, FuncRef );
-
- // Push return value on stack
- tolua_pushboolean( tolua_S, bRetVal );
- return 1;
-}
-
-
-
-
-
-static int tolua_cWorld_ForEachPlayer(lua_State* tolua_S)
-{
- int NumArgs = lua_gettop( tolua_S )-1; // This includes 'self'
- if( NumArgs != 1 && NumArgs != 2)
- {
- LOGWARN("Error in function call 'ForEachPlayer': Requires 1 or 2 arguments, got %i", NumArgs );
- return 0;
- }
-
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
-
- if( !lua_isfunction( tolua_S, 2 ) )
- {
- LOGWARN("Error in function call 'ForEachPlayer': Expected a function for parameter #1");
- return 0;
- }
-
- // luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top
- int TableRef = LUA_REFNIL;
- if( NumArgs == 2 )
- {
- TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
- if( TableRef == LUA_REFNIL )
- {
- LOGWARN("Error in function call 'ForEachPlayer': Could not get value reference of parameter #2");
- return 0;
- }
- }
-
- // table value is popped, and now function is on top of the stack
- int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
- if( FuncRef == LUA_REFNIL )
- {
- LOGWARN("Error in function call 'ForEachPlayer': Could not get function reference of parameter #1");
- return 0;
- }
-
- class cLuaPlayerCallback : public cPlayerListCallback
- {
- public:
- cLuaPlayerCallback( lua_State* a_LuaState, int a_FuncRef, int a_TableRef )
- : LuaState( a_LuaState )
- , FuncRef( a_FuncRef )
- , TableRef( a_TableRef )
- {}
-
- private:
- virtual bool Item(cPlayer * a_Player) override
- {
- lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); // Push function reference
- tolua_pushusertype( LuaState, a_Player, "cPlayer" );
- if( TableRef != LUA_REFNIL )
- {
- lua_rawgeti( LuaState, LUA_REGISTRYINDEX, TableRef); // Push table reference
- }
-
- int s = lua_pcall( LuaState, (TableRef==LUA_REFNIL?1:2), 1, 0);
- if( report_errors( LuaState, s ) )
- {
- return true; // Abort enumeration
- }
-
- if( lua_isboolean( LuaState, -1 ) )
- {
- return (tolua_toboolean( LuaState, -1, 0) > 0);
- }
- return false; // Continue enumeration
- }
- lua_State * LuaState;
- int FuncRef;
- int TableRef;
- } Callback( tolua_S, FuncRef, TableRef );
-
- bool bRetVal = self->ForEachPlayer( Callback );
-
- // Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references
- luaL_unref( tolua_S, LUA_REGISTRYINDEX, TableRef );
- luaL_unref( tolua_S, LUA_REGISTRYINDEX, FuncRef );
-
- // Push return value on stack
- tolua_pushboolean( tolua_S, bRetVal );
- return 1;
-}
-
-
-
-
-
-static int tolua_cPlugin_GetCommands(lua_State* tolua_S)
-{
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
-
- const std::vector< cPlugin::CommandStruct > & AllCommands = self->GetCommands();
-
- lua_createtable(tolua_S, AllCommands.size(), 0);
- int newTable = lua_gettop(tolua_S);
- int index = 1;
- std::vector< cPlugin::CommandStruct >::const_iterator iter = AllCommands.begin();
- while(iter != AllCommands.end())
- {
- const cPlugin::CommandStruct & CS = *iter;
- tolua_pushusertype( tolua_S, (void*)&CS, "const cPlugin::CommandStruct" );
- lua_rawseti(tolua_S, newTable, index);
- ++iter;
- ++index;
- }
- return 1;
-}
-
-
-
-
-
-static int tolua_cPluginManager_GetAllPlugins(lua_State* tolua_S)
-{
- cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
-
- const cPluginManager::PluginList & AllPlugins = self->GetAllPlugins();
-
- lua_createtable(tolua_S, AllPlugins.size(), 0);
- int newTable = lua_gettop(tolua_S);
- int index = 1;
- cPluginManager::PluginList::const_iterator iter = AllPlugins.begin();
- while(iter != AllPlugins.end())
- {
- const cPlugin* Plugin = *iter;
- tolua_pushusertype( tolua_S, (void*)Plugin, "const cPlugin" );
- lua_rawseti(tolua_S, newTable, index);
- ++iter;
- ++index;
- }
- return 1;
-}
-
-
-
-
-
-static int tolua_cPlayer_GetGroups(lua_State* tolua_S)
-{
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-
- const cPlayer::GroupList & AllGroups = self->GetGroups();
-
- lua_createtable(tolua_S, AllGroups.size(), 0);
- int newTable = lua_gettop(tolua_S);
- int index = 1;
- cPlayer::GroupList::const_iterator iter = AllGroups.begin();
- while(iter != AllGroups.end())
- {
- const cGroup* Group = *iter;
- tolua_pushusertype( tolua_S, (void*)Group, "const cGroup" );
- lua_rawseti(tolua_S, newTable, index);
- ++iter;
- ++index;
- }
- return 1;
-}
-
-
-
-
-
-static int tolua_cPlayer_GetResolvedPermissions(lua_State* tolua_S)
-{
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
-
- cPlayer::StringList AllPermissions = self->GetResolvedPermissions();
-
- lua_createtable(tolua_S, AllPermissions.size(), 0);
- int newTable = lua_gettop(tolua_S);
- int index = 1;
- cPlayer::StringList::iterator iter = AllPermissions.begin();
- while(iter != AllPermissions.end())
- {
- std::string& Permission = *iter;
- tolua_pushstring( tolua_S, Permission.c_str() );
- lua_rawseti(tolua_S, newTable, index);
- ++iter;
- ++index;
- }
- return 1;
-}
-
-
-
-
-
-static int tolua_cPlugin_BindCommand(lua_State* tolua_S)
-{
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
- cPluginManager* PluginManager = cRoot::Get()->GetPluginManager();
- cLuaCommandBinder* CommandBinder = PluginManager->GetLuaCommandBinder();
-
- tolua_Error tolua_err;
- tolua_err.array = 0;
- tolua_err.index = 0;
- tolua_err.type = 0;
-
- std::string Permission = "";
- std::string Command = "";
- int Reference = LUA_REFNIL;
-
- if( tolua_isstring( tolua_S, 2, 0, &tolua_err ) &&
- lua_isfunction( tolua_S, 3 ) )
- {
- Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
- Command = ((std::string) tolua_tocppstring(tolua_S,2,0));
- }
- else if( tolua_isstring( tolua_S, 2, 0, &tolua_err ) &&
- tolua_isstring( tolua_S, 3, 0, &tolua_err ) &&
- lua_isfunction( tolua_S, 4 ) )
- {
- Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
- Command = ((std::string) tolua_tocppstring(tolua_S,2,0));
- Permission = ((std::string) tolua_tocppstring(tolua_S,3,0));
- }
- else
- {
- if( tolua_err.type == 0 )
- {
- tolua_err.type = "function";
- }
- tolua_error(tolua_S,"#ferror in function 'BindCommand'.",&tolua_err);
- return 0;
- }
-
- if( Reference != LUA_REFNIL )
- {
- if( !CommandBinder->BindCommand( Command, Permission, self, tolua_S, Reference ) )
- {
- luaL_unref( tolua_S, LUA_REGISTRYINDEX, Reference );
- }
- }
- else
- {
- LOGERROR("ERROR: cPlugin:BindCommand invalid function reference in 2nd argument (Command: \"%s\")", Command.c_str() );
- }
-
- return 0;
-}
-
-
-
-
-
-static int tolua_cWebPlugin_Lua_AddTab(lua_State* tolua_S)
-{
- cWebPlugin_Lua* self = (cWebPlugin_Lua*) tolua_tousertype(tolua_S,1,0);
-
- tolua_Error tolua_err;
- tolua_err.array = 0;
- tolua_err.index = 0;
- tolua_err.type = 0;
-
- std::string Title = "";
- int Reference = LUA_REFNIL;
-
- if( tolua_isstring( tolua_S, 2, 0, &tolua_err ) &&
- lua_isfunction( tolua_S, 3 ) )
- {
- Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
- Title = ((std::string) tolua_tocppstring(tolua_S,2,0));
- }
- else
- {
- if( tolua_err.type == 0 )
- {
- tolua_err.type = "function";
- }
- tolua_error(tolua_S,"#ferror in function 'AddTab'.",&tolua_err);
- return 0;
- }
-
- if( Reference != LUA_REFNIL )
- {
- if( !self->AddTab( Title.c_str(), tolua_S, Reference ) )
- {
- luaL_unref( tolua_S, LUA_REGISTRYINDEX, Reference );
- }
- }
- else
- {
- LOGERROR("ERROR: cWebPlugin_Lua:AddTab invalid function reference in 2nd argument (Title: \"%s\")", Title.c_str() );
- }
-
- return 0;
-}
-
-
-
-
-
-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() );
- return 1;
-}
-
-
-
-
-
-static int tolua_push_StringStringMap(lua_State* tolua_S, std::map< std::string, std::string >& a_StringStringMap )
-{
- lua_newtable(tolua_S);
- int top = lua_gettop(tolua_S);
-
- for( std::map< std::string, std::string >::iterator it = a_StringStringMap.begin(); it != a_StringStringMap.end(); ++it )
- {
- const char* key = it->first.c_str();
- const char* value = it->second.c_str();
- lua_pushstring(tolua_S, key);
- lua_pushstring(tolua_S, value);
- lua_settable(tolua_S, top);
- }
-
- return 1;
-}
-
-
-
-
-
-static int tolua_get_HTTPRequest_Params(lua_State* tolua_S)
-{
- HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0);
- return tolua_push_StringStringMap(tolua_S, self->Params);
-}
-
-
-
-
-
-static int tolua_get_HTTPRequest_PostParams(lua_State* tolua_S)
-{
- HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0);
- return tolua_push_StringStringMap(tolua_S, self->PostParams);
-}
-
-
-
-
-
-static int tolua_get_HTTPRequest_FormData(lua_State* tolua_S)
-{
- HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0);
- std::map< std::string, HTTPFormData >& FormData = self->FormData;
-
- lua_newtable(tolua_S);
- int top = lua_gettop(tolua_S);
-
- for( std::map< std::string, HTTPFormData >::iterator it = FormData.begin(); it != FormData.end(); ++it )
- {
- lua_pushstring(tolua_S, it->first.c_str() );
- tolua_pushusertype(tolua_S, &(it->second), "HTTPFormData" );
- //lua_pushlstring(tolua_S, it->second.Value.c_str(), it->second.Value.size() ); // Might contain binary data
- lua_settable(tolua_S, top);
- }
-
- return 1;
-}
-
-
-
-
-
-void ManualBindings::Bind( lua_State* tolua_S )
-{
- tolua_beginmodule(tolua_S,NULL);
- tolua_function(tolua_S,"StringSplit",tolua_StringSplit);
- tolua_function(tolua_S,"LOG",tolua_LOG);
- tolua_function(tolua_S,"LOGINFO",tolua_LOGINFO);
- tolua_function(tolua_S,"LOGWARN",tolua_LOGWARN);
- tolua_function(tolua_S,"LOGERROR",tolua_LOGERROR);
- tolua_function(tolua_S,"Log",tolua_LOG); // Deprecated
-
- tolua_beginmodule(tolua_S,"cRoot");
- tolua_function(tolua_S,"ForEachWorld",tolua_cRoot_ForEachWorld);
- tolua_endmodule(tolua_S);
- tolua_beginmodule(tolua_S,"cWorld");
- tolua_function(tolua_S,"ForEachPlayer",tolua_cWorld_ForEachPlayer);
- tolua_endmodule(tolua_S);
- tolua_beginmodule(tolua_S,"cPlugin");
- tolua_function(tolua_S,"GetCommands",tolua_cPlugin_GetCommands);
- tolua_function(tolua_S,"BindCommand",tolua_cPlugin_BindCommand);
- tolua_endmodule(tolua_S);
- tolua_beginmodule(tolua_S,"cPluginManager");
- tolua_function(tolua_S,"GetAllPlugins",tolua_cPluginManager_GetAllPlugins);
- tolua_endmodule(tolua_S);
- tolua_beginmodule(tolua_S,"cPlayer");
- tolua_function(tolua_S,"GetGroups",tolua_cPlayer_GetGroups);
- tolua_function(tolua_S,"GetResolvedPermissions",tolua_cPlayer_GetResolvedPermissions);
- tolua_endmodule(tolua_S);
- tolua_beginmodule(tolua_S,"cWebPlugin_Lua");
- tolua_function(tolua_S,"AddTab",tolua_cWebPlugin_Lua_AddTab);
- tolua_endmodule(tolua_S);
-
- tolua_cclass(tolua_S,"HTTPRequest","HTTPRequest","",NULL);
- tolua_beginmodule(tolua_S,"HTTPRequest");
- //tolua_variable(tolua_S,"Method",tolua_get_HTTPRequest_Method,tolua_set_HTTPRequest_Method);
- //tolua_variable(tolua_S,"Path",tolua_get_HTTPRequest_Path,tolua_set_HTTPRequest_Path);
- tolua_variable(tolua_S,"Params",tolua_get_HTTPRequest_Params,0);
- tolua_variable(tolua_S,"PostParams",tolua_get_HTTPRequest_PostParams,0);
- tolua_variable(tolua_S,"FormData",tolua_get_HTTPRequest_FormData,0);
- tolua_endmodule(tolua_S);
-
- tolua_beginmodule(tolua_S,"cClientHandle");
- tolua_constant(tolua_S,"MIN_VIEW_DISTANCE",cClientHandle::MIN_VIEW_DISTANCE);
- tolua_constant(tolua_S,"MAX_VIEW_DISTANCE",cClientHandle::MAX_VIEW_DISTANCE);
- tolua_endmodule(tolua_S);
-
- tolua_function(tolua_S,"md5",tolua_md5);
-
- tolua_endmodule(tolua_S);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "ManualBindings.h" +#include "tolua++.h" + +#include "cRoot.h" +#include "cWorld.h" +#include "cPlugin.h" +#include "cPluginManager.h" +#include "cWebPlugin_Lua.h" +#include "cLuaCommandBinder.h" +#include "cPlayer.h" +#include "cWebAdmin.h" +#include "cStringMap.h" +#include "cClientHandle.h" +#include "md5/md5.h" + + +static bool report_errors(lua_State* lua, int status) +{ + if ( status!=0 ) + { + std::string s = lua_tostring(lua, -1); + LOGERROR("-- %s", s.c_str() ); + lua_pop(lua, 1); + return true; + } + return false; +} + + +/**************************** + * Lua bound functions with special return types + **/ + +static int tolua_StringSplit(lua_State* tolua_S) +{ + std::string str = ((std::string) tolua_tocppstring(tolua_S,1,0)); + std::string delim = ((std::string) tolua_tocppstring(tolua_S,2,0)); + + AStringVector Split = StringSplit( str, delim ); + + lua_createtable(tolua_S, Split.size(), 0); + int newTable = lua_gettop(tolua_S); + int index = 1; + std::vector<std::string>::const_iterator iter = Split.begin(); + while(iter != Split.end()) { + tolua_pushstring( tolua_S, (*iter).c_str() ); + lua_rawseti(tolua_S, newTable, index); + ++iter; + ++index; + } + return 1; +} + + + + + +static int tolua_LOG(lua_State* tolua_S) +{ + const char* str = tolua_tocppstring(tolua_S,1,0); + cMCLogger::GetInstance()->LogSimple( str, 0 ); + return 0; +} + + + + + +static int tolua_LOGINFO(lua_State* tolua_S) +{ + const char* str = tolua_tocppstring(tolua_S,1,0); + cMCLogger::GetInstance()->LogSimple( str, 1 ); + return 0; +} + + + + + +static int tolua_LOGWARN(lua_State* tolua_S) +{ + const char* str = tolua_tocppstring(tolua_S,1,0); + cMCLogger::GetInstance()->LogSimple( str, 2 ); + return 0; +} + + + + + +static int tolua_LOGERROR(lua_State* tolua_S) +{ + const char* str = tolua_tocppstring(tolua_S,1,0); + cMCLogger::GetInstance()->LogSimple( str, 3 ); + return 0; +} + + + + + +static int tolua_cRoot_ForEachWorld(lua_State * tolua_S) +{ + int NumArgs = lua_gettop( tolua_S ) - 1; // This includes 'self' + if ((NumArgs != 1) && (NumArgs != 2)) + { + LOGWARN("Error in function call 'ForEachWorld': Requires 1 or 2 arguments, got %i", NumArgs); + return 0; + } + + cRoot * self = (cRoot *)tolua_tousertype(tolua_S, 1, 0); + + if (!lua_isfunction(tolua_S, 2)) + { + LOGWARN("Error in function call 'ForEachWorld': Expected a function for parameter #1"); + return 0; + } + + // luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top + int TableRef = LUA_REFNIL; + if( NumArgs == 2 ) + { + TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if( TableRef == LUA_REFNIL ) + { + LOGWARN("Error in function call 'ForEachWorld': Could not get value reference of parameter #2"); + return 0; + } + } + + // table value is popped, and now function is on top of the stack + int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if( FuncRef == LUA_REFNIL ) + { + LOGWARN("Error in function call 'ForEachWorld': Could not get function reference of parameter #1"); + return 0; + } + + class cLuaWorldCallback : public cWorldListCallback + { + public: + cLuaWorldCallback( lua_State* a_LuaState, int a_FuncRef, int a_TableRef ) + : LuaState( a_LuaState ) + , FuncRef( a_FuncRef ) + , TableRef( a_TableRef ) + {} + + private: + virtual bool Item(cWorld * a_World) override + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); // Push function reference + tolua_pushusertype( LuaState, a_World, "cWorld" ); + if (TableRef != LUA_REFNIL) + { + lua_rawgeti(LuaState, LUA_REGISTRYINDEX, TableRef); // Push table reference + } + + int s = lua_pcall( LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); + if (report_errors(LuaState, s)) + { + return true; // break enumeration + } + + if (lua_isboolean( LuaState, -1)) + { + return (tolua_toboolean( LuaState, -1, 0) > 0); + } + return false; // continue enumeration + } + lua_State* LuaState; + int FuncRef; + int TableRef; + } Callback( tolua_S, FuncRef, TableRef ); + + bool bRetVal = self->ForEachWorld(Callback); + + // Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references + luaL_unref( tolua_S, LUA_REGISTRYINDEX, TableRef ); + luaL_unref( tolua_S, LUA_REGISTRYINDEX, FuncRef ); + + // Push return value on stack + tolua_pushboolean( tolua_S, bRetVal ); + return 1; +} + + + + + +static int tolua_cWorld_ForEachPlayer(lua_State* tolua_S) +{ + int NumArgs = lua_gettop( tolua_S )-1; // This includes 'self' + if( NumArgs != 1 && NumArgs != 2) + { + LOGWARN("Error in function call 'ForEachPlayer': Requires 1 or 2 arguments, got %i", NumArgs ); + return 0; + } + + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + + if( !lua_isfunction( tolua_S, 2 ) ) + { + LOGWARN("Error in function call 'ForEachPlayer': Expected a function for parameter #1"); + return 0; + } + + // luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top + int TableRef = LUA_REFNIL; + if( NumArgs == 2 ) + { + TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if( TableRef == LUA_REFNIL ) + { + LOGWARN("Error in function call 'ForEachPlayer': Could not get value reference of parameter #2"); + return 0; + } + } + + // table value is popped, and now function is on top of the stack + int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if( FuncRef == LUA_REFNIL ) + { + LOGWARN("Error in function call 'ForEachPlayer': Could not get function reference of parameter #1"); + return 0; + } + + class cLuaPlayerCallback : public cPlayerListCallback + { + public: + cLuaPlayerCallback( lua_State* a_LuaState, int a_FuncRef, int a_TableRef ) + : LuaState( a_LuaState ) + , FuncRef( a_FuncRef ) + , TableRef( a_TableRef ) + {} + + private: + virtual bool Item(cPlayer * a_Player) override + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); // Push function reference + tolua_pushusertype( LuaState, a_Player, "cPlayer" ); + if( TableRef != LUA_REFNIL ) + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, TableRef); // Push table reference + } + + int s = lua_pcall( LuaState, (TableRef==LUA_REFNIL?1:2), 1, 0); + if( report_errors( LuaState, s ) ) + { + return true; // Abort enumeration + } + + if( lua_isboolean( LuaState, -1 ) ) + { + return (tolua_toboolean( LuaState, -1, 0) > 0); + } + return false; // Continue enumeration + } + lua_State * LuaState; + int FuncRef; + int TableRef; + } Callback( tolua_S, FuncRef, TableRef ); + + bool bRetVal = self->ForEachPlayer( Callback ); + + // Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references + luaL_unref( tolua_S, LUA_REGISTRYINDEX, TableRef ); + luaL_unref( tolua_S, LUA_REGISTRYINDEX, FuncRef ); + + // Push return value on stack + tolua_pushboolean( tolua_S, bRetVal ); + return 1; +} + + + + + +static int tolua_cPlugin_GetCommands(lua_State* tolua_S) +{ + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + + const std::vector< cPlugin::CommandStruct > & AllCommands = self->GetCommands(); + + lua_createtable(tolua_S, AllCommands.size(), 0); + int newTable = lua_gettop(tolua_S); + int index = 1; + std::vector< cPlugin::CommandStruct >::const_iterator iter = AllCommands.begin(); + while(iter != AllCommands.end()) + { + const cPlugin::CommandStruct & CS = *iter; + tolua_pushusertype( tolua_S, (void*)&CS, "const cPlugin::CommandStruct" ); + lua_rawseti(tolua_S, newTable, index); + ++iter; + ++index; + } + return 1; +} + + + + + +static int tolua_cPluginManager_GetAllPlugins(lua_State* tolua_S) +{ + cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); + + const cPluginManager::PluginList & AllPlugins = self->GetAllPlugins(); + + lua_createtable(tolua_S, AllPlugins.size(), 0); + int newTable = lua_gettop(tolua_S); + int index = 1; + cPluginManager::PluginList::const_iterator iter = AllPlugins.begin(); + while(iter != AllPlugins.end()) + { + const cPlugin* Plugin = *iter; + tolua_pushusertype( tolua_S, (void*)Plugin, "const cPlugin" ); + lua_rawseti(tolua_S, newTable, index); + ++iter; + ++index; + } + return 1; +} + + + + + +static int tolua_cPlayer_GetGroups(lua_State* tolua_S) +{ + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + + const cPlayer::GroupList & AllGroups = self->GetGroups(); + + lua_createtable(tolua_S, AllGroups.size(), 0); + int newTable = lua_gettop(tolua_S); + int index = 1; + cPlayer::GroupList::const_iterator iter = AllGroups.begin(); + while(iter != AllGroups.end()) + { + const cGroup* Group = *iter; + tolua_pushusertype( tolua_S, (void*)Group, "const cGroup" ); + lua_rawseti(tolua_S, newTable, index); + ++iter; + ++index; + } + return 1; +} + + + + + +static int tolua_cPlayer_GetResolvedPermissions(lua_State* tolua_S) +{ + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + + cPlayer::StringList AllPermissions = self->GetResolvedPermissions(); + + lua_createtable(tolua_S, AllPermissions.size(), 0); + int newTable = lua_gettop(tolua_S); + int index = 1; + cPlayer::StringList::iterator iter = AllPermissions.begin(); + while(iter != AllPermissions.end()) + { + std::string& Permission = *iter; + tolua_pushstring( tolua_S, Permission.c_str() ); + lua_rawseti(tolua_S, newTable, index); + ++iter; + ++index; + } + return 1; +} + + + + + +static int tolua_cPlugin_BindCommand(lua_State* tolua_S) +{ + cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); + cPluginManager* PluginManager = cRoot::Get()->GetPluginManager(); + cLuaCommandBinder* CommandBinder = PluginManager->GetLuaCommandBinder(); + + tolua_Error tolua_err; + tolua_err.array = 0; + tolua_err.index = 0; + tolua_err.type = 0; + + std::string Permission = ""; + std::string Command = ""; + int Reference = LUA_REFNIL; + + if( tolua_isstring( tolua_S, 2, 0, &tolua_err ) && + lua_isfunction( tolua_S, 3 ) ) + { + Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); + } + else if( tolua_isstring( tolua_S, 2, 0, &tolua_err ) && + tolua_isstring( tolua_S, 3, 0, &tolua_err ) && + lua_isfunction( tolua_S, 4 ) ) + { + Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + Command = ((std::string) tolua_tocppstring(tolua_S,2,0)); + Permission = ((std::string) tolua_tocppstring(tolua_S,3,0)); + } + else + { + if( tolua_err.type == 0 ) + { + tolua_err.type = "function"; + } + tolua_error(tolua_S,"#ferror in function 'BindCommand'.",&tolua_err); + return 0; + } + + if( Reference != LUA_REFNIL ) + { + if( !CommandBinder->BindCommand( Command, Permission, self, tolua_S, Reference ) ) + { + luaL_unref( tolua_S, LUA_REGISTRYINDEX, Reference ); + } + } + else + { + LOGERROR("ERROR: cPlugin:BindCommand invalid function reference in 2nd argument (Command: \"%s\")", Command.c_str() ); + } + + return 0; +} + + + + + +static int tolua_cWebPlugin_Lua_AddTab(lua_State* tolua_S) +{ + cWebPlugin_Lua* self = (cWebPlugin_Lua*) tolua_tousertype(tolua_S,1,0); + + tolua_Error tolua_err; + tolua_err.array = 0; + tolua_err.index = 0; + tolua_err.type = 0; + + std::string Title = ""; + int Reference = LUA_REFNIL; + + if( tolua_isstring( tolua_S, 2, 0, &tolua_err ) && + lua_isfunction( tolua_S, 3 ) ) + { + Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + Title = ((std::string) tolua_tocppstring(tolua_S,2,0)); + } + else + { + if( tolua_err.type == 0 ) + { + tolua_err.type = "function"; + } + tolua_error(tolua_S,"#ferror in function 'AddTab'.",&tolua_err); + return 0; + } + + if( Reference != LUA_REFNIL ) + { + if( !self->AddTab( Title.c_str(), tolua_S, Reference ) ) + { + luaL_unref( tolua_S, LUA_REGISTRYINDEX, Reference ); + } + } + else + { + LOGERROR("ERROR: cWebPlugin_Lua:AddTab invalid function reference in 2nd argument (Title: \"%s\")", Title.c_str() ); + } + + return 0; +} + + + + + +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() ); + return 1; +} + + + + + +static int tolua_push_StringStringMap(lua_State* tolua_S, std::map< std::string, std::string >& a_StringStringMap ) +{ + lua_newtable(tolua_S); + int top = lua_gettop(tolua_S); + + for( std::map< std::string, std::string >::iterator it = a_StringStringMap.begin(); it != a_StringStringMap.end(); ++it ) + { + const char* key = it->first.c_str(); + const char* value = it->second.c_str(); + lua_pushstring(tolua_S, key); + lua_pushstring(tolua_S, value); + lua_settable(tolua_S, top); + } + + return 1; +} + + + + + +static int tolua_get_HTTPRequest_Params(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); + return tolua_push_StringStringMap(tolua_S, self->Params); +} + + + + + +static int tolua_get_HTTPRequest_PostParams(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); + return tolua_push_StringStringMap(tolua_S, self->PostParams); +} + + + + + +static int tolua_get_HTTPRequest_FormData(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); + std::map< std::string, HTTPFormData >& FormData = self->FormData; + + lua_newtable(tolua_S); + int top = lua_gettop(tolua_S); + + for( std::map< std::string, HTTPFormData >::iterator it = FormData.begin(); it != FormData.end(); ++it ) + { + lua_pushstring(tolua_S, it->first.c_str() ); + tolua_pushusertype(tolua_S, &(it->second), "HTTPFormData" ); + //lua_pushlstring(tolua_S, it->second.Value.c_str(), it->second.Value.size() ); // Might contain binary data + lua_settable(tolua_S, top); + } + + return 1; +} + + + + + +void ManualBindings::Bind( lua_State* tolua_S ) +{ + tolua_beginmodule(tolua_S,NULL); + tolua_function(tolua_S,"StringSplit",tolua_StringSplit); + tolua_function(tolua_S,"LOG",tolua_LOG); + tolua_function(tolua_S,"LOGINFO",tolua_LOGINFO); + tolua_function(tolua_S,"LOGWARN",tolua_LOGWARN); + tolua_function(tolua_S,"LOGERROR",tolua_LOGERROR); + tolua_function(tolua_S,"Log",tolua_LOG); // Deprecated + + tolua_beginmodule(tolua_S,"cRoot"); + tolua_function(tolua_S,"ForEachWorld",tolua_cRoot_ForEachWorld); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S,"cWorld"); + tolua_function(tolua_S,"ForEachPlayer",tolua_cWorld_ForEachPlayer); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S,"cPlugin"); + tolua_function(tolua_S,"GetCommands",tolua_cPlugin_GetCommands); + tolua_function(tolua_S,"BindCommand",tolua_cPlugin_BindCommand); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S,"cPluginManager"); + tolua_function(tolua_S,"GetAllPlugins",tolua_cPluginManager_GetAllPlugins); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S,"cPlayer"); + tolua_function(tolua_S,"GetGroups",tolua_cPlayer_GetGroups); + tolua_function(tolua_S,"GetResolvedPermissions",tolua_cPlayer_GetResolvedPermissions); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S,"cWebPlugin_Lua"); + tolua_function(tolua_S,"AddTab",tolua_cWebPlugin_Lua_AddTab); + tolua_endmodule(tolua_S); + + tolua_cclass(tolua_S,"HTTPRequest","HTTPRequest","",NULL); + tolua_beginmodule(tolua_S,"HTTPRequest"); + //tolua_variable(tolua_S,"Method",tolua_get_HTTPRequest_Method,tolua_set_HTTPRequest_Method); + //tolua_variable(tolua_S,"Path",tolua_get_HTTPRequest_Path,tolua_set_HTTPRequest_Path); + tolua_variable(tolua_S,"Params",tolua_get_HTTPRequest_Params,0); + tolua_variable(tolua_S,"PostParams",tolua_get_HTTPRequest_PostParams,0); + tolua_variable(tolua_S,"FormData",tolua_get_HTTPRequest_FormData,0); + tolua_endmodule(tolua_S); + + tolua_beginmodule(tolua_S,"cClientHandle"); + tolua_constant(tolua_S,"MIN_VIEW_DISTANCE",cClientHandle::MIN_VIEW_DISTANCE); + tolua_constant(tolua_S,"MAX_VIEW_DISTANCE",cClientHandle::MAX_VIEW_DISTANCE); + tolua_endmodule(tolua_S); + + tolua_function(tolua_S,"md5",tolua_md5); + + tolua_endmodule(tolua_S); +} + + + + diff --git a/source/ManualBindings.h b/source/ManualBindings.h index 147a1362d..e6594947e 100644 --- a/source/ManualBindings.h +++ b/source/ManualBindings.h @@ -1,8 +1,8 @@ -#pragma once
-
-struct lua_State;
-class ManualBindings
-{
-public:
- static void Bind( lua_State* tolua_S );
+#pragma once + +struct lua_State; +class ManualBindings +{ +public: + static void Bind( lua_State* tolua_S ); };
\ No newline at end of file diff --git a/source/Matrix4f.cpp b/source/Matrix4f.cpp index 322bad192..d0a407a99 100644 --- a/source/Matrix4f.cpp +++ b/source/Matrix4f.cpp @@ -1,4 +1,4 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-// _X: empty file??
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +// _X: empty file?? diff --git a/source/Matrix4f.h b/source/Matrix4f.h index 131208099..ab925da03 100644 --- a/source/Matrix4f.h +++ b/source/Matrix4f.h @@ -1,111 +1,111 @@ -#pragma once
-
-#define _USE_MATH_DEFINES
-#include <math.h>
-#include "Vector3f.h"
-
-class Matrix4f
-{
-public:
- enum
- {
- TX=3,
- TY=7,
- TZ=11,
- D0=0, D1=5, D2=10, D3=15,
- SX=D0, SY=D1, SZ=D2,
- W=D3
- };
- Matrix4f() { Identity(); }
- float& operator [] ( int a_N ) { return cell[a_N]; }
- void Identity()
- {
- cell[1] = cell[2] = cell[TX] = cell[4] = cell[6] = cell[TY] =
- cell[8] = cell[9] = cell[TZ] = cell[12] = cell[13] = cell[14] = 0;
- cell[D0] = cell[D1] = cell[D2] = cell[W] = 1;
- }
- void Init( Vector3f a_Pos, float a_RX, float a_RY, float a_RZ )
- {
- Matrix4f t;
- t.RotateX( a_RZ );
- RotateY( a_RY );
- Concatenate( t );
- t.RotateZ( a_RX );
- Concatenate( t );
- Translate( a_Pos );
- }
- void RotateX( float a_RX )
- {
- float sx = (float)sin( a_RX * M_PI / 180 );
- float cx = (float)cos( a_RX * M_PI / 180 );
- Identity();
- cell[5] = cx, cell[6] = sx, cell[9] = -sx, cell[10] = cx;
- }
- void RotateY( float a_RY )
- {
- float sy = (float)sin( a_RY * M_PI / 180 );
- float cy = (float)cos( a_RY * M_PI / 180 );
- Identity ();
- cell[0] = cy, cell[2] = -sy, cell[8] = sy, cell[10] = cy;
- }
- void RotateZ( float a_RZ )
- {
- float sz = (float)sin( a_RZ * M_PI / 180 );
- float cz = (float)cos( a_RZ * M_PI / 180 );
- Identity ();
- cell[0] = cz, cell[1] = sz, cell[4] = -sz, cell[5] = cz;
- }
- void Translate( Vector3f a_Pos ) { cell[TX] += a_Pos.x; cell[TY] += a_Pos.y; cell[TZ] += a_Pos.z; }
- void SetTranslation( Vector3f a_Pos ) { cell[TX] = a_Pos.x; cell[TY] = a_Pos.y; cell[TZ] = a_Pos.z; }
- void Concatenate( const Matrix4f& m2 )
- {
- Matrix4f res;
- int c;
- for ( c = 0; c < 4; c++ ) for ( int r = 0; r < 4; r++ )
- res.cell[r * 4 + c] = cell[r * 4] * m2.cell[c] +
- cell[r * 4 + 1] * m2.cell[c + 4] +
- cell[r * 4 + 2] * m2.cell[c + 8] +
- cell[r * 4 + 3] * m2.cell[c + 12];
- for ( c = 0; c < 16; c++ ) cell[c] = res.cell[c];
- }
- Vector3f Transform( const Vector3f& v ) const
- {
- float x = cell[0] * v.x + cell[1] * v.y + cell[2] * v.z + cell[3];
- float y = cell[4] * v.x + cell[5] * v.y + cell[6] * v.z + cell[7];
- float z = cell[8] * v.x + cell[9] * v.y + cell[10] * v.z + cell[11];
- return Vector3f( x, y, z );
- }
- void Invert()
- {
- Matrix4f t;
- int h, i;
- float tx = -cell[3], ty = -cell[7], tz = -cell[11];
- for ( h = 0; h < 3; h++ ) for ( int v = 0; v < 3; v++ ) t.cell[h + v * 4] = cell[v + h * 4];
- for ( i = 0; i < 11; i++ ) cell[i] = t.cell[i];
- cell[3] = tx * cell[0] + ty * cell[1] + tz * cell[2];
- cell[7] = tx * cell[4] + ty * cell[5] + tz * cell[6];
- cell[11] = tx * cell[8] + ty * cell[9] + tz * cell[10];
- }
- Vector3f GetXColumn() { return Vector3f( cell[0], cell[1], cell[2] ); }
- Vector3f GetYColumn() { return Vector3f( cell[4], cell[5], cell[6] ); }
- Vector3f GetZColumn() { return Vector3f( cell[8], cell[9], cell[10] ); }
- void SetXColumn( const Vector3f & a_X )
- {
- cell[0] = a_X.x;
- cell[1] = a_X.y;
- cell[2] = a_X.z;
- }
- void SetYColumn( const Vector3f & a_Y )
- {
- cell[4] = a_Y.x;
- cell[5] = a_Y.y;
- cell[6] = a_Y.z;
- }
- void SetZColumn( const Vector3f & a_Z )
- {
- cell[8] = a_Z.x;
- cell[9] = a_Z.y;
- cell[10] = a_Z.z;
- }
- float cell[16];
-};
+#pragma once + +#define _USE_MATH_DEFINES +#include <math.h> +#include "Vector3f.h" + +class Matrix4f +{ +public: + enum + { + TX=3, + TY=7, + TZ=11, + D0=0, D1=5, D2=10, D3=15, + SX=D0, SY=D1, SZ=D2, + W=D3 + }; + Matrix4f() { Identity(); } + float& operator [] ( int a_N ) { return cell[a_N]; } + void Identity() + { + cell[1] = cell[2] = cell[TX] = cell[4] = cell[6] = cell[TY] = + cell[8] = cell[9] = cell[TZ] = cell[12] = cell[13] = cell[14] = 0; + cell[D0] = cell[D1] = cell[D2] = cell[W] = 1; + } + void Init( Vector3f a_Pos, float a_RX, float a_RY, float a_RZ ) + { + Matrix4f t; + t.RotateX( a_RZ ); + RotateY( a_RY ); + Concatenate( t ); + t.RotateZ( a_RX ); + Concatenate( t ); + Translate( a_Pos ); + } + void RotateX( float a_RX ) + { + float sx = (float)sin( a_RX * M_PI / 180 ); + float cx = (float)cos( a_RX * M_PI / 180 ); + Identity(); + cell[5] = cx, cell[6] = sx, cell[9] = -sx, cell[10] = cx; + } + void RotateY( float a_RY ) + { + float sy = (float)sin( a_RY * M_PI / 180 ); + float cy = (float)cos( a_RY * M_PI / 180 ); + Identity (); + cell[0] = cy, cell[2] = -sy, cell[8] = sy, cell[10] = cy; + } + void RotateZ( float a_RZ ) + { + float sz = (float)sin( a_RZ * M_PI / 180 ); + float cz = (float)cos( a_RZ * M_PI / 180 ); + Identity (); + cell[0] = cz, cell[1] = sz, cell[4] = -sz, cell[5] = cz; + } + void Translate( Vector3f a_Pos ) { cell[TX] += a_Pos.x; cell[TY] += a_Pos.y; cell[TZ] += a_Pos.z; } + void SetTranslation( Vector3f a_Pos ) { cell[TX] = a_Pos.x; cell[TY] = a_Pos.y; cell[TZ] = a_Pos.z; } + void Concatenate( const Matrix4f& m2 ) + { + Matrix4f res; + int c; + for ( c = 0; c < 4; c++ ) for ( int r = 0; r < 4; r++ ) + res.cell[r * 4 + c] = cell[r * 4] * m2.cell[c] + + cell[r * 4 + 1] * m2.cell[c + 4] + + cell[r * 4 + 2] * m2.cell[c + 8] + + cell[r * 4 + 3] * m2.cell[c + 12]; + for ( c = 0; c < 16; c++ ) cell[c] = res.cell[c]; + } + Vector3f Transform( const Vector3f& v ) const + { + float x = cell[0] * v.x + cell[1] * v.y + cell[2] * v.z + cell[3]; + float y = cell[4] * v.x + cell[5] * v.y + cell[6] * v.z + cell[7]; + float z = cell[8] * v.x + cell[9] * v.y + cell[10] * v.z + cell[11]; + return Vector3f( x, y, z ); + } + void Invert() + { + Matrix4f t; + int h, i; + float tx = -cell[3], ty = -cell[7], tz = -cell[11]; + for ( h = 0; h < 3; h++ ) for ( int v = 0; v < 3; v++ ) t.cell[h + v * 4] = cell[v + h * 4]; + for ( i = 0; i < 11; i++ ) cell[i] = t.cell[i]; + cell[3] = tx * cell[0] + ty * cell[1] + tz * cell[2]; + cell[7] = tx * cell[4] + ty * cell[5] + tz * cell[6]; + cell[11] = tx * cell[8] + ty * cell[9] + tz * cell[10]; + } + Vector3f GetXColumn() { return Vector3f( cell[0], cell[1], cell[2] ); } + Vector3f GetYColumn() { return Vector3f( cell[4], cell[5], cell[6] ); } + Vector3f GetZColumn() { return Vector3f( cell[8], cell[9], cell[10] ); } + void SetXColumn( const Vector3f & a_X ) + { + cell[0] = a_X.x; + cell[1] = a_X.y; + cell[2] = a_X.z; + } + void SetYColumn( const Vector3f & a_Y ) + { + cell[4] = a_Y.x; + cell[5] = a_Y.y; + cell[6] = a_Y.z; + } + void SetZColumn( const Vector3f & a_Z ) + { + cell[8] = a_Z.x; + cell[9] = a_Z.y; + cell[10] = a_Z.z; + } + float cell[16]; +}; diff --git a/source/MemoryLeak.h b/source/MemoryLeak.h index a7f0c316b..e9c0c34e3 100644 --- a/source/MemoryLeak.h +++ b/source/MemoryLeak.h @@ -1,19 +1,19 @@ -#pragma once
-
-#ifdef _WIN32
- #ifdef _DEBUG
- // Enable the CRT debugging features:
- #define _CRTDBG_MAP_ALLOC
- #include <stdlib.h>
- #include <crtdbg.h>
-
- // This works only in MSVC 2010+:
- #if _MSC_VER >= 1600
- // Map the new operator
- #ifndef DEBUG_NEW
- #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
- #define new DEBUG_NEW
- #endif // _CRTDBG_MAP_ALLOC
- #endif // _MSC_VER
- #endif // _DEBUG
-#endif // _WIN32
+#pragma once + +#ifdef _WIN32 + #ifdef _DEBUG + // Enable the CRT debugging features: + #define _CRTDBG_MAP_ALLOC + #include <stdlib.h> + #include <crtdbg.h> + + // This works only in MSVC 2010+: + #if _MSC_VER >= 1600 + // Map the new operator + #ifndef DEBUG_NEW + #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) + #define new DEBUG_NEW + #endif // _CRTDBG_MAP_ALLOC + #endif // _MSC_VER + #endif // _DEBUG +#endif // _WIN32 diff --git a/source/MersenneTwister.h b/source/MersenneTwister.h index c6184ec0b..dc7134a93 100644 --- a/source/MersenneTwister.h +++ b/source/MersenneTwister.h @@ -1,456 +1,456 @@ -// MersenneTwister.h
-// Mersenne Twister random number generator -- a C++ class MTRand
-// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
-// Richard J. Wagner v1.1 28 September 2009 wagnerr@umich.edu
-
-// The Mersenne Twister is an algorithm for generating random numbers. It
-// was designed with consideration of the flaws in various other generators.
-// The period, 2^19937-1, and the order of equidistribution, 623 dimensions,
-// are far greater. The generator is also fast; it avoids multiplication and
-// division, and it benefits from caches and pipelines. For more information
-// see the inventors' web page at
-// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
-
-// Reference
-// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
-// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
-// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
-
-// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
-// Copyright (C) 2000 - 2009, Richard J. Wagner
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-//
-// 3. The names of its contributors may not be used to endorse or promote
-// products derived from this software without specific prior written
-// permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef MERSENNETWISTER_H
-#define MERSENNETWISTER_H
-
-// Not thread safe (unless auto-initialization is avoided and each thread has
-// its own MTRand object)
-
-#include <iostream>
-#include <climits>
-#include <cstdio>
-#include <ctime>
-#include <cmath>
-
-class MTRand {
-// Data
-public:
- typedef long uint32; // unsigned integer type, at least 32 bits
-
- enum { N = 624 }; // length of state vector
- enum { SAVE = N + 1 }; // length of array for save()
-
-protected:
- enum { M = 397 }; // period parameter
-
- uint32 state[N]; // internal state
- uint32 *pNext; // next value to get from state
- int left; // number of values left before reload needed
-
-// Methods
-public:
- MTRand( const uint32 oneSeed ); // initialize with a simple uint32
- MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or array
- MTRand(); // auto-initialize with /dev/urandom or time() and clock()
- MTRand( const MTRand& o ); // copy
-
- // Do NOT use for CRYPTOGRAPHY without securely hashing several returned
- // values together, otherwise the generator state can be learned after
- // reading 624 consecutive values.
-
- // Access to 32-bit random numbers
- uint32 randInt(); // integer in [0,2^32-1]
- uint32 randInt( const uint32 n ); // integer in [0,n] for n < 2^32
- double rand(); // real number in [0,1]
- double rand( const double n ); // real number in [0,n]
- double randExc(); // real number in [0,1)
- double randExc( const double n ); // real number in [0,n)
- double randDblExc(); // real number in (0,1)
- double randDblExc( const double n ); // real number in (0,n)
- double operator()(); // same as rand()
-
- // Access to 53-bit random numbers (capacity of IEEE double precision)
- double rand53(); // real number in [0,1)
-
- // Access to nonuniform random number distributions
- double randNorm( const double mean = 0.0, const double stddev = 1.0 );
-
- // Re-seeding functions with same behavior as initializers
- void seed( const uint32 oneSeed );
- void seed( uint32 *const bigSeed, const uint32 seedLength = N );
- void seed();
-
- // Saving and loading generator state
- void save( uint32* saveArray ) const; // to array of size SAVE
- void load( uint32 *const loadArray ); // from such array
- friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand );
- friend std::istream& operator>>( std::istream& is, MTRand& mtrand );
- MTRand& operator=( const MTRand& o );
-
-protected:
- void initialize( const uint32 oneSeed );
- void reload();
- uint32 hiBit( const uint32 u ) const { return u & 0x80000000UL; }
- uint32 loBit( const uint32 u ) const { return u & 0x00000001UL; }
- uint32 loBits( const uint32 u ) const { return u & 0x7fffffffUL; }
- uint32 mixBits( const uint32 u, const uint32 v ) const
- { return hiBit(u) | loBits(v); }
- uint32 magic( const uint32 u ) const
- { return loBit(u) ? 0x9908b0dfUL : 0x0UL; }
- uint32 twist( const uint32 m, const uint32 s0, const uint32 s1 ) const
- { return m ^ (mixBits(s0,s1)>>1) ^ magic(s1); }
- static uint32 hash( time_t t, clock_t c );
-};
-
-// Functions are defined in order of usage to assist inlining
-
-inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
-{
- // Get a uint32 from t and c
- // Better than uint32(x) in case x is floating point in [0,1]
- // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk)
-
- static uint32 differ = 0; // guarantee time-based seeds will change
-
- uint32 h1 = 0;
- unsigned char *p = (unsigned char *) &t;
- for( size_t i = 0; i < sizeof(t); ++i )
- {
- h1 *= UCHAR_MAX + 2U;
- h1 += p[i];
- }
- uint32 h2 = 0;
- p = (unsigned char *) &c;
- for( size_t j = 0; j < sizeof(c); ++j )
- {
- h2 *= UCHAR_MAX + 2U;
- h2 += p[j];
- }
- return ( h1 + differ++ ) ^ h2;
-}
-
-inline void MTRand::initialize( const uint32 seed )
-{
- // Initialize generator state with seed
- // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
- // In previous versions, most significant bits (MSBs) of the seed affect
- // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
- register uint32 *s = state;
- register uint32 *r = state;
- register int i = 1;
- *s++ = seed & 0xffffffffUL;
- for( ; i < N; ++i )
- {
- *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
- r++;
- }
-}
-
-inline void MTRand::reload()
-{
- // Generate N new values in state
- // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com)
- static const int MmN = int(M) - int(N); // in case enums are unsigned
- register uint32 *p = state;
- register int i;
- for( i = N - M; i--; ++p )
- *p = twist( p[M], p[0], p[1] );
- for( i = M; --i; ++p )
- *p = twist( p[MmN], p[0], p[1] );
- *p = twist( p[MmN], p[0], state[0] );
-
- left = N, pNext = state;
-}
-
-inline void MTRand::seed( const uint32 oneSeed )
-{
- // Seed the generator with a simple uint32
- initialize(oneSeed);
- reload();
-}
-
-inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength )
-{
- // Seed the generator with an array of uint32's
- // There are 2^19937-1 possible initial states. This function allows
- // all of those to be accessed by providing at least 19937 bits (with a
- // default seed length of N = 624 uint32's). Any bits above the lower 32
- // in each element are discarded.
- // Just call seed() if you want to get array from /dev/urandom
- initialize(19650218UL);
- register int i = 1;
- register uint32 j = 0;
- register int k = ( N > seedLength ? N : seedLength );
- for( ; k; --k )
- {
- state[i] =
- state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
- state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
- state[i] &= 0xffffffffUL;
- ++i; ++j;
- if( i >= N ) { state[0] = state[N-1]; i = 1; }
- if( j >= seedLength ) j = 0;
- }
- for( k = N - 1; k; --k )
- {
- state[i] =
- state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
- state[i] -= i;
- state[i] &= 0xffffffffUL;
- ++i;
- if( i >= N ) { state[0] = state[N-1]; i = 1; }
- }
- state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array
- reload();
-}
-
-inline void MTRand::seed()
-{
- // Seed the generator with an array from /dev/urandom if available
- // Otherwise use a hash of time() and clock() values
-
- // First try getting an array from /dev/urandom
-
- /* // Commented out by FakeTruth because doing this 200 times a tick is SUUUUPEERRR SLOW!!~~!ÕNe
- FILE* urandom = fopen( "/dev/urandom", "rb" );
- if( urandom )
- {
- uint32 bigSeed[N];
- register uint32 *s = bigSeed;
- register int i = N;
- register bool success = true;
- while( success && i-- )
- success = fread( s++, sizeof(uint32), 1, urandom );
- fclose(urandom);
- if( success ) { seed( bigSeed, N ); return; }
- }
- */
-
- // Was not successful, so use time() and clock() instead
- seed( hash( time(NULL), clock() ) );
-}
-
-inline MTRand::MTRand( const uint32 oneSeed )
- { seed(oneSeed); }
-
-inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength )
- { seed(bigSeed,seedLength); }
-
-inline MTRand::MTRand()
- { seed(); }
-
-inline MTRand::MTRand( const MTRand& o )
-{
- register const uint32 *t = o.state;
- register uint32 *s = state;
- register int i = N;
- for( ; i--; *s++ = *t++ ) {}
- left = o.left;
- pNext = &state[N-left];
-}
-
-inline MTRand::uint32 MTRand::randInt()
-{
- // Pull a 32-bit integer from the generator state
- // Every other access function simply transforms the numbers extracted here
-
- if( left == 0 ) reload();
- --left;
-
- register uint32 s1;
- s1 = *pNext++;
- s1 ^= (s1 >> 11);
- s1 ^= (s1 << 7) & 0x9d2c5680UL;
- s1 ^= (s1 << 15) & 0xefc60000UL;
- return ( s1 ^ (s1 >> 18) );
-}
-
-inline MTRand::uint32 MTRand::randInt( const uint32 n )
-{
- // Find which bits are used in n
- // Optimized by Magnus Jonsson (magnus@smartelectronix.com)
- uint32 used = n;
- used |= used >> 1;
- used |= used >> 2;
- used |= used >> 4;
- used |= used >> 8;
- used |= used >> 16;
-
- // Draw numbers until one is found in [0,n]
- uint32 i;
- do
- i = randInt() & used; // toss unused bits to shorten search
- while( i > n );
- return i;
-}
-
-inline double MTRand::rand()
- { return double(randInt()) * (1.0/4294967295.0); }
-
-inline double MTRand::rand( const double n )
- { return rand() * n; }
-
-inline double MTRand::randExc()
- { return double(randInt()) * (1.0/4294967296.0); }
-
-inline double MTRand::randExc( const double n )
- { return randExc() * n; }
-
-inline double MTRand::randDblExc()
- { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
-
-inline double MTRand::randDblExc( const double n )
- { return randDblExc() * n; }
-
-inline double MTRand::rand53()
-{
- uint32 a = randInt() >> 5, b = randInt() >> 6;
- return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada
-}
-
-inline double MTRand::randNorm( const double mean, const double stddev )
-{
- // Return a real number from a normal (Gaussian) distribution with given
- // mean and standard deviation by polar form of Box-Muller transformation
- double x, y, r;
- do
- {
- x = 2.0 * rand() - 1.0;
- y = 2.0 * rand() - 1.0;
- r = x * x + y * y;
- }
- while ( r >= 1.0 || r == 0.0 );
- double s = sqrt( -2.0 * log(r) / r );
- return mean + x * s * stddev;
-}
-
-inline double MTRand::operator()()
-{
- return rand();
-}
-
-inline void MTRand::save( uint32* saveArray ) const
-{
- register const uint32 *s = state;
- register uint32 *sa = saveArray;
- register int i = N;
- for( ; i--; *sa++ = *s++ ) {}
- *sa = left;
-}
-
-inline void MTRand::load( uint32 *const loadArray )
-{
- register uint32 *s = state;
- register uint32 *la = loadArray;
- register int i = N;
- for( ; i--; *s++ = *la++ ) {}
- left = *la;
- pNext = &state[N-left];
-}
-
-inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand )
-{
- register const MTRand::uint32 *s = mtrand.state;
- register int i = mtrand.N;
- for( ; i--; os << *s++ << "\t" ) {}
- return os << mtrand.left;
-}
-
-inline std::istream& operator>>( std::istream& is, MTRand& mtrand )
-{
- register MTRand::uint32 *s = mtrand.state;
- register int i = mtrand.N;
- for( ; i--; is >> *s++ ) {}
- is >> mtrand.left;
- mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
- return is;
-}
-
-inline MTRand& MTRand::operator=( const MTRand& o )
-{
- if( this == &o ) return (*this);
- register const uint32 *t = o.state;
- register uint32 *s = state;
- register int i = N;
- for( ; i--; *s++ = *t++ ) {}
- left = o.left;
- pNext = &state[N-left];
- return (*this);
-}
-
-#endif // MERSENNETWISTER_H
-
-// Change log:
-//
-// v0.1 - First release on 15 May 2000
-// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
-// - Translated from C to C++
-// - Made completely ANSI compliant
-// - Designed convenient interface for initialization, seeding, and
-// obtaining numbers in default or user-defined ranges
-// - Added automatic seeding from /dev/urandom or time() and clock()
-// - Provided functions for saving and loading generator state
-//
-// v0.2 - Fixed bug which reloaded generator one step too late
-//
-// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
-//
-// v0.4 - Removed trailing newline in saved generator format to be consistent
-// with output format of built-in types
-//
-// v0.5 - Improved portability by replacing static const int's with enum's and
-// clarifying return values in seed(); suggested by Eric Heimburg
-// - Removed MAXINT constant; use 0xffffffffUL instead
-//
-// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
-// - Changed integer [0,n] generator to give better uniformity
-//
-// v0.7 - Fixed operator precedence ambiguity in reload()
-// - Added access for real numbers in (0,1) and (0,n)
-//
-// v0.8 - Included time.h header to properly support time_t and clock_t
-//
-// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
-// - Allowed for seeding with arrays of any length
-// - Added access for real numbers in [0,1) with 53-bit resolution
-// - Added access for real numbers from normal (Gaussian) distributions
-// - Increased overall speed by optimizing twist()
-// - Doubled speed of integer [0,n] generation
-// - Fixed out-of-range number generation on 64-bit machines
-// - Improved portability by substituting literal constants for long enum's
-// - Changed license from GNU LGPL to BSD
-//
-// v1.1 - Corrected parameter label in randNorm from "variance" to "stddev"
-// - Changed randNorm algorithm from basic to polar form for efficiency
-// - Updated includes from deprecated <xxxx.h> to standard <cxxxx> forms
-// - Cleaned declarations and definitions to please Intel compiler
-// - Revised twist() operator to work on ones'-complement machines
-// - Fixed reload() function to work when N and M are unsigned
-// - Added copy constructor and copy operator from Salvador Espana
+// MersenneTwister.h +// Mersenne Twister random number generator -- a C++ class MTRand +// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus +// Richard J. Wagner v1.1 28 September 2009 wagnerr@umich.edu + +// The Mersenne Twister is an algorithm for generating random numbers. It +// was designed with consideration of the flaws in various other generators. +// The period, 2^19937-1, and the order of equidistribution, 623 dimensions, +// are far greater. The generator is also fast; it avoids multiplication and +// division, and it benefits from caches and pipelines. For more information +// see the inventors' web page at +// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + +// Reference +// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally +// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on +// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. + +// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, +// Copyright (C) 2000 - 2009, Richard J. Wagner +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The names of its contributors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef MERSENNETWISTER_H +#define MERSENNETWISTER_H + +// Not thread safe (unless auto-initialization is avoided and each thread has +// its own MTRand object) + +#include <iostream> +#include <climits> +#include <cstdio> +#include <ctime> +#include <cmath> + +class MTRand { +// Data +public: + typedef long uint32; // unsigned integer type, at least 32 bits + + enum { N = 624 }; // length of state vector + enum { SAVE = N + 1 }; // length of array for save() + +protected: + enum { M = 397 }; // period parameter + + uint32 state[N]; // internal state + uint32 *pNext; // next value to get from state + int left; // number of values left before reload needed + +// Methods +public: + MTRand( const uint32 oneSeed ); // initialize with a simple uint32 + MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or array + MTRand(); // auto-initialize with /dev/urandom or time() and clock() + MTRand( const MTRand& o ); // copy + + // Do NOT use for CRYPTOGRAPHY without securely hashing several returned + // values together, otherwise the generator state can be learned after + // reading 624 consecutive values. + + // Access to 32-bit random numbers + uint32 randInt(); // integer in [0,2^32-1] + uint32 randInt( const uint32 n ); // integer in [0,n] for n < 2^32 + double rand(); // real number in [0,1] + double rand( const double n ); // real number in [0,n] + double randExc(); // real number in [0,1) + double randExc( const double n ); // real number in [0,n) + double randDblExc(); // real number in (0,1) + double randDblExc( const double n ); // real number in (0,n) + double operator()(); // same as rand() + + // Access to 53-bit random numbers (capacity of IEEE double precision) + double rand53(); // real number in [0,1) + + // Access to nonuniform random number distributions + double randNorm( const double mean = 0.0, const double stddev = 1.0 ); + + // Re-seeding functions with same behavior as initializers + void seed( const uint32 oneSeed ); + void seed( uint32 *const bigSeed, const uint32 seedLength = N ); + void seed(); + + // Saving and loading generator state + void save( uint32* saveArray ) const; // to array of size SAVE + void load( uint32 *const loadArray ); // from such array + friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ); + friend std::istream& operator>>( std::istream& is, MTRand& mtrand ); + MTRand& operator=( const MTRand& o ); + +protected: + void initialize( const uint32 oneSeed ); + void reload(); + uint32 hiBit( const uint32 u ) const { return u & 0x80000000UL; } + uint32 loBit( const uint32 u ) const { return u & 0x00000001UL; } + uint32 loBits( const uint32 u ) const { return u & 0x7fffffffUL; } + uint32 mixBits( const uint32 u, const uint32 v ) const + { return hiBit(u) | loBits(v); } + uint32 magic( const uint32 u ) const + { return loBit(u) ? 0x9908b0dfUL : 0x0UL; } + uint32 twist( const uint32 m, const uint32 s0, const uint32 s1 ) const + { return m ^ (mixBits(s0,s1)>>1) ^ magic(s1); } + static uint32 hash( time_t t, clock_t c ); +}; + +// Functions are defined in order of usage to assist inlining + +inline MTRand::uint32 MTRand::hash( time_t t, clock_t c ) +{ + // Get a uint32 from t and c + // Better than uint32(x) in case x is floating point in [0,1] + // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk) + + static uint32 differ = 0; // guarantee time-based seeds will change + + uint32 h1 = 0; + unsigned char *p = (unsigned char *) &t; + for( size_t i = 0; i < sizeof(t); ++i ) + { + h1 *= UCHAR_MAX + 2U; + h1 += p[i]; + } + uint32 h2 = 0; + p = (unsigned char *) &c; + for( size_t j = 0; j < sizeof(c); ++j ) + { + h2 *= UCHAR_MAX + 2U; + h2 += p[j]; + } + return ( h1 + differ++ ) ^ h2; +} + +inline void MTRand::initialize( const uint32 seed ) +{ + // Initialize generator state with seed + // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. + // In previous versions, most significant bits (MSBs) of the seed affect + // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. + register uint32 *s = state; + register uint32 *r = state; + register int i = 1; + *s++ = seed & 0xffffffffUL; + for( ; i < N; ++i ) + { + *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL; + r++; + } +} + +inline void MTRand::reload() +{ + // Generate N new values in state + // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) + static const int MmN = int(M) - int(N); // in case enums are unsigned + register uint32 *p = state; + register int i; + for( i = N - M; i--; ++p ) + *p = twist( p[M], p[0], p[1] ); + for( i = M; --i; ++p ) + *p = twist( p[MmN], p[0], p[1] ); + *p = twist( p[MmN], p[0], state[0] ); + + left = N, pNext = state; +} + +inline void MTRand::seed( const uint32 oneSeed ) +{ + // Seed the generator with a simple uint32 + initialize(oneSeed); + reload(); +} + +inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength ) +{ + // Seed the generator with an array of uint32's + // There are 2^19937-1 possible initial states. This function allows + // all of those to be accessed by providing at least 19937 bits (with a + // default seed length of N = 624 uint32's). Any bits above the lower 32 + // in each element are discarded. + // Just call seed() if you want to get array from /dev/urandom + initialize(19650218UL); + register int i = 1; + register uint32 j = 0; + register int k = ( N > seedLength ? N : seedLength ); + for( ; k; --k ) + { + state[i] = + state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL ); + state[i] += ( bigSeed[j] & 0xffffffffUL ) + j; + state[i] &= 0xffffffffUL; + ++i; ++j; + if( i >= N ) { state[0] = state[N-1]; i = 1; } + if( j >= seedLength ) j = 0; + } + for( k = N - 1; k; --k ) + { + state[i] = + state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL ); + state[i] -= i; + state[i] &= 0xffffffffUL; + ++i; + if( i >= N ) { state[0] = state[N-1]; i = 1; } + } + state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array + reload(); +} + +inline void MTRand::seed() +{ + // Seed the generator with an array from /dev/urandom if available + // Otherwise use a hash of time() and clock() values + + // First try getting an array from /dev/urandom + + /* // Commented out by FakeTruth because doing this 200 times a tick is SUUUUPEERRR SLOW!!~~!ÕNe + FILE* urandom = fopen( "/dev/urandom", "rb" ); + if( urandom ) + { + uint32 bigSeed[N]; + register uint32 *s = bigSeed; + register int i = N; + register bool success = true; + while( success && i-- ) + success = fread( s++, sizeof(uint32), 1, urandom ); + fclose(urandom); + if( success ) { seed( bigSeed, N ); return; } + } + */ + + // Was not successful, so use time() and clock() instead + seed( hash( time(NULL), clock() ) ); +} + +inline MTRand::MTRand( const uint32 oneSeed ) + { seed(oneSeed); } + +inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength ) + { seed(bigSeed,seedLength); } + +inline MTRand::MTRand() + { seed(); } + +inline MTRand::MTRand( const MTRand& o ) +{ + register const uint32 *t = o.state; + register uint32 *s = state; + register int i = N; + for( ; i--; *s++ = *t++ ) {} + left = o.left; + pNext = &state[N-left]; +} + +inline MTRand::uint32 MTRand::randInt() +{ + // Pull a 32-bit integer from the generator state + // Every other access function simply transforms the numbers extracted here + + if( left == 0 ) reload(); + --left; + + register uint32 s1; + s1 = *pNext++; + s1 ^= (s1 >> 11); + s1 ^= (s1 << 7) & 0x9d2c5680UL; + s1 ^= (s1 << 15) & 0xefc60000UL; + return ( s1 ^ (s1 >> 18) ); +} + +inline MTRand::uint32 MTRand::randInt( const uint32 n ) +{ + // Find which bits are used in n + // Optimized by Magnus Jonsson (magnus@smartelectronix.com) + uint32 used = n; + used |= used >> 1; + used |= used >> 2; + used |= used >> 4; + used |= used >> 8; + used |= used >> 16; + + // Draw numbers until one is found in [0,n] + uint32 i; + do + i = randInt() & used; // toss unused bits to shorten search + while( i > n ); + return i; +} + +inline double MTRand::rand() + { return double(randInt()) * (1.0/4294967295.0); } + +inline double MTRand::rand( const double n ) + { return rand() * n; } + +inline double MTRand::randExc() + { return double(randInt()) * (1.0/4294967296.0); } + +inline double MTRand::randExc( const double n ) + { return randExc() * n; } + +inline double MTRand::randDblExc() + { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); } + +inline double MTRand::randDblExc( const double n ) + { return randDblExc() * n; } + +inline double MTRand::rand53() +{ + uint32 a = randInt() >> 5, b = randInt() >> 6; + return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada +} + +inline double MTRand::randNorm( const double mean, const double stddev ) +{ + // Return a real number from a normal (Gaussian) distribution with given + // mean and standard deviation by polar form of Box-Muller transformation + double x, y, r; + do + { + x = 2.0 * rand() - 1.0; + y = 2.0 * rand() - 1.0; + r = x * x + y * y; + } + while ( r >= 1.0 || r == 0.0 ); + double s = sqrt( -2.0 * log(r) / r ); + return mean + x * s * stddev; +} + +inline double MTRand::operator()() +{ + return rand(); +} + +inline void MTRand::save( uint32* saveArray ) const +{ + register const uint32 *s = state; + register uint32 *sa = saveArray; + register int i = N; + for( ; i--; *sa++ = *s++ ) {} + *sa = left; +} + +inline void MTRand::load( uint32 *const loadArray ) +{ + register uint32 *s = state; + register uint32 *la = loadArray; + register int i = N; + for( ; i--; *s++ = *la++ ) {} + left = *la; + pNext = &state[N-left]; +} + +inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ) +{ + register const MTRand::uint32 *s = mtrand.state; + register int i = mtrand.N; + for( ; i--; os << *s++ << "\t" ) {} + return os << mtrand.left; +} + +inline std::istream& operator>>( std::istream& is, MTRand& mtrand ) +{ + register MTRand::uint32 *s = mtrand.state; + register int i = mtrand.N; + for( ; i--; is >> *s++ ) {} + is >> mtrand.left; + mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left]; + return is; +} + +inline MTRand& MTRand::operator=( const MTRand& o ) +{ + if( this == &o ) return (*this); + register const uint32 *t = o.state; + register uint32 *s = state; + register int i = N; + for( ; i--; *s++ = *t++ ) {} + left = o.left; + pNext = &state[N-left]; + return (*this); +} + +#endif // MERSENNETWISTER_H + +// Change log: +// +// v0.1 - First release on 15 May 2000 +// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus +// - Translated from C to C++ +// - Made completely ANSI compliant +// - Designed convenient interface for initialization, seeding, and +// obtaining numbers in default or user-defined ranges +// - Added automatic seeding from /dev/urandom or time() and clock() +// - Provided functions for saving and loading generator state +// +// v0.2 - Fixed bug which reloaded generator one step too late +// +// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew +// +// v0.4 - Removed trailing newline in saved generator format to be consistent +// with output format of built-in types +// +// v0.5 - Improved portability by replacing static const int's with enum's and +// clarifying return values in seed(); suggested by Eric Heimburg +// - Removed MAXINT constant; use 0xffffffffUL instead +// +// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits +// - Changed integer [0,n] generator to give better uniformity +// +// v0.7 - Fixed operator precedence ambiguity in reload() +// - Added access for real numbers in (0,1) and (0,n) +// +// v0.8 - Included time.h header to properly support time_t and clock_t +// +// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto +// - Allowed for seeding with arrays of any length +// - Added access for real numbers in [0,1) with 53-bit resolution +// - Added access for real numbers from normal (Gaussian) distributions +// - Increased overall speed by optimizing twist() +// - Doubled speed of integer [0,n] generation +// - Fixed out-of-range number generation on 64-bit machines +// - Improved portability by substituting literal constants for long enum's +// - Changed license from GNU LGPL to BSD +// +// v1.1 - Corrected parameter label in randNorm from "variance" to "stddev" +// - Changed randNorm algorithm from basic to polar form for efficiency +// - Updated includes from deprecated <xxxx.h> to standard <cxxxx> forms +// - Cleaned declarations and definitions to please Intel compiler +// - Revised twist() operator to work on ones'-complement machines +// - Fixed reload() function to work when N and M are unsigned +// - Added copy constructor and copy operator from Salvador Espana diff --git a/source/PacketID.h b/source/PacketID.h index d557a284f..f11688284 100644 --- a/source/PacketID.h +++ b/source/PacketID.h @@ -1,61 +1,61 @@ -#pragma once
-
-//tolua_begin
-enum ENUM_PACKET_ID
-{
- E_KEEP_ALIVE = 0x00,
- E_LOGIN = 0x01,
- E_HANDSHAKE = 0x02,
- E_CHAT = 0x03,
- E_UPDATE_TIME = 0x04,
- E_ENTITY_EQUIPMENT = 0x05,
- E_USE_ENTITY = 0x07,
- E_UPDATE_HEALTH = 0x08,
- E_RESPAWN = 0x09,
- E_FLYING = 0x0a,
- E_PLAYERPOS = 0x0b,
- E_PLAYERLOOK = 0x0c,
- E_PLAYERMOVELOOK = 0x0d,
- E_BLOCK_DIG = 0x0e,
- E_BLOCK_PLACE = 0x0f,
- E_ITEM_SWITCH = 0x10,
- E_ADD_TO_INV = 0x11, // TODO: Sure this is not Use Bed??
- E_ANIMATION = 0x12,
- E_PACKET_13 = 0x13,
- E_NAMED_ENTITY_SPAWN = 0x14,
- E_PICKUP_SPAWN = 0x15,
- E_COLLECT_ITEM = 0x16,
- E_ADD_VEHICLE = 0x17,
- E_SPAWN_MOB = 0x18,
- E_DESTROY_ENT = 0x1d,
- E_ENTITY = 0x1e,
- E_REL_ENT_MOVE = 0x1f,
- E_ENT_LOOK = 0x20,
- E_REL_ENT_MOVE_LOOK = 0x21,
- E_ENT_TELEPORT = 0x22,
- E_ENT_HEAD_LOOK = 0x23,
- E_ENT_STATUS = 0x26,
- E_METADATA = 0x28,
- E_PRE_CHUNK = 0x32,
- E_MAP_CHUNK = 0x33,
- E_MULTI_BLOCK = 0x34,
- E_BLOCK_CHANGE = 0x35,
- E_BLOCK_ACTION = 0x36,
- E_EXPLOSION = 0x3C,
- E_SOUND_EFFECT = 0x3D,
- E_NEW_INVALID_STATE = 0x46,
- E_THUNDERBOLT = 0x47,
- E_WINDOW_OPEN = 0x64,
- E_WINDOW_CLOSE = 0x65,
- E_WINDOW_CLICK = 0x66,
- E_INVENTORY_SLOT = 0x67,
- E_INVENTORY_WHOLE = 0x68,
- E_INVENTORY_PROGRESS = 0x69,
- E_CREATIVE_INVENTORY_ACTION = 0x6B,
- E_UPDATE_SIGN = 0x82,
- E_PLAYER_LIST_ITEM = 0xC9,
- E_PLAYER_ABILITIES = 0xca, // since 1.2.4, protocol version 29
- E_PING = 0xfe,
- E_DISCONNECT = 0xff,
-};
-//tolua_end
+#pragma once + +//tolua_begin +enum ENUM_PACKET_ID +{ + E_KEEP_ALIVE = 0x00, + E_LOGIN = 0x01, + E_HANDSHAKE = 0x02, + E_CHAT = 0x03, + E_UPDATE_TIME = 0x04, + E_ENTITY_EQUIPMENT = 0x05, + E_USE_ENTITY = 0x07, + E_UPDATE_HEALTH = 0x08, + E_RESPAWN = 0x09, + E_FLYING = 0x0a, + E_PLAYERPOS = 0x0b, + E_PLAYERLOOK = 0x0c, + E_PLAYERMOVELOOK = 0x0d, + E_BLOCK_DIG = 0x0e, + E_BLOCK_PLACE = 0x0f, + E_ITEM_SWITCH = 0x10, + E_ADD_TO_INV = 0x11, // TODO: Sure this is not Use Bed?? + E_ANIMATION = 0x12, + E_PACKET_13 = 0x13, + E_NAMED_ENTITY_SPAWN = 0x14, + E_PICKUP_SPAWN = 0x15, + E_COLLECT_ITEM = 0x16, + E_ADD_VEHICLE = 0x17, + E_SPAWN_MOB = 0x18, + E_DESTROY_ENT = 0x1d, + E_ENTITY = 0x1e, + E_REL_ENT_MOVE = 0x1f, + E_ENT_LOOK = 0x20, + E_REL_ENT_MOVE_LOOK = 0x21, + E_ENT_TELEPORT = 0x22, + E_ENT_HEAD_LOOK = 0x23, + E_ENT_STATUS = 0x26, + E_METADATA = 0x28, + E_PRE_CHUNK = 0x32, + E_MAP_CHUNK = 0x33, + E_MULTI_BLOCK = 0x34, + E_BLOCK_CHANGE = 0x35, + E_BLOCK_ACTION = 0x36, + E_EXPLOSION = 0x3C, + E_SOUND_EFFECT = 0x3D, + E_NEW_INVALID_STATE = 0x46, + E_THUNDERBOLT = 0x47, + E_WINDOW_OPEN = 0x64, + E_WINDOW_CLOSE = 0x65, + E_WINDOW_CLICK = 0x66, + E_INVENTORY_SLOT = 0x67, + E_INVENTORY_WHOLE = 0x68, + E_INVENTORY_PROGRESS = 0x69, + E_CREATIVE_INVENTORY_ACTION = 0x6B, + E_UPDATE_SIGN = 0x82, + E_PLAYER_LIST_ITEM = 0xC9, + E_PLAYER_ABILITIES = 0xca, // since 1.2.4, protocol version 29 + E_PING = 0xfe, + E_DISCONNECT = 0xff, +}; +//tolua_end diff --git a/source/SquirrelBindings.cpp b/source/SquirrelBindings.cpp index 9c960d923..d8f513370 100644 --- a/source/SquirrelBindings.cpp +++ b/source/SquirrelBindings.cpp @@ -1,140 +1,140 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "SquirrelBindings.h"
-#if USE_SQUIRREL
-#pragma warning(disable:4100) // Getting A LOT of these warnings from SqPlus
-#pragma warning(disable:4127)
-
-#include <sqplus/sqplus.h>
-#include <sqplus/SquirrelObject.h>
-#include <../squirrel/sqstate.h>
-#include <../squirrel/sqvm.h>
-
-#include "cPlugin.h"
-#include "cPluginManager.h"
-#include "cRoot.h"
-#include "cPlayer.h"
-
-
-
-
-
-bool SquirrelBindings::IsBound = false;
-
-bool IsTopClosure( HSQUIRRELVM v )
-{
- return ( v->_stack[0]._type == OT_CLOSURE );
-}
-
-class __Squirrel_Base_Class // All inheritable classes should extend this class, as it allows virtual functions to call Squirrel
-{
-public:
- template<typename T>
- static int ConstructAndDestruct(HSQUIRRELVM v, T* a_Instance, SQRELEASEHOOK a_ReleaseHook )
- {
- LOG("ConstructAndDestruct()");
-
- StackHandler sa(v);
- HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE
- SquirrelObject instance(ho);
- SqPlus::PopulateAncestry(v, instance, a_Instance);
- a_Instance->vm = v;
- a_Instance->obj = instance;
-
- sq_setinstanceup(v, 1, a_Instance);
- sq_setreleasehook(v, 1, a_ReleaseHook);
- return TRUE;
- }
-
- HSQUIRRELVM vm;
- SquirrelObject obj;
-};
-
-class cPlugin__Squirrel : public cPlugin, public __Squirrel_Base_Class
-{
-public:
- cPlugin__Squirrel() { SetLanguage( cPlugin::E_SQUIRREL ); }
-
- bool Initialize() // This is a pure virtual function, so it NEEDS an implementation on the script side or it would be an illegal instance
- {
- SqPlus::SquirrelFunction<bool> InitFunc(obj, "Initialize");
- if( !InitFunc.func.IsNull() )
- return InitFunc();
- LOGWARN("cPlugin__Squirrel::Initialize() Pure virtual function called!"); // Spam some errorz to make it clear this function needs to be implemented
- return false;
- }
-
- static int constructor(HSQUIRRELVM v) { return ConstructAndDestruct( v, new cPlugin__Squirrel, SqPlus::ReleaseClassPtr<cPlugin__Squirrel>::release ); }
-
- virtual bool OnChat( const char* a_Chat, cPlayer* a_Player )
- {
- if( !IsTopClosure(vm) ) // Avoid recursion (TODO: FIXME: THIS NEEDS MORE RESEARCH!)
- { //Called from C++
- return SqPlus::SquirrelFunction<bool>(obj, "OnChat")(a_Chat, a_Player);
- }
- else // Called from Squirrel
- {
- return cPlugin::OnChat(a_Chat, a_Player);
- }
- }
-};
-
-static void printFunc(HSQUIRRELVM v,const SQChar * s,...)
-{
- (void)v;
- va_list vl;
- va_start(vl,s);
- cMCLogger::GetInstance()->Log( s, vl );
- va_end(vl);
-}
-
-DECLARE_INSTANCE_TYPE( cRoot );
-DECLARE_INSTANCE_TYPE( cPluginManager );
-DECLARE_ENUM_TYPE( cPluginManager::PluginHook );
-DECLARE_INSTANCE_TYPE( cPlugin );
-DECLARE_INSTANCE_TYPE( cPlugin__Squirrel );
-
-DECLARE_INSTANCE_TYPE( cEntity );
-DECLARE_INSTANCE_TYPE( cPawn );
-DECLARE_INSTANCE_TYPE( cPlayer );
-
-void SquirrelBindings::Bind( HSQUIRRELVM a_SquirrelVM )
-{
- IsBound = true;
-
- sq_setprintfunc(a_SquirrelVM, printFunc, printFunc);
-
-
- SqPlus::SQClassDefNoConstructor<cEntity>("cEntity");
- SqPlus::SQClassDefNoConstructor<cPawn, cEntity>("cPawn", "cEntity");
- SqPlus::SQClassDefNoConstructor<cPlayer, cPawn>("cPlayer", "cPawn"). // All NoConstructor because they need a custom one
- func(&cPlayer::GetName, "GetName");
-
- SqPlus::SQClassDefNoConstructor<cPlugin>("cPlugin").
- func(&cPlugin::SetName, "SetName").
- func(&cPlugin::GetName, "GetName").
- func(&cPlugin::GetVersion, "GetVersion").
- func(&cPlugin::OnChat, "OnChat");
-
-
- SqPlus::SQClassDef<cPlugin__Squirrel, cPlugin>("cPlugin__Squirrel", "cPlugin").
- staticFunc(&cPlugin__Squirrel::constructor, "constructor");
-
-
- SqPlus::SQClassDefNoConstructor<cRoot>("cRoot").
- staticFunc(&cRoot::Get, "Get").
- func(static_cast<cPluginManager* (__thiscall cRoot::*)(void)>(&cRoot::GetPluginManager), "GetPluginManager");
-
-
- SqPlus::SQClassDefNoConstructor<cPluginManager>("cPluginManager").
- overloadFunc<bool (cPluginManager::*)(cPlugin*)>(&cPluginManager::AddPlugin, "AddPlugin").
- func(&cPluginManager::GetPlugin, "GetPlugin").
- func(&cPluginManager::AddHook, "AddHook").
- enumInt( cPluginManager::E_PLUGIN_CHAT, "E_PLUGIN_CHAT");
-
-
-
-}
-
-#endif
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "SquirrelBindings.h" +#if USE_SQUIRREL +#pragma warning(disable:4100) // Getting A LOT of these warnings from SqPlus +#pragma warning(disable:4127) + +#include <sqplus/sqplus.h> +#include <sqplus/SquirrelObject.h> +#include <../squirrel/sqstate.h> +#include <../squirrel/sqvm.h> + +#include "cPlugin.h" +#include "cPluginManager.h" +#include "cRoot.h" +#include "cPlayer.h" + + + + + +bool SquirrelBindings::IsBound = false; + +bool IsTopClosure( HSQUIRRELVM v ) +{ + return ( v->_stack[0]._type == OT_CLOSURE ); +} + +class __Squirrel_Base_Class // All inheritable classes should extend this class, as it allows virtual functions to call Squirrel +{ +public: + template<typename T> + static int ConstructAndDestruct(HSQUIRRELVM v, T* a_Instance, SQRELEASEHOOK a_ReleaseHook ) + { + LOG("ConstructAndDestruct()"); + + StackHandler sa(v); + HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE + SquirrelObject instance(ho); + SqPlus::PopulateAncestry(v, instance, a_Instance); + a_Instance->vm = v; + a_Instance->obj = instance; + + sq_setinstanceup(v, 1, a_Instance); + sq_setreleasehook(v, 1, a_ReleaseHook); + return TRUE; + } + + HSQUIRRELVM vm; + SquirrelObject obj; +}; + +class cPlugin__Squirrel : public cPlugin, public __Squirrel_Base_Class +{ +public: + cPlugin__Squirrel() { SetLanguage( cPlugin::E_SQUIRREL ); } + + bool Initialize() // This is a pure virtual function, so it NEEDS an implementation on the script side or it would be an illegal instance + { + SqPlus::SquirrelFunction<bool> InitFunc(obj, "Initialize"); + if( !InitFunc.func.IsNull() ) + return InitFunc(); + LOGWARN("cPlugin__Squirrel::Initialize() Pure virtual function called!"); // Spam some errorz to make it clear this function needs to be implemented + return false; + } + + static int constructor(HSQUIRRELVM v) { return ConstructAndDestruct( v, new cPlugin__Squirrel, SqPlus::ReleaseClassPtr<cPlugin__Squirrel>::release ); } + + virtual bool OnChat( const char* a_Chat, cPlayer* a_Player ) + { + if( !IsTopClosure(vm) ) // Avoid recursion (TODO: FIXME: THIS NEEDS MORE RESEARCH!) + { //Called from C++ + return SqPlus::SquirrelFunction<bool>(obj, "OnChat")(a_Chat, a_Player); + } + else // Called from Squirrel + { + return cPlugin::OnChat(a_Chat, a_Player); + } + } +}; + +static void printFunc(HSQUIRRELVM v,const SQChar * s,...) +{ + (void)v; + va_list vl; + va_start(vl,s); + cMCLogger::GetInstance()->Log( s, vl ); + va_end(vl); +} + +DECLARE_INSTANCE_TYPE( cRoot ); +DECLARE_INSTANCE_TYPE( cPluginManager ); +DECLARE_ENUM_TYPE( cPluginManager::PluginHook ); +DECLARE_INSTANCE_TYPE( cPlugin ); +DECLARE_INSTANCE_TYPE( cPlugin__Squirrel ); + +DECLARE_INSTANCE_TYPE( cEntity ); +DECLARE_INSTANCE_TYPE( cPawn ); +DECLARE_INSTANCE_TYPE( cPlayer ); + +void SquirrelBindings::Bind( HSQUIRRELVM a_SquirrelVM ) +{ + IsBound = true; + + sq_setprintfunc(a_SquirrelVM, printFunc, printFunc); + + + SqPlus::SQClassDefNoConstructor<cEntity>("cEntity"); + SqPlus::SQClassDefNoConstructor<cPawn, cEntity>("cPawn", "cEntity"); + SqPlus::SQClassDefNoConstructor<cPlayer, cPawn>("cPlayer", "cPawn"). // All NoConstructor because they need a custom one + func(&cPlayer::GetName, "GetName"); + + SqPlus::SQClassDefNoConstructor<cPlugin>("cPlugin"). + func(&cPlugin::SetName, "SetName"). + func(&cPlugin::GetName, "GetName"). + func(&cPlugin::GetVersion, "GetVersion"). + func(&cPlugin::OnChat, "OnChat"); + + + SqPlus::SQClassDef<cPlugin__Squirrel, cPlugin>("cPlugin__Squirrel", "cPlugin"). + staticFunc(&cPlugin__Squirrel::constructor, "constructor"); + + + SqPlus::SQClassDefNoConstructor<cRoot>("cRoot"). + staticFunc(&cRoot::Get, "Get"). + func(static_cast<cPluginManager* (__thiscall cRoot::*)(void)>(&cRoot::GetPluginManager), "GetPluginManager"); + + + SqPlus::SQClassDefNoConstructor<cPluginManager>("cPluginManager"). + overloadFunc<bool (cPluginManager::*)(cPlugin*)>(&cPluginManager::AddPlugin, "AddPlugin"). + func(&cPluginManager::GetPlugin, "GetPlugin"). + func(&cPluginManager::AddHook, "AddHook"). + enumInt( cPluginManager::E_PLUGIN_CHAT, "E_PLUGIN_CHAT"); + + + +} + +#endif diff --git a/source/SquirrelBindings.h b/source/SquirrelBindings.h index 858428414..06a3df716 100644 --- a/source/SquirrelBindings.h +++ b/source/SquirrelBindings.h @@ -1,15 +1,15 @@ -#pragma once
-
-#define USE_SQUIRREL 0
-
-#if USE_SQUIRREL
-
-struct SQVM;
-class SquirrelBindings
-{
-public:
- static void Bind( SQVM* a_SquirrelVM );
- static bool IsBound;
-};
-
-#endif
+#pragma once + +#define USE_SQUIRREL 0 + +#if USE_SQUIRREL + +struct SQVM; +class SquirrelBindings +{ +public: + static void Bind( SQVM* a_SquirrelVM ); + static bool IsBound; +}; + +#endif diff --git a/source/StackWalker.cpp b/source/StackWalker.cpp index 37db4a563..bf18b9fc9 100644 --- a/source/StackWalker.cpp +++ b/source/StackWalker.cpp @@ -1,1345 +1,1345 @@ -/**********************************************************************
- *
- * StackWalker.cpp
- *
- *
- * History:
- * 2005-07-27 v1 - First public release on http://www.codeproject.com/
- * http://www.codeproject.com/threads/StackWalker.asp
- * 2005-07-28 v2 - Changed the params of the constructor and ShowCallstack
- * (to simplify the usage)
- * 2005-08-01 v3 - Changed to use 'CONTEXT_FULL' instead of CONTEXT_ALL
- * (should also be enough)
- * - Changed to compile correctly with the PSDK of VC7.0
- * (GetFileVersionInfoSizeA and GetFileVersionInfoA is wrongly defined:
- * it uses LPSTR instead of LPCSTR as first paremeter)
- * - Added declarations to support VC5/6 without using 'dbghelp.h'
- * - Added a 'pUserData' member to the ShowCallstack function and the
- * PReadProcessMemoryRoutine declaration (to pass some user-defined data,
- * which can be used in the readMemoryFunction-callback)
- * 2005-08-02 v4 - OnSymInit now also outputs the OS-Version by default
- * - Added example for doing an exception-callstack-walking in main.cpp
- * (thanks to owillebo: http://www.codeproject.com/script/profile/whos_who.asp?id=536268)
- * 2005-08-05 v5 - Removed most Lint (http://www.gimpel.com/) errors... thanks to Okko Willeboordse!
- * 2008-08-04 v6 - Fixed Bug: Missing LEAK-end-tag
- * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2502890#xx2502890xx
- * Fixed Bug: Compiled with "WIN32_LEAN_AND_MEAN"
- * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=1824718#xx1824718xx
- * Fixed Bug: Compiling with "/Wall"
- * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2638243#xx2638243xx
- * Fixed Bug: Now checking SymUseSymSrv
- * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1388979#xx1388979xx
- * Fixed Bug: Support for recursive function calls
- * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1434538#xx1434538xx
- * Fixed Bug: Missing FreeLibrary call in "GetModuleListTH32"
- * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1326923#xx1326923xx
- * Fixed Bug: SymDia is number 7, not 9!
- * 2008-09-11 v7 For some (undocumented) reason, dbhelp.h is needing a packing of 8!
- * Thanks to Teajay which reported the bug...
- * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2718933#xx2718933xx
- * 2008-11-27 v8 Debugging Tools for Windows are now stored in a different directory
- * Thanks to Luiz Salamon which reported this "bug"...
- * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2822736#xx2822736xx
- * 2009-04-10 v9 License slihtly corrected (<ORGANIZATION> replaced)
- * 2010-04-15 v10 Added support for VS2010 RTM
- * 2010-05-2ß v11 Now using secure MyStrcCpy. Thanks to luke.simon:
- * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=3477467#xx3477467xx
- *
- * LICENSE (http://www.opensource.org/licenses/bsd-license.php)
- *
- * Copyright (c) 2005-2010, Jochen Kalmbach
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * Neither the name of Jochen Kalmbach nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- **********************************************************************/
-#include <windows.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <stdlib.h>
-#pragma comment(lib, "version.lib") // for "VerQueryValue"
-#pragma warning(disable:4826)
-
-#include "StackWalker.h"
-
-
-// If VC7 and later, then use the shipped 'dbghelp.h'-file
-#pragma pack(push,8)
-#if _MSC_VER >= 1300
-#include <dbghelp.h>
-#else
-// inline the important dbghelp.h-declarations...
-typedef enum {
- SymNone = 0,
- SymCoff,
- SymCv,
- SymPdb,
- SymExport,
- SymDeferred,
- SymSym,
- SymDia,
- SymVirtual,
- NumSymTypes
-} SYM_TYPE;
-typedef struct _IMAGEHLP_LINE64 {
- DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64)
- PVOID Key; // internal
- DWORD LineNumber; // line number in file
- PCHAR FileName; // full filename
- DWORD64 Address; // first instruction of line
-} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
-typedef struct _IMAGEHLP_MODULE64 {
- DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
- DWORD64 BaseOfImage; // base load address of module
- DWORD ImageSize; // virtual size of the loaded module
- DWORD TimeDateStamp; // date/time stamp from pe header
- DWORD CheckSum; // checksum from the pe header
- DWORD NumSyms; // number of symbols in the symbol table
- SYM_TYPE SymType; // type of symbols loaded
- CHAR ModuleName[32]; // module name
- CHAR ImageName[256]; // image name
- CHAR LoadedImageName[256]; // symbol file name
-} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64;
-typedef struct _IMAGEHLP_SYMBOL64 {
- DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64)
- DWORD64 Address; // virtual address including dll base address
- DWORD Size; // estimated size of symbol, can be zero
- DWORD Flags; // info about the symbols, see the SYMF defines
- DWORD MaxNameLength; // maximum size of symbol name in 'Name'
- CHAR Name[1]; // symbol name (null terminated string)
-} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
-typedef enum {
- AddrMode1616,
- AddrMode1632,
- AddrModeReal,
- AddrModeFlat
-} ADDRESS_MODE;
-typedef struct _tagADDRESS64 {
- DWORD64 Offset;
- WORD Segment;
- ADDRESS_MODE Mode;
-} ADDRESS64, *LPADDRESS64;
-typedef struct _KDHELP64 {
- DWORD64 Thread;
- DWORD ThCallbackStack;
- DWORD ThCallbackBStore;
- DWORD NextCallback;
- DWORD FramePointer;
- DWORD64 KiCallUserMode;
- DWORD64 KeUserCallbackDispatcher;
- DWORD64 SystemRangeStart;
- DWORD64 Reserved[8];
-} KDHELP64, *PKDHELP64;
-typedef struct _tagSTACKFRAME64 {
- ADDRESS64 AddrPC; // program counter
- ADDRESS64 AddrReturn; // return address
- ADDRESS64 AddrFrame; // frame pointer
- ADDRESS64 AddrStack; // stack pointer
- ADDRESS64 AddrBStore; // backing store pointer
- PVOID FuncTableEntry; // pointer to pdata/fpo or NULL
- DWORD64 Params[4]; // possible arguments to the function
- BOOL Far; // WOW far call
- BOOL Virtual; // is this a virtual frame?
- DWORD64 Reserved[3];
- KDHELP64 KdHelp;
-} STACKFRAME64, *LPSTACKFRAME64;
-typedef
-BOOL
-(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(
- HANDLE hProcess,
- DWORD64 qwBaseAddress,
- PVOID lpBuffer,
- DWORD nSize,
- LPDWORD lpNumberOfBytesRead
- );
-typedef
-PVOID
-(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)(
- HANDLE hProcess,
- DWORD64 AddrBase
- );
-typedef
-DWORD64
-(__stdcall *PGET_MODULE_BASE_ROUTINE64)(
- HANDLE hProcess,
- DWORD64 Address
- );
-typedef
-DWORD64
-(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(
- HANDLE hProcess,
- HANDLE hThread,
- LPADDRESS64 lpaddr
- );
-#define SYMOPT_CASE_INSENSITIVE 0x00000001
-#define SYMOPT_UNDNAME 0x00000002
-#define SYMOPT_DEFERRED_LOADS 0x00000004
-#define SYMOPT_NO_CPP 0x00000008
-#define SYMOPT_LOAD_LINES 0x00000010
-#define SYMOPT_OMAP_FIND_NEAREST 0x00000020
-#define SYMOPT_LOAD_ANYTHING 0x00000040
-#define SYMOPT_IGNORE_CVREC 0x00000080
-#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100
-#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200
-#define SYMOPT_EXACT_SYMBOLS 0x00000400
-#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800
-#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000
-#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000
-#define SYMOPT_PUBLICS_ONLY 0x00004000
-#define SYMOPT_NO_PUBLICS 0x00008000
-#define SYMOPT_AUTO_PUBLICS 0x00010000
-#define SYMOPT_NO_IMAGE_SEARCH 0x00020000
-#define SYMOPT_SECURE 0x00040000
-#define SYMOPT_DEBUG 0x80000000
-#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration
-#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration;
-#endif // _MSC_VER < 1300
-#pragma pack(pop)
-
-// Some missing defines (for VC5/6):
-#ifndef INVALID_FILE_ATTRIBUTES
-#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
-#endif
-
-
-// secure-CRT_functions are only available starting with VC8
-#if _MSC_VER < 1400
-#define strcpy_s strcpy
-#define strncpy_s strncpy
-#define strcat_s(dst, len, src) strcat(dst, src)
-#define _snprintf_s _snprintf
-#define _tcscat_s _tcscat
-#endif
-
-static void MyStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc)
-{
- if (nMaxDestSize <= 0) return;
- if (strlen(szSrc) < nMaxDestSize)
- {
- strcpy_s(szDest, nMaxDestSize, szSrc);
- }
- else
- {
- strncpy_s(szDest, nMaxDestSize, szSrc, nMaxDestSize);
- szDest[nMaxDestSize-1] = 0;
- }
-} // MyStrCpy
-
-// Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL')
-#define USED_CONTEXT_FLAGS CONTEXT_FULL
-
-
-class StackWalkerInternal
-{
-public:
- StackWalkerInternal(StackWalker *parent, HANDLE hProcess)
- {
- m_parent = parent;
- m_hDbhHelp = NULL;
- pSC = NULL;
- m_hProcess = hProcess;
- m_szSymPath = NULL;
- pSFTA = NULL;
- pSGLFA = NULL;
- pSGMB = NULL;
- pSGMI = NULL;
- pSGO = NULL;
- pSGSFA = NULL;
- pSI = NULL;
- pSLM = NULL;
- pSSO = NULL;
- pSW = NULL;
- pUDSN = NULL;
- pSGSP = NULL;
- }
- ~StackWalkerInternal()
- {
- if (pSC != NULL)
- pSC(m_hProcess); // SymCleanup
- if (m_hDbhHelp != NULL)
- FreeLibrary(m_hDbhHelp);
- m_hDbhHelp = NULL;
- m_parent = NULL;
- if(m_szSymPath != NULL)
- free(m_szSymPath);
- m_szSymPath = NULL;
- }
- BOOL Init(LPCSTR szSymPath)
- {
- if (m_parent == NULL)
- return FALSE;
- // Dynamically load the Entry-Points for dbghelp.dll:
- // First try to load the newsest one from
- TCHAR szTemp[4096];
- // But before wqe do this, we first check if the ".local" file exists
- if (GetModuleFileName(NULL, szTemp, 4096) > 0)
- {
- _tcscat_s(szTemp, _T(".local"));
- if (GetFileAttributes(szTemp) == INVALID_FILE_ATTRIBUTES)
- {
- // ".local" file does not exist, so we can try to load the dbghelp.dll from the "Debugging Tools for Windows"
- // Ok, first try the new path according to the archtitecture:
-#ifdef _M_IX86
- if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) )
- {
- _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x86)\\dbghelp.dll"));
- // now check if the file exists:
- if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
- {
- m_hDbhHelp = LoadLibrary(szTemp);
- }
- }
-#elif _M_X64
- if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) )
- {
- _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x64)\\dbghelp.dll"));
- // now check if the file exists:
- if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
- {
- m_hDbhHelp = LoadLibrary(szTemp);
- }
- }
-#elif _M_IA64
- if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) )
- {
- _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (ia64)\\dbghelp.dll"));
- // now check if the file exists:
- if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
- {
- m_hDbhHelp = LoadLibrary(szTemp);
- }
- }
-#endif
- // If still not found, try the old directories...
- if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) )
- {
- _tcscat_s(szTemp, _T("\\Debugging Tools for Windows\\dbghelp.dll"));
- // now check if the file exists:
- if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
- {
- m_hDbhHelp = LoadLibrary(szTemp);
- }
- }
-#if defined _M_X64 || defined _M_IA64
- // Still not found? Then try to load the (old) 64-Bit version:
- if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) )
- {
- _tcscat_s(szTemp, _T("\\Debugging Tools for Windows 64-Bit\\dbghelp.dll"));
- if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
- {
- m_hDbhHelp = LoadLibrary(szTemp);
- }
- }
-#endif
- }
- }
- if (m_hDbhHelp == NULL) // if not already loaded, try to load a default-one
- m_hDbhHelp = LoadLibrary( _T("dbghelp.dll") );
- if (m_hDbhHelp == NULL)
- return FALSE;
- pSI = (tSI) GetProcAddress(m_hDbhHelp, "SymInitialize" );
- pSC = (tSC) GetProcAddress(m_hDbhHelp, "SymCleanup" );
-
- pSW = (tSW) GetProcAddress(m_hDbhHelp, "StackWalk64" );
- pSGO = (tSGO) GetProcAddress(m_hDbhHelp, "SymGetOptions" );
- pSSO = (tSSO) GetProcAddress(m_hDbhHelp, "SymSetOptions" );
-
- pSFTA = (tSFTA) GetProcAddress(m_hDbhHelp, "SymFunctionTableAccess64" );
- pSGLFA = (tSGLFA) GetProcAddress(m_hDbhHelp, "SymGetLineFromAddr64" );
- pSGMB = (tSGMB) GetProcAddress(m_hDbhHelp, "SymGetModuleBase64" );
- pSGMI = (tSGMI) GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64" );
- //pSGMI_V3 = (tSGMI_V3) GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64" );
- pSGSFA = (tSGSFA) GetProcAddress(m_hDbhHelp, "SymGetSymFromAddr64" );
- pUDSN = (tUDSN) GetProcAddress(m_hDbhHelp, "UnDecorateSymbolName" );
- pSLM = (tSLM) GetProcAddress(m_hDbhHelp, "SymLoadModule64" );
- pSGSP =(tSGSP) GetProcAddress(m_hDbhHelp, "SymGetSearchPath" );
-
- if ( pSC == NULL || pSFTA == NULL || pSGMB == NULL || pSGMI == NULL ||
- pSGO == NULL || pSGSFA == NULL || pSI == NULL || pSSO == NULL ||
- pSW == NULL || pUDSN == NULL || pSLM == NULL )
- {
- FreeLibrary(m_hDbhHelp);
- m_hDbhHelp = NULL;
- pSC = NULL;
- return FALSE;
- }
-
- // SymInitialize
- if (szSymPath != NULL)
- m_szSymPath = _strdup(szSymPath);
- if (this->pSI(m_hProcess, m_szSymPath, FALSE) == FALSE)
- this->m_parent->OnDbgHelpErr("SymInitialize", GetLastError(), 0);
-
- DWORD symOptions = this->pSGO(); // SymGetOptions
- symOptions |= SYMOPT_LOAD_LINES;
- symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS;
- //symOptions |= SYMOPT_NO_PROMPTS;
- // SymSetOptions
- symOptions = this->pSSO(symOptions);
-
- char buf[StackWalker::STACKWALK_MAX_NAMELEN] = {0};
- if (this->pSGSP != NULL)
- {
- if (this->pSGSP(m_hProcess, buf, StackWalker::STACKWALK_MAX_NAMELEN) == FALSE)
- this->m_parent->OnDbgHelpErr("SymGetSearchPath", GetLastError(), 0);
- }
- char szUserName[1024] = {0};
- DWORD dwSize = 1024;
- GetUserNameA(szUserName, &dwSize);
- this->m_parent->OnSymInit(buf, symOptions, szUserName);
-
- return TRUE;
- }
-
- StackWalker *m_parent;
-
- HMODULE m_hDbhHelp;
- HANDLE m_hProcess;
- LPSTR m_szSymPath;
-
-/*typedef struct IMAGEHLP_MODULE64_V3 {
- DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
- DWORD64 BaseOfImage; // base load address of module
- DWORD ImageSize; // virtual size of the loaded module
- DWORD TimeDateStamp; // date/time stamp from pe header
- DWORD CheckSum; // checksum from the pe header
- DWORD NumSyms; // number of symbols in the symbol table
- SYM_TYPE SymType; // type of symbols loaded
- CHAR ModuleName[32]; // module name
- CHAR ImageName[256]; // image name
- // new elements: 07-Jun-2002
- CHAR LoadedImageName[256]; // symbol file name
- CHAR LoadedPdbName[256]; // pdb file name
- DWORD CVSig; // Signature of the CV record in the debug directories
- CHAR CVData[MAX_PATH * 3]; // Contents of the CV record
- DWORD PdbSig; // Signature of PDB
- GUID PdbSig70; // Signature of PDB (VC 7 and up)
- DWORD PdbAge; // DBI age of pdb
- BOOL PdbUnmatched; // loaded an unmatched pdb
- BOOL DbgUnmatched; // loaded an unmatched dbg
- BOOL LineNumbers; // we have line number information
- BOOL GlobalSymbols; // we have internal symbol information
- BOOL TypeInfo; // we have type information
- // new elements: 17-Dec-2003
- BOOL SourceIndexed; // pdb supports source server
- BOOL Publics; // contains public symbols
-};
-*/
-
-#pragma pack(push,8)
-typedef struct IMAGEHLP_MODULE64_V2 {
- DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
- DWORD64 BaseOfImage; // base load address of module
- DWORD ImageSize; // virtual size of the loaded module
- DWORD TimeDateStamp; // date/time stamp from pe header
- DWORD CheckSum; // checksum from the pe header
- DWORD NumSyms; // number of symbols in the symbol table
- SYM_TYPE SymType; // type of symbols loaded
- CHAR ModuleName[32]; // module name
- CHAR ImageName[256]; // image name
- CHAR LoadedImageName[256]; // symbol file name
-};
-#pragma pack(pop)
-
-
- // SymCleanup()
- typedef BOOL (__stdcall *tSC)( IN HANDLE hProcess );
- tSC pSC;
-
- // SymFunctionTableAccess64()
- typedef PVOID (__stdcall *tSFTA)( HANDLE hProcess, DWORD64 AddrBase );
- tSFTA pSFTA;
-
- // SymGetLineFromAddr64()
- typedef BOOL (__stdcall *tSGLFA)( IN HANDLE hProcess, IN DWORD64 dwAddr,
- OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_LINE64 Line );
- tSGLFA pSGLFA;
-
- // SymGetModuleBase64()
- typedef DWORD64 (__stdcall *tSGMB)( IN HANDLE hProcess, IN DWORD64 dwAddr );
- tSGMB pSGMB;
-
- // SymGetModuleInfo64()
- typedef BOOL (__stdcall *tSGMI)( IN HANDLE hProcess, IN DWORD64 dwAddr, OUT IMAGEHLP_MODULE64_V2 *ModuleInfo );
- tSGMI pSGMI;
-
-// // SymGetModuleInfo64()
-// typedef BOOL (__stdcall *tSGMI_V3)( IN HANDLE hProcess, IN DWORD64 dwAddr, OUT IMAGEHLP_MODULE64_V3 *ModuleInfo );
-// tSGMI_V3 pSGMI_V3;
-
- // SymGetOptions()
- typedef DWORD (__stdcall *tSGO)( VOID );
- tSGO pSGO;
-
- // SymGetSymFromAddr64()
- typedef BOOL (__stdcall *tSGSFA)( IN HANDLE hProcess, IN DWORD64 dwAddr,
- OUT PDWORD64 pdwDisplacement, OUT PIMAGEHLP_SYMBOL64 Symbol );
- tSGSFA pSGSFA;
-
- // SymInitialize()
- typedef BOOL (__stdcall *tSI)( IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess );
- tSI pSI;
-
- // SymLoadModule64()
- typedef DWORD64 (__stdcall *tSLM)( IN HANDLE hProcess, IN HANDLE hFile,
- IN PSTR ImageName, IN PSTR ModuleName, IN DWORD64 BaseOfDll, IN DWORD SizeOfDll );
- tSLM pSLM;
-
- // SymSetOptions()
- typedef DWORD (__stdcall *tSSO)( IN DWORD SymOptions );
- tSSO pSSO;
-
- // StackWalk64()
- typedef BOOL (__stdcall *tSW)(
- DWORD MachineType,
- HANDLE hProcess,
- HANDLE hThread,
- LPSTACKFRAME64 StackFrame,
- PVOID ContextRecord,
- PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
- PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
- PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
- PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress );
- tSW pSW;
-
- // UnDecorateSymbolName()
- typedef DWORD (__stdcall WINAPI *tUDSN)( PCSTR DecoratedName, PSTR UnDecoratedName,
- DWORD UndecoratedLength, DWORD Flags );
- tUDSN pUDSN;
-
- typedef BOOL (__stdcall WINAPI *tSGSP)(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength);
- tSGSP pSGSP;
-
-
-private:
- // **************************************** ToolHelp32 ************************
- #define MAX_MODULE_NAME32 255
- #define TH32CS_SNAPMODULE 0x00000008
- #pragma pack( push, 8 )
- typedef struct tagMODULEENTRY32
- {
- DWORD dwSize;
- DWORD th32ModuleID; // This module
- DWORD th32ProcessID; // owning process
- DWORD GlblcntUsage; // Global usage count on the module
- DWORD ProccntUsage; // Module usage count in th32ProcessID's context
- BYTE * modBaseAddr; // Base address of module in th32ProcessID's context
- DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr
- HMODULE hModule; // The hModule of this module in th32ProcessID's context
- char szModule[MAX_MODULE_NAME32 + 1];
- char szExePath[MAX_PATH];
- } MODULEENTRY32;
- typedef MODULEENTRY32 * PMODULEENTRY32;
- typedef MODULEENTRY32 * LPMODULEENTRY32;
- #pragma pack( pop )
-
- BOOL GetModuleListTH32(HANDLE hProcess, DWORD pid)
- {
- // CreateToolhelp32Snapshot()
- typedef HANDLE (__stdcall *tCT32S)(DWORD dwFlags, DWORD th32ProcessID);
- // Module32First()
- typedef BOOL (__stdcall *tM32F)(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
- // Module32Next()
- typedef BOOL (__stdcall *tM32N)(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
-
- // try both dlls...
- const TCHAR *dllname[] = { _T("kernel32.dll"), _T("tlhelp32.dll") };
- HINSTANCE hToolhelp = NULL;
- tCT32S pCT32S = NULL;
- tM32F pM32F = NULL;
- tM32N pM32N = NULL;
-
- HANDLE hSnap;
- MODULEENTRY32 me;
- me.dwSize = sizeof(me);
- BOOL keepGoing;
- size_t i;
-
- for (i = 0; i<(sizeof(dllname) / sizeof(dllname[0])); i++ )
- {
- hToolhelp = LoadLibrary( dllname[i] );
- if (hToolhelp == NULL)
- continue;
- pCT32S = (tCT32S) GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot");
- pM32F = (tM32F) GetProcAddress(hToolhelp, "Module32First");
- pM32N = (tM32N) GetProcAddress(hToolhelp, "Module32Next");
- if ( (pCT32S != NULL) && (pM32F != NULL) && (pM32N != NULL) )
- break; // found the functions!
- FreeLibrary(hToolhelp);
- hToolhelp = NULL;
- }
-
- if (hToolhelp == NULL)
- return FALSE;
-
- hSnap = pCT32S( TH32CS_SNAPMODULE, pid );
- if (hSnap == (HANDLE) -1)
- {
- FreeLibrary(hToolhelp);
- return FALSE;
- }
-
- keepGoing = !!pM32F( hSnap, &me );
- int cnt = 0;
- while (keepGoing)
- {
- this->LoadModule(hProcess, me.szExePath, me.szModule, (DWORD64) me.modBaseAddr, me.modBaseSize);
- cnt++;
- keepGoing = !!pM32N( hSnap, &me );
- }
- CloseHandle(hSnap);
- FreeLibrary(hToolhelp);
- if (cnt <= 0)
- return FALSE;
- return TRUE;
- } // GetModuleListTH32
-
- // **************************************** PSAPI ************************
- typedef struct _MODULEINFO {
- LPVOID lpBaseOfDll;
- DWORD SizeOfImage;
- LPVOID EntryPoint;
- } MODULEINFO, *LPMODULEINFO;
-
- BOOL GetModuleListPSAPI(HANDLE hProcess)
- {
- // EnumProcessModules()
- typedef BOOL (__stdcall *tEPM)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded );
- // GetModuleFileNameEx()
- typedef DWORD (__stdcall *tGMFNE)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize );
- // GetModuleBaseName()
- typedef DWORD (__stdcall *tGMBN)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize );
- // GetModuleInformation()
- typedef BOOL (__stdcall *tGMI)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO pmi, DWORD nSize );
-
- HINSTANCE hPsapi;
- tEPM pEPM;
- tGMFNE pGMFNE;
- tGMBN pGMBN;
- tGMI pGMI;
-
- DWORD i;
- //ModuleEntry e;
- DWORD cbNeeded;
- MODULEINFO mi;
- HMODULE *hMods = 0;
- char *tt = NULL;
- char *tt2 = NULL;
- const SIZE_T TTBUFLEN = 8096;
- int cnt = 0;
-
- hPsapi = LoadLibrary( _T("psapi.dll") );
- if (hPsapi == NULL)
- return FALSE;
-
- pEPM = (tEPM) GetProcAddress( hPsapi, "EnumProcessModules" );
- pGMFNE = (tGMFNE) GetProcAddress( hPsapi, "GetModuleFileNameExA" );
- pGMBN = (tGMFNE) GetProcAddress( hPsapi, "GetModuleBaseNameA" );
- pGMI = (tGMI) GetProcAddress( hPsapi, "GetModuleInformation" );
- if ( (pEPM == NULL) || (pGMFNE == NULL) || (pGMBN == NULL) || (pGMI == NULL) )
- {
- // we couldn´t find all functions
- FreeLibrary(hPsapi);
- return FALSE;
- }
-
- hMods = (HMODULE*) malloc(sizeof(HMODULE) * (TTBUFLEN / sizeof HMODULE));
- tt = (char*) malloc(sizeof(char) * TTBUFLEN);
- tt2 = (char*) malloc(sizeof(char) * TTBUFLEN);
- if ( (hMods == NULL) || (tt == NULL) || (tt2 == NULL) )
- goto cleanup;
-
- if ( ! pEPM( hProcess, hMods, TTBUFLEN, &cbNeeded ) )
- {
- //_ftprintf(fLogFile, _T("%lu: EPM failed, GetLastError = %lu\n"), g_dwShowCount, gle );
- goto cleanup;
- }
-
- if ( cbNeeded > TTBUFLEN )
- {
- //_ftprintf(fLogFile, _T("%lu: More than %lu module handles. Huh?\n"), g_dwShowCount, lenof( hMods ) );
- goto cleanup;
- }
-
- for ( i = 0; i < cbNeeded / sizeof hMods[0]; i++ )
- {
- // base address, size
- pGMI(hProcess, hMods[i], &mi, sizeof mi );
- // image file name
- tt[0] = 0;
- pGMFNE(hProcess, hMods[i], tt, TTBUFLEN );
- // module name
- tt2[0] = 0;
- pGMBN(hProcess, hMods[i], tt2, TTBUFLEN );
-
- DWORD dwRes = this->LoadModule(hProcess, tt, tt2, (DWORD64) mi.lpBaseOfDll, mi.SizeOfImage);
- if (dwRes != ERROR_SUCCESS)
- this->m_parent->OnDbgHelpErr("LoadModule", dwRes, 0);
- cnt++;
- }
-
- cleanup:
- if (hPsapi != NULL) FreeLibrary(hPsapi);
- if (tt2 != NULL) free(tt2);
- if (tt != NULL) free(tt);
- if (hMods != NULL) free(hMods);
-
- return cnt != 0;
- } // GetModuleListPSAPI
-
- DWORD LoadModule(HANDLE hProcess, LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size)
- {
- CHAR *szImg = _strdup(img);
- CHAR *szMod = _strdup(mod);
- DWORD result = ERROR_SUCCESS;
- if ( (szImg == NULL) || (szMod == NULL) )
- result = ERROR_NOT_ENOUGH_MEMORY;
- else
- {
- if (pSLM(hProcess, 0, szImg, szMod, baseAddr, size) == 0)
- result = GetLastError();
- }
- ULONGLONG fileVersion = 0;
- if ( (m_parent != NULL) && (szImg != NULL) )
- {
- // try to retrive the file-version:
- if ( (this->m_parent->m_options & StackWalker::RetrieveFileVersion) != 0)
- {
- VS_FIXEDFILEINFO *fInfo = NULL;
- DWORD dwHandle;
- DWORD dwSize = GetFileVersionInfoSizeA(szImg, &dwHandle);
- if (dwSize > 0)
- {
- LPVOID vData = malloc(dwSize);
- if (vData != NULL)
- {
- if (GetFileVersionInfoA(szImg, dwHandle, dwSize, vData) != 0)
- {
- UINT len;
- TCHAR szSubBlock[] = _T("\\");
- if (VerQueryValue(vData, szSubBlock, (LPVOID*) &fInfo, &len) == 0)
- fInfo = NULL;
- else
- {
- fileVersion = ((ULONGLONG)fInfo->dwFileVersionLS) + ((ULONGLONG)fInfo->dwFileVersionMS << 32);
- }
- }
- free(vData);
- }
- }
- }
-
- // Retrive some additional-infos about the module
- IMAGEHLP_MODULE64_V2 Module;
- const char *szSymType = "-unknown-";
- if (this->GetModuleInfo(hProcess, baseAddr, &Module) != FALSE)
- {
- switch(Module.SymType)
- {
- case SymNone:
- szSymType = "-nosymbols-";
- break;
- case SymCoff: // 1
- szSymType = "COFF";
- break;
- case SymCv: // 2
- szSymType = "CV";
- break;
- case SymPdb: // 3
- szSymType = "PDB";
- break;
- case SymExport: // 4
- szSymType = "-exported-";
- break;
- case SymDeferred: // 5
- szSymType = "-deferred-";
- break;
- case SymSym: // 6
- szSymType = "SYM";
- break;
- case 7: // SymDia:
- szSymType = "DIA";
- break;
- case 8: //SymVirtual:
- szSymType = "Virtual";
- break;
- }
- }
- this->m_parent->OnLoadModule(img, mod, baseAddr, size, result, szSymType, Module.LoadedImageName, fileVersion);
- }
- if (szImg != NULL) free(szImg);
- if (szMod != NULL) free(szMod);
- return result;
- }
-public:
- BOOL LoadModules(HANDLE hProcess, DWORD dwProcessId)
- {
- // first try toolhelp32
- if (GetModuleListTH32(hProcess, dwProcessId))
- return true;
- // then try psapi
- return GetModuleListPSAPI(hProcess);
- }
-
-
- BOOL GetModuleInfo(HANDLE hProcess, DWORD64 baseAddr, IMAGEHLP_MODULE64_V2 *pModuleInfo)
- {
- if(this->pSGMI == NULL)
- {
- SetLastError(ERROR_DLL_INIT_FAILED);
- return FALSE;
- }
- // First try to use the larger ModuleInfo-Structure
-// memset(pModuleInfo, 0, sizeof(IMAGEHLP_MODULE64_V3));
-// pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V3);
-// if (this->pSGMI_V3 != NULL)
-// {
-// if (this->pSGMI_V3(hProcess, baseAddr, pModuleInfo) != FALSE)
-// return TRUE;
-// // check if the parameter was wrong (size is bad...)
-// if (GetLastError() != ERROR_INVALID_PARAMETER)
-// return FALSE;
-// }
- // could not retrive the bigger structure, try with the smaller one (as defined in VC7.1)...
- pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2);
- void *pData = malloc(4096); // reserve enough memory, so the bug in v6.3.5.1 does not lead to memory-overwrites...
- if (pData == NULL)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- memcpy(pData, pModuleInfo, sizeof(IMAGEHLP_MODULE64_V2));
- if (this->pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V2*) pData) != FALSE)
- {
- // only copy as much memory as is reserved...
- memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V2));
- pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2);
- free(pData);
- return TRUE;
- }
- free(pData);
- SetLastError(ERROR_DLL_INIT_FAILED);
- return FALSE;
- }
-};
-
-// #############################################################
-StackWalker::StackWalker(DWORD dwProcessId, HANDLE hProcess)
-{
- this->m_options = OptionsAll;
- this->m_modulesLoaded = FALSE;
- this->m_hProcess = hProcess;
- this->m_sw = new StackWalkerInternal(this, this->m_hProcess);
- this->m_dwProcessId = dwProcessId;
- this->m_szSymPath = NULL;
- this->m_MaxRecursionCount = 1000;
-}
-StackWalker::StackWalker(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess)
-{
- this->m_options = options;
- this->m_modulesLoaded = FALSE;
- this->m_hProcess = hProcess;
- this->m_sw = new StackWalkerInternal(this, this->m_hProcess);
- this->m_dwProcessId = dwProcessId;
- if (szSymPath != NULL)
- {
- this->m_szSymPath = _strdup(szSymPath);
- this->m_options |= SymBuildPath;
- }
- else
- this->m_szSymPath = NULL;
- this->m_MaxRecursionCount = 1000;
-}
-
-StackWalker::~StackWalker()
-{
- if (m_szSymPath != NULL)
- free(m_szSymPath);
- m_szSymPath = NULL;
- if (this->m_sw != NULL)
- delete this->m_sw;
- this->m_sw = NULL;
-}
-
-BOOL StackWalker::LoadModules()
-{
- if (this->m_sw == NULL)
- {
- SetLastError(ERROR_DLL_INIT_FAILED);
- return FALSE;
- }
- if (m_modulesLoaded != FALSE)
- return TRUE;
-
- // Build the sym-path:
- char *szSymPath = NULL;
- if ( (this->m_options & SymBuildPath) != 0)
- {
- const size_t nSymPathLen = 4096;
- szSymPath = (char*) malloc(nSymPathLen);
- if (szSymPath == NULL)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- szSymPath[0] = 0;
- // Now first add the (optional) provided sympath:
- if (this->m_szSymPath != NULL)
- {
- strcat_s(szSymPath, nSymPathLen, this->m_szSymPath);
- strcat_s(szSymPath, nSymPathLen, ";");
- }
-
- strcat_s(szSymPath, nSymPathLen, ".;");
-
- const size_t nTempLen = 1024;
- char szTemp[nTempLen];
- // Now add the current directory:
- if (GetCurrentDirectoryA(nTempLen, szTemp) > 0)
- {
- szTemp[nTempLen-1] = 0;
- strcat_s(szSymPath, nSymPathLen, szTemp);
- strcat_s(szSymPath, nSymPathLen, ";");
- }
-
- // Now add the path for the main-module:
- if (GetModuleFileNameA(NULL, szTemp, nTempLen) > 0)
- {
- szTemp[nTempLen-1] = 0;
- for (char *p = (szTemp+strlen(szTemp)-1); p >= szTemp; --p)
- {
- // locate the rightmost path separator
- if ( (*p == '\\') || (*p == '/') || (*p == ':') )
- {
- *p = 0;
- break;
- }
- } // for (search for path separator...)
- if (strlen(szTemp) > 0)
- {
- strcat_s(szSymPath, nSymPathLen, szTemp);
- strcat_s(szSymPath, nSymPathLen, ";");
- }
- }
- if (GetEnvironmentVariableA("_NT_SYMBOL_PATH", szTemp, nTempLen) > 0)
- {
- szTemp[nTempLen-1] = 0;
- strcat_s(szSymPath, nSymPathLen, szTemp);
- strcat_s(szSymPath, nSymPathLen, ";");
- }
- if (GetEnvironmentVariableA("_NT_ALTERNATE_SYMBOL_PATH", szTemp, nTempLen) > 0)
- {
- szTemp[nTempLen-1] = 0;
- strcat_s(szSymPath, nSymPathLen, szTemp);
- strcat_s(szSymPath, nSymPathLen, ";");
- }
- if (GetEnvironmentVariableA("SYSTEMROOT", szTemp, nTempLen) > 0)
- {
- szTemp[nTempLen-1] = 0;
- strcat_s(szSymPath, nSymPathLen, szTemp);
- strcat_s(szSymPath, nSymPathLen, ";");
- // also add the "system32"-directory:
- strcat_s(szTemp, nTempLen, "\\system32");
- strcat_s(szSymPath, nSymPathLen, szTemp);
- strcat_s(szSymPath, nSymPathLen, ";");
- }
-
- if ( (this->m_options & SymUseSymSrv) != 0)
- {
- if (GetEnvironmentVariableA("SYSTEMDRIVE", szTemp, nTempLen) > 0)
- {
- szTemp[nTempLen-1] = 0;
- strcat_s(szSymPath, nSymPathLen, "SRV*");
- strcat_s(szSymPath, nSymPathLen, szTemp);
- strcat_s(szSymPath, nSymPathLen, "\\websymbols");
- strcat_s(szSymPath, nSymPathLen, "*http://msdl.microsoft.com/download/symbols;");
- }
- else
- strcat_s(szSymPath, nSymPathLen, "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;");
- }
- } // if SymBuildPath
-
- // First Init the whole stuff...
- BOOL bRet = this->m_sw->Init(szSymPath);
- if (szSymPath != NULL) free(szSymPath); szSymPath = NULL;
- if (bRet == FALSE)
- {
- this->OnDbgHelpErr("Error while initializing dbghelp.dll", 0, 0);
- SetLastError(ERROR_DLL_INIT_FAILED);
- return FALSE;
- }
-
- bRet = this->m_sw->LoadModules(this->m_hProcess, this->m_dwProcessId);
- if (bRet != FALSE)
- m_modulesLoaded = TRUE;
- return bRet;
-}
-
-
-// The following is used to pass the "userData"-Pointer to the user-provided readMemoryFunction
-// This has to be done due to a problem with the "hProcess"-parameter in x64...
-// Because this class is in no case multi-threading-enabled (because of the limitations
-// of dbghelp.dll) it is "safe" to use a static-variable
-static StackWalker::PReadProcessMemoryRoutine s_readMemoryFunction = NULL;
-static LPVOID s_readMemoryFunction_UserData = NULL;
-
-BOOL StackWalker::ShowCallstack(HANDLE hThread, const CONTEXT *context, PReadProcessMemoryRoutine readMemoryFunction, LPVOID pUserData)
-{
- CONTEXT c;
- CallstackEntry csEntry;
- IMAGEHLP_SYMBOL64 *pSym = NULL;
- StackWalkerInternal::IMAGEHLP_MODULE64_V2 Module;
- IMAGEHLP_LINE64 Line;
- int frameNum;
- bool bLastEntryCalled = true;
- int curRecursionCount = 0;
-
- if (m_modulesLoaded == FALSE)
- this->LoadModules(); // ignore the result...
-
- if (this->m_sw->m_hDbhHelp == NULL)
- {
- SetLastError(ERROR_DLL_INIT_FAILED);
- return FALSE;
- }
-
- s_readMemoryFunction = readMemoryFunction;
- s_readMemoryFunction_UserData = pUserData;
-
- if (context == NULL)
- {
- // If no context is provided, capture the context
- if (hThread == GetCurrentThread())
- {
- GET_CURRENT_CONTEXT(c, USED_CONTEXT_FLAGS);
- }
- else
- {
- SuspendThread(hThread);
- memset(&c, 0, sizeof(CONTEXT));
- c.ContextFlags = USED_CONTEXT_FLAGS;
- if (GetThreadContext(hThread, &c) == FALSE)
- {
- ResumeThread(hThread);
- return FALSE;
- }
- }
- }
- else
- c = *context;
-
- // init STACKFRAME for first call
- STACKFRAME64 s; // in/out stackframe
- memset(&s, 0, sizeof(s));
- DWORD imageType;
-#ifdef _M_IX86
- // normally, call ImageNtHeader() and use machine info from PE header
- imageType = IMAGE_FILE_MACHINE_I386;
- s.AddrPC.Offset = c.Eip;
- s.AddrPC.Mode = AddrModeFlat;
- s.AddrFrame.Offset = c.Ebp;
- s.AddrFrame.Mode = AddrModeFlat;
- s.AddrStack.Offset = c.Esp;
- s.AddrStack.Mode = AddrModeFlat;
-#elif _M_X64
- imageType = IMAGE_FILE_MACHINE_AMD64;
- s.AddrPC.Offset = c.Rip;
- s.AddrPC.Mode = AddrModeFlat;
- s.AddrFrame.Offset = c.Rsp;
- s.AddrFrame.Mode = AddrModeFlat;
- s.AddrStack.Offset = c.Rsp;
- s.AddrStack.Mode = AddrModeFlat;
-#elif _M_IA64
- imageType = IMAGE_FILE_MACHINE_IA64;
- s.AddrPC.Offset = c.StIIP;
- s.AddrPC.Mode = AddrModeFlat;
- s.AddrFrame.Offset = c.IntSp;
- s.AddrFrame.Mode = AddrModeFlat;
- s.AddrBStore.Offset = c.RsBSP;
- s.AddrBStore.Mode = AddrModeFlat;
- s.AddrStack.Offset = c.IntSp;
- s.AddrStack.Mode = AddrModeFlat;
-#else
-#error "Platform not supported!"
-#endif
-
- pSym = (IMAGEHLP_SYMBOL64 *) malloc(sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
- if (!pSym) goto cleanup; // not enough memory...
- memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
- pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
- pSym->MaxNameLength = STACKWALK_MAX_NAMELEN;
-
- memset(&Line, 0, sizeof(Line));
- Line.SizeOfStruct = sizeof(Line);
-
- memset(&Module, 0, sizeof(Module));
- Module.SizeOfStruct = sizeof(Module);
-
- for (frameNum = 0; ; ++frameNum )
- {
- // get next stack frame (StackWalk64(), SymFunctionTableAccess64(), SymGetModuleBase64())
- // if this returns ERROR_INVALID_ADDRESS (487) or ERROR_NOACCESS (998), you can
- // assume that either you are done, or that the stack is so hosed that the next
- // deeper frame could not be found.
- // CONTEXT need not to be suplied if imageTyp is IMAGE_FILE_MACHINE_I386!
- if ( ! this->m_sw->pSW(imageType, this->m_hProcess, hThread, &s, &c, myReadProcMem, this->m_sw->pSFTA, this->m_sw->pSGMB, NULL) )
- {
- // INFO: "StackWalk64" does not set "GetLastError"...
- this->OnDbgHelpErr("StackWalk64", 0, s.AddrPC.Offset);
- break;
- }
-
- csEntry.offset = s.AddrPC.Offset;
- csEntry.name[0] = 0;
- csEntry.undName[0] = 0;
- csEntry.undFullName[0] = 0;
- csEntry.offsetFromSmybol = 0;
- csEntry.offsetFromLine = 0;
- csEntry.lineFileName[0] = 0;
- csEntry.lineNumber = 0;
- csEntry.loadedImageName[0] = 0;
- csEntry.moduleName[0] = 0;
- if (s.AddrPC.Offset == s.AddrReturn.Offset)
- {
- if ( (this->m_MaxRecursionCount > 0) && (curRecursionCount > m_MaxRecursionCount) )
- {
- this->OnDbgHelpErr("StackWalk64-Endless-Callstack!", 0, s.AddrPC.Offset);
- break;
- }
- curRecursionCount++;
- }
- else
- curRecursionCount = 0;
- if (s.AddrPC.Offset != 0)
- {
- // we seem to have a valid PC
- // show procedure info (SymGetSymFromAddr64())
- if (this->m_sw->pSGSFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromSmybol), pSym) != FALSE)
- {
- MyStrCpy(csEntry.name, STACKWALK_MAX_NAMELEN, pSym->Name);
- // UnDecorateSymbolName()
- this->m_sw->pUDSN( pSym->Name, csEntry.undName, STACKWALK_MAX_NAMELEN, UNDNAME_NAME_ONLY );
- this->m_sw->pUDSN( pSym->Name, csEntry.undFullName, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE );
- }
- else
- {
- this->OnDbgHelpErr("SymGetSymFromAddr64", GetLastError(), s.AddrPC.Offset);
- }
-
- // show line number info, NT5.0-method (SymGetLineFromAddr64())
- if (this->m_sw->pSGLFA != NULL )
- { // yes, we have SymGetLineFromAddr64()
- if (this->m_sw->pSGLFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromLine), &Line) != FALSE)
- {
- csEntry.lineNumber = Line.LineNumber;
- MyStrCpy(csEntry.lineFileName, STACKWALK_MAX_NAMELEN, Line.FileName);
- }
- else
- {
- this->OnDbgHelpErr("SymGetLineFromAddr64", GetLastError(), s.AddrPC.Offset);
- }
- } // yes, we have SymGetLineFromAddr64()
-
- // show module info (SymGetModuleInfo64())
- if (this->m_sw->GetModuleInfo(this->m_hProcess, s.AddrPC.Offset, &Module ) != FALSE)
- { // got module info OK
- switch ( Module.SymType )
- {
- case SymNone:
- csEntry.symTypeString = "-nosymbols-";
- break;
- case SymCoff:
- csEntry.symTypeString = "COFF";
- break;
- case SymCv:
- csEntry.symTypeString = "CV";
- break;
- case SymPdb:
- csEntry.symTypeString = "PDB";
- break;
- case SymExport:
- csEntry.symTypeString = "-exported-";
- break;
- case SymDeferred:
- csEntry.symTypeString = "-deferred-";
- break;
- case SymSym:
- csEntry.symTypeString = "SYM";
- break;
-#if API_VERSION_NUMBER >= 9
- case SymDia:
- csEntry.symTypeString = "DIA";
- break;
-#endif
- case 8: //SymVirtual:
- csEntry.symTypeString = "Virtual";
- break;
- default:
- //_snprintf( ty, sizeof ty, "symtype=%ld", (long) Module.SymType );
- csEntry.symTypeString = NULL;
- break;
- }
-
- // TODO: Mache dies sicher...!
- MyStrCpy(csEntry.moduleName, STACKWALK_MAX_NAMELEN, Module.ModuleName);
- csEntry.baseOfImage = Module.BaseOfImage;
- MyStrCpy(csEntry.loadedImageName, STACKWALK_MAX_NAMELEN, Module.LoadedImageName);
- } // got module info OK
- else
- {
- this->OnDbgHelpErr("SymGetModuleInfo64", GetLastError(), s.AddrPC.Offset);
- }
- } // we seem to have a valid PC
-
- CallstackEntryType et = nextEntry;
- if (frameNum == 0)
- et = firstEntry;
- bLastEntryCalled = false;
- this->OnCallstackEntry(et, csEntry);
-
- if (s.AddrReturn.Offset == 0)
- {
- bLastEntryCalled = true;
- this->OnCallstackEntry(lastEntry, csEntry);
- SetLastError(ERROR_SUCCESS);
- break;
- }
- } // for ( frameNum )
-
- cleanup:
- if (pSym) free( pSym );
-
- if (bLastEntryCalled == false)
- this->OnCallstackEntry(lastEntry, csEntry);
-
- if (context == NULL)
- ResumeThread(hThread);
-
- return TRUE;
-}
-
-BOOL __stdcall StackWalker::myReadProcMem(
- HANDLE hProcess,
- DWORD64 qwBaseAddress,
- PVOID lpBuffer,
- DWORD nSize,
- LPDWORD lpNumberOfBytesRead
- )
-{
- if (s_readMemoryFunction == NULL)
- {
- SIZE_T st;
- BOOL bRet = ReadProcessMemory(hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, &st);
- *lpNumberOfBytesRead = (DWORD) st;
- //printf("ReadMemory: hProcess: %p, baseAddr: %p, buffer: %p, size: %d, read: %d, result: %d\n", hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, (DWORD) st, (DWORD) bRet);
- return bRet;
- }
- else
- {
- return s_readMemoryFunction(hProcess, qwBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead, s_readMemoryFunction_UserData);
- }
-}
-
-void StackWalker::OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion)
-{
- CHAR buffer[STACKWALK_MAX_NAMELEN];
- if (fileVersion == 0)
- _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s'\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName);
- else
- {
- DWORD v4 = (DWORD) fileVersion & 0xFFFF;
- DWORD v3 = (DWORD) (fileVersion>>16) & 0xFFFF;
- DWORD v2 = (DWORD) (fileVersion>>32) & 0xFFFF;
- DWORD v1 = (DWORD) (fileVersion>>48) & 0xFFFF;
- _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s', fileVersion: %d.%d.%d.%d\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName, v1, v2, v3, v4);
- }
- OnOutput(buffer);
-}
-
-void StackWalker::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry)
-{
- CHAR buffer[STACKWALK_MAX_NAMELEN];
- if ( (eType != lastEntry) && (entry.offset != 0) )
- {
- if (entry.name[0] == 0)
- MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, "(function-name not available)");
- if (entry.undName[0] != 0)
- MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undName);
- if (entry.undFullName[0] != 0)
- MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undFullName);
- if (entry.lineFileName[0] == 0)
- {
- MyStrCpy(entry.lineFileName, STACKWALK_MAX_NAMELEN, "(filename not available)");
- if (entry.moduleName[0] == 0)
- MyStrCpy(entry.moduleName, STACKWALK_MAX_NAMELEN, "(module-name not available)");
- _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%p (%s): %s: %s\n", (LPVOID) entry.offset, entry.moduleName, entry.lineFileName, entry.name);
- }
- else
- _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s (%d): %s\n", entry.lineFileName, entry.lineNumber, entry.name);
- buffer[STACKWALK_MAX_NAMELEN-1] = 0;
- OnOutput(buffer);
- }
-}
-
-void StackWalker::OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr)
-{
- CHAR buffer[STACKWALK_MAX_NAMELEN];
- _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "ERROR: %s, GetLastError: %d (Address: %p)\n", szFuncName, gle, (LPVOID) addr);
- OnOutput(buffer);
-}
-
-void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName)
-{
- CHAR buffer[STACKWALK_MAX_NAMELEN];
- _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n", szSearchPath, symOptions, szUserName);
- OnOutput(buffer);
- // Also display the OS-version
-#if _MSC_VER <= 1200
- OSVERSIONINFOA ver;
- ZeroMemory(&ver, sizeof(OSVERSIONINFOA));
- ver.dwOSVersionInfoSize = sizeof(ver);
- if (GetVersionExA(&ver) != FALSE)
- {
- _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s)\n",
- ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber,
- ver.szCSDVersion);
- OnOutput(buffer);
- }
-#else
- OSVERSIONINFOEXA ver;
- ZeroMemory(&ver, sizeof(OSVERSIONINFOEXA));
- ver.dwOSVersionInfoSize = sizeof(ver);
- if (GetVersionExA( (OSVERSIONINFOA*) &ver) != FALSE)
- {
- _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n",
- ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber,
- ver.szCSDVersion, ver.wSuiteMask, ver.wProductType);
- OnOutput(buffer);
- }
-#endif
-}
-
-void StackWalker::OnOutput(LPCSTR buffer)
-{
- OutputDebugStringA(buffer);
-}
+/********************************************************************** + * + * StackWalker.cpp + * + * + * History: + * 2005-07-27 v1 - First public release on http://www.codeproject.com/ + * http://www.codeproject.com/threads/StackWalker.asp + * 2005-07-28 v2 - Changed the params of the constructor and ShowCallstack + * (to simplify the usage) + * 2005-08-01 v3 - Changed to use 'CONTEXT_FULL' instead of CONTEXT_ALL + * (should also be enough) + * - Changed to compile correctly with the PSDK of VC7.0 + * (GetFileVersionInfoSizeA and GetFileVersionInfoA is wrongly defined: + * it uses LPSTR instead of LPCSTR as first paremeter) + * - Added declarations to support VC5/6 without using 'dbghelp.h' + * - Added a 'pUserData' member to the ShowCallstack function and the + * PReadProcessMemoryRoutine declaration (to pass some user-defined data, + * which can be used in the readMemoryFunction-callback) + * 2005-08-02 v4 - OnSymInit now also outputs the OS-Version by default + * - Added example for doing an exception-callstack-walking in main.cpp + * (thanks to owillebo: http://www.codeproject.com/script/profile/whos_who.asp?id=536268) + * 2005-08-05 v5 - Removed most Lint (http://www.gimpel.com/) errors... thanks to Okko Willeboordse! + * 2008-08-04 v6 - Fixed Bug: Missing LEAK-end-tag + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2502890#xx2502890xx + * Fixed Bug: Compiled with "WIN32_LEAN_AND_MEAN" + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=1824718#xx1824718xx + * Fixed Bug: Compiling with "/Wall" + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2638243#xx2638243xx + * Fixed Bug: Now checking SymUseSymSrv + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1388979#xx1388979xx + * Fixed Bug: Support for recursive function calls + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1434538#xx1434538xx + * Fixed Bug: Missing FreeLibrary call in "GetModuleListTH32" + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1326923#xx1326923xx + * Fixed Bug: SymDia is number 7, not 9! + * 2008-09-11 v7 For some (undocumented) reason, dbhelp.h is needing a packing of 8! + * Thanks to Teajay which reported the bug... + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2718933#xx2718933xx + * 2008-11-27 v8 Debugging Tools for Windows are now stored in a different directory + * Thanks to Luiz Salamon which reported this "bug"... + * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2822736#xx2822736xx + * 2009-04-10 v9 License slihtly corrected (<ORGANIZATION> replaced) + * 2010-04-15 v10 Added support for VS2010 RTM + * 2010-05-2ß v11 Now using secure MyStrcCpy. Thanks to luke.simon: + * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=3477467#xx3477467xx + * + * LICENSE (http://www.opensource.org/licenses/bsd-license.php) + * + * Copyright (c) 2005-2010, Jochen Kalmbach + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of Jochen Kalmbach nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ +#include <windows.h> +#include <tchar.h> +#include <stdio.h> +#include <stdlib.h> +#pragma comment(lib, "version.lib") // for "VerQueryValue" +#pragma warning(disable:4826) + +#include "StackWalker.h" + + +// If VC7 and later, then use the shipped 'dbghelp.h'-file +#pragma pack(push,8) +#if _MSC_VER >= 1300 +#include <dbghelp.h> +#else +// inline the important dbghelp.h-declarations... +typedef enum { + SymNone = 0, + SymCoff, + SymCv, + SymPdb, + SymExport, + SymDeferred, + SymSym, + SymDia, + SymVirtual, + NumSymTypes +} SYM_TYPE; +typedef struct _IMAGEHLP_LINE64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PCHAR FileName; // full filename + DWORD64 Address; // first instruction of line +} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64; +typedef struct _IMAGEHLP_MODULE64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name +} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64; +typedef struct _IMAGEHLP_SYMBOL64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64) + DWORD64 Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + CHAR Name[1]; // symbol name (null terminated string) +} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; +typedef enum { + AddrMode1616, + AddrMode1632, + AddrModeReal, + AddrModeFlat +} ADDRESS_MODE; +typedef struct _tagADDRESS64 { + DWORD64 Offset; + WORD Segment; + ADDRESS_MODE Mode; +} ADDRESS64, *LPADDRESS64; +typedef struct _KDHELP64 { + DWORD64 Thread; + DWORD ThCallbackStack; + DWORD ThCallbackBStore; + DWORD NextCallback; + DWORD FramePointer; + DWORD64 KiCallUserMode; + DWORD64 KeUserCallbackDispatcher; + DWORD64 SystemRangeStart; + DWORD64 Reserved[8]; +} KDHELP64, *PKDHELP64; +typedef struct _tagSTACKFRAME64 { + ADDRESS64 AddrPC; // program counter + ADDRESS64 AddrReturn; // return address + ADDRESS64 AddrFrame; // frame pointer + ADDRESS64 AddrStack; // stack pointer + ADDRESS64 AddrBStore; // backing store pointer + PVOID FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD64 Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD64 Reserved[3]; + KDHELP64 KdHelp; +} STACKFRAME64, *LPSTACKFRAME64; +typedef +BOOL +(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)( + HANDLE hProcess, + DWORD64 qwBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead + ); +typedef +PVOID +(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( + HANDLE hProcess, + DWORD64 AddrBase + ); +typedef +DWORD64 +(__stdcall *PGET_MODULE_BASE_ROUTINE64)( + HANDLE hProcess, + DWORD64 Address + ); +typedef +DWORD64 +(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)( + HANDLE hProcess, + HANDLE hThread, + LPADDRESS64 lpaddr + ); +#define SYMOPT_CASE_INSENSITIVE 0x00000001 +#define SYMOPT_UNDNAME 0x00000002 +#define SYMOPT_DEFERRED_LOADS 0x00000004 +#define SYMOPT_NO_CPP 0x00000008 +#define SYMOPT_LOAD_LINES 0x00000010 +#define SYMOPT_OMAP_FIND_NEAREST 0x00000020 +#define SYMOPT_LOAD_ANYTHING 0x00000040 +#define SYMOPT_IGNORE_CVREC 0x00000080 +#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 +#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 +#define SYMOPT_EXACT_SYMBOLS 0x00000400 +#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 +#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 +#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 +#define SYMOPT_PUBLICS_ONLY 0x00004000 +#define SYMOPT_NO_PUBLICS 0x00008000 +#define SYMOPT_AUTO_PUBLICS 0x00010000 +#define SYMOPT_NO_IMAGE_SEARCH 0x00020000 +#define SYMOPT_SECURE 0x00040000 +#define SYMOPT_DEBUG 0x80000000 +#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration +#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration; +#endif // _MSC_VER < 1300 +#pragma pack(pop) + +// Some missing defines (for VC5/6): +#ifndef INVALID_FILE_ATTRIBUTES +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#endif + + +// secure-CRT_functions are only available starting with VC8 +#if _MSC_VER < 1400 +#define strcpy_s strcpy +#define strncpy_s strncpy +#define strcat_s(dst, len, src) strcat(dst, src) +#define _snprintf_s _snprintf +#define _tcscat_s _tcscat +#endif + +static void MyStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc) +{ + if (nMaxDestSize <= 0) return; + if (strlen(szSrc) < nMaxDestSize) + { + strcpy_s(szDest, nMaxDestSize, szSrc); + } + else + { + strncpy_s(szDest, nMaxDestSize, szSrc, nMaxDestSize); + szDest[nMaxDestSize-1] = 0; + } +} // MyStrCpy + +// Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL') +#define USED_CONTEXT_FLAGS CONTEXT_FULL + + +class StackWalkerInternal +{ +public: + StackWalkerInternal(StackWalker *parent, HANDLE hProcess) + { + m_parent = parent; + m_hDbhHelp = NULL; + pSC = NULL; + m_hProcess = hProcess; + m_szSymPath = NULL; + pSFTA = NULL; + pSGLFA = NULL; + pSGMB = NULL; + pSGMI = NULL; + pSGO = NULL; + pSGSFA = NULL; + pSI = NULL; + pSLM = NULL; + pSSO = NULL; + pSW = NULL; + pUDSN = NULL; + pSGSP = NULL; + } + ~StackWalkerInternal() + { + if (pSC != NULL) + pSC(m_hProcess); // SymCleanup + if (m_hDbhHelp != NULL) + FreeLibrary(m_hDbhHelp); + m_hDbhHelp = NULL; + m_parent = NULL; + if(m_szSymPath != NULL) + free(m_szSymPath); + m_szSymPath = NULL; + } + BOOL Init(LPCSTR szSymPath) + { + if (m_parent == NULL) + return FALSE; + // Dynamically load the Entry-Points for dbghelp.dll: + // First try to load the newsest one from + TCHAR szTemp[4096]; + // But before wqe do this, we first check if the ".local" file exists + if (GetModuleFileName(NULL, szTemp, 4096) > 0) + { + _tcscat_s(szTemp, _T(".local")); + if (GetFileAttributes(szTemp) == INVALID_FILE_ATTRIBUTES) + { + // ".local" file does not exist, so we can try to load the dbghelp.dll from the "Debugging Tools for Windows" + // Ok, first try the new path according to the archtitecture: +#ifdef _M_IX86 + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x86)\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#elif _M_X64 + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x64)\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#elif _M_IA64 + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (ia64)\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#endif + // If still not found, try the old directories... + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows\\dbghelp.dll")); + // now check if the file exists: + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#if defined _M_X64 || defined _M_IA64 + // Still not found? Then try to load the (old) 64-Bit version: + if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) + { + _tcscat_s(szTemp, _T("\\Debugging Tools for Windows 64-Bit\\dbghelp.dll")); + if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) + { + m_hDbhHelp = LoadLibrary(szTemp); + } + } +#endif + } + } + if (m_hDbhHelp == NULL) // if not already loaded, try to load a default-one + m_hDbhHelp = LoadLibrary( _T("dbghelp.dll") ); + if (m_hDbhHelp == NULL) + return FALSE; + pSI = (tSI) GetProcAddress(m_hDbhHelp, "SymInitialize" ); + pSC = (tSC) GetProcAddress(m_hDbhHelp, "SymCleanup" ); + + pSW = (tSW) GetProcAddress(m_hDbhHelp, "StackWalk64" ); + pSGO = (tSGO) GetProcAddress(m_hDbhHelp, "SymGetOptions" ); + pSSO = (tSSO) GetProcAddress(m_hDbhHelp, "SymSetOptions" ); + + pSFTA = (tSFTA) GetProcAddress(m_hDbhHelp, "SymFunctionTableAccess64" ); + pSGLFA = (tSGLFA) GetProcAddress(m_hDbhHelp, "SymGetLineFromAddr64" ); + pSGMB = (tSGMB) GetProcAddress(m_hDbhHelp, "SymGetModuleBase64" ); + pSGMI = (tSGMI) GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64" ); + //pSGMI_V3 = (tSGMI_V3) GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64" ); + pSGSFA = (tSGSFA) GetProcAddress(m_hDbhHelp, "SymGetSymFromAddr64" ); + pUDSN = (tUDSN) GetProcAddress(m_hDbhHelp, "UnDecorateSymbolName" ); + pSLM = (tSLM) GetProcAddress(m_hDbhHelp, "SymLoadModule64" ); + pSGSP =(tSGSP) GetProcAddress(m_hDbhHelp, "SymGetSearchPath" ); + + if ( pSC == NULL || pSFTA == NULL || pSGMB == NULL || pSGMI == NULL || + pSGO == NULL || pSGSFA == NULL || pSI == NULL || pSSO == NULL || + pSW == NULL || pUDSN == NULL || pSLM == NULL ) + { + FreeLibrary(m_hDbhHelp); + m_hDbhHelp = NULL; + pSC = NULL; + return FALSE; + } + + // SymInitialize + if (szSymPath != NULL) + m_szSymPath = _strdup(szSymPath); + if (this->pSI(m_hProcess, m_szSymPath, FALSE) == FALSE) + this->m_parent->OnDbgHelpErr("SymInitialize", GetLastError(), 0); + + DWORD symOptions = this->pSGO(); // SymGetOptions + symOptions |= SYMOPT_LOAD_LINES; + symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS; + //symOptions |= SYMOPT_NO_PROMPTS; + // SymSetOptions + symOptions = this->pSSO(symOptions); + + char buf[StackWalker::STACKWALK_MAX_NAMELEN] = {0}; + if (this->pSGSP != NULL) + { + if (this->pSGSP(m_hProcess, buf, StackWalker::STACKWALK_MAX_NAMELEN) == FALSE) + this->m_parent->OnDbgHelpErr("SymGetSearchPath", GetLastError(), 0); + } + char szUserName[1024] = {0}; + DWORD dwSize = 1024; + GetUserNameA(szUserName, &dwSize); + this->m_parent->OnSymInit(buf, symOptions, szUserName); + + return TRUE; + } + + StackWalker *m_parent; + + HMODULE m_hDbhHelp; + HANDLE m_hProcess; + LPSTR m_szSymPath; + +/*typedef struct IMAGEHLP_MODULE64_V3 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + // new elements: 07-Jun-2002 + CHAR LoadedImageName[256]; // symbol file name + CHAR LoadedPdbName[256]; // pdb file name + DWORD CVSig; // Signature of the CV record in the debug directories + CHAR CVData[MAX_PATH * 3]; // Contents of the CV record + DWORD PdbSig; // Signature of PDB + GUID PdbSig70; // Signature of PDB (VC 7 and up) + DWORD PdbAge; // DBI age of pdb + BOOL PdbUnmatched; // loaded an unmatched pdb + BOOL DbgUnmatched; // loaded an unmatched dbg + BOOL LineNumbers; // we have line number information + BOOL GlobalSymbols; // we have internal symbol information + BOOL TypeInfo; // we have type information + // new elements: 17-Dec-2003 + BOOL SourceIndexed; // pdb supports source server + BOOL Publics; // contains public symbols +}; +*/ + +#pragma pack(push,8) +typedef struct IMAGEHLP_MODULE64_V2 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name +}; +#pragma pack(pop) + + + // SymCleanup() + typedef BOOL (__stdcall *tSC)( IN HANDLE hProcess ); + tSC pSC; + + // SymFunctionTableAccess64() + typedef PVOID (__stdcall *tSFTA)( HANDLE hProcess, DWORD64 AddrBase ); + tSFTA pSFTA; + + // SymGetLineFromAddr64() + typedef BOOL (__stdcall *tSGLFA)( IN HANDLE hProcess, IN DWORD64 dwAddr, + OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_LINE64 Line ); + tSGLFA pSGLFA; + + // SymGetModuleBase64() + typedef DWORD64 (__stdcall *tSGMB)( IN HANDLE hProcess, IN DWORD64 dwAddr ); + tSGMB pSGMB; + + // SymGetModuleInfo64() + typedef BOOL (__stdcall *tSGMI)( IN HANDLE hProcess, IN DWORD64 dwAddr, OUT IMAGEHLP_MODULE64_V2 *ModuleInfo ); + tSGMI pSGMI; + +// // SymGetModuleInfo64() +// typedef BOOL (__stdcall *tSGMI_V3)( IN HANDLE hProcess, IN DWORD64 dwAddr, OUT IMAGEHLP_MODULE64_V3 *ModuleInfo ); +// tSGMI_V3 pSGMI_V3; + + // SymGetOptions() + typedef DWORD (__stdcall *tSGO)( VOID ); + tSGO pSGO; + + // SymGetSymFromAddr64() + typedef BOOL (__stdcall *tSGSFA)( IN HANDLE hProcess, IN DWORD64 dwAddr, + OUT PDWORD64 pdwDisplacement, OUT PIMAGEHLP_SYMBOL64 Symbol ); + tSGSFA pSGSFA; + + // SymInitialize() + typedef BOOL (__stdcall *tSI)( IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess ); + tSI pSI; + + // SymLoadModule64() + typedef DWORD64 (__stdcall *tSLM)( IN HANDLE hProcess, IN HANDLE hFile, + IN PSTR ImageName, IN PSTR ModuleName, IN DWORD64 BaseOfDll, IN DWORD SizeOfDll ); + tSLM pSLM; + + // SymSetOptions() + typedef DWORD (__stdcall *tSSO)( IN DWORD SymOptions ); + tSSO pSSO; + + // StackWalk64() + typedef BOOL (__stdcall *tSW)( + DWORD MachineType, + HANDLE hProcess, + HANDLE hThread, + LPSTACKFRAME64 StackFrame, + PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress ); + tSW pSW; + + // UnDecorateSymbolName() + typedef DWORD (__stdcall WINAPI *tUDSN)( PCSTR DecoratedName, PSTR UnDecoratedName, + DWORD UndecoratedLength, DWORD Flags ); + tUDSN pUDSN; + + typedef BOOL (__stdcall WINAPI *tSGSP)(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength); + tSGSP pSGSP; + + +private: + // **************************************** ToolHelp32 ************************ + #define MAX_MODULE_NAME32 255 + #define TH32CS_SNAPMODULE 0x00000008 + #pragma pack( push, 8 ) + typedef struct tagMODULEENTRY32 + { + DWORD dwSize; + DWORD th32ModuleID; // This module + DWORD th32ProcessID; // owning process + DWORD GlblcntUsage; // Global usage count on the module + DWORD ProccntUsage; // Module usage count in th32ProcessID's context + BYTE * modBaseAddr; // Base address of module in th32ProcessID's context + DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr + HMODULE hModule; // The hModule of this module in th32ProcessID's context + char szModule[MAX_MODULE_NAME32 + 1]; + char szExePath[MAX_PATH]; + } MODULEENTRY32; + typedef MODULEENTRY32 * PMODULEENTRY32; + typedef MODULEENTRY32 * LPMODULEENTRY32; + #pragma pack( pop ) + + BOOL GetModuleListTH32(HANDLE hProcess, DWORD pid) + { + // CreateToolhelp32Snapshot() + typedef HANDLE (__stdcall *tCT32S)(DWORD dwFlags, DWORD th32ProcessID); + // Module32First() + typedef BOOL (__stdcall *tM32F)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); + // Module32Next() + typedef BOOL (__stdcall *tM32N)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); + + // try both dlls... + const TCHAR *dllname[] = { _T("kernel32.dll"), _T("tlhelp32.dll") }; + HINSTANCE hToolhelp = NULL; + tCT32S pCT32S = NULL; + tM32F pM32F = NULL; + tM32N pM32N = NULL; + + HANDLE hSnap; + MODULEENTRY32 me; + me.dwSize = sizeof(me); + BOOL keepGoing; + size_t i; + + for (i = 0; i<(sizeof(dllname) / sizeof(dllname[0])); i++ ) + { + hToolhelp = LoadLibrary( dllname[i] ); + if (hToolhelp == NULL) + continue; + pCT32S = (tCT32S) GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot"); + pM32F = (tM32F) GetProcAddress(hToolhelp, "Module32First"); + pM32N = (tM32N) GetProcAddress(hToolhelp, "Module32Next"); + if ( (pCT32S != NULL) && (pM32F != NULL) && (pM32N != NULL) ) + break; // found the functions! + FreeLibrary(hToolhelp); + hToolhelp = NULL; + } + + if (hToolhelp == NULL) + return FALSE; + + hSnap = pCT32S( TH32CS_SNAPMODULE, pid ); + if (hSnap == (HANDLE) -1) + { + FreeLibrary(hToolhelp); + return FALSE; + } + + keepGoing = !!pM32F( hSnap, &me ); + int cnt = 0; + while (keepGoing) + { + this->LoadModule(hProcess, me.szExePath, me.szModule, (DWORD64) me.modBaseAddr, me.modBaseSize); + cnt++; + keepGoing = !!pM32N( hSnap, &me ); + } + CloseHandle(hSnap); + FreeLibrary(hToolhelp); + if (cnt <= 0) + return FALSE; + return TRUE; + } // GetModuleListTH32 + + // **************************************** PSAPI ************************ + typedef struct _MODULEINFO { + LPVOID lpBaseOfDll; + DWORD SizeOfImage; + LPVOID EntryPoint; + } MODULEINFO, *LPMODULEINFO; + + BOOL GetModuleListPSAPI(HANDLE hProcess) + { + // EnumProcessModules() + typedef BOOL (__stdcall *tEPM)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ); + // GetModuleFileNameEx() + typedef DWORD (__stdcall *tGMFNE)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); + // GetModuleBaseName() + typedef DWORD (__stdcall *tGMBN)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); + // GetModuleInformation() + typedef BOOL (__stdcall *tGMI)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO pmi, DWORD nSize ); + + HINSTANCE hPsapi; + tEPM pEPM; + tGMFNE pGMFNE; + tGMBN pGMBN; + tGMI pGMI; + + DWORD i; + //ModuleEntry e; + DWORD cbNeeded; + MODULEINFO mi; + HMODULE *hMods = 0; + char *tt = NULL; + char *tt2 = NULL; + const SIZE_T TTBUFLEN = 8096; + int cnt = 0; + + hPsapi = LoadLibrary( _T("psapi.dll") ); + if (hPsapi == NULL) + return FALSE; + + pEPM = (tEPM) GetProcAddress( hPsapi, "EnumProcessModules" ); + pGMFNE = (tGMFNE) GetProcAddress( hPsapi, "GetModuleFileNameExA" ); + pGMBN = (tGMFNE) GetProcAddress( hPsapi, "GetModuleBaseNameA" ); + pGMI = (tGMI) GetProcAddress( hPsapi, "GetModuleInformation" ); + if ( (pEPM == NULL) || (pGMFNE == NULL) || (pGMBN == NULL) || (pGMI == NULL) ) + { + // we couldn´t find all functions + FreeLibrary(hPsapi); + return FALSE; + } + + hMods = (HMODULE*) malloc(sizeof(HMODULE) * (TTBUFLEN / sizeof HMODULE)); + tt = (char*) malloc(sizeof(char) * TTBUFLEN); + tt2 = (char*) malloc(sizeof(char) * TTBUFLEN); + if ( (hMods == NULL) || (tt == NULL) || (tt2 == NULL) ) + goto cleanup; + + if ( ! pEPM( hProcess, hMods, TTBUFLEN, &cbNeeded ) ) + { + //_ftprintf(fLogFile, _T("%lu: EPM failed, GetLastError = %lu\n"), g_dwShowCount, gle ); + goto cleanup; + } + + if ( cbNeeded > TTBUFLEN ) + { + //_ftprintf(fLogFile, _T("%lu: More than %lu module handles. Huh?\n"), g_dwShowCount, lenof( hMods ) ); + goto cleanup; + } + + for ( i = 0; i < cbNeeded / sizeof hMods[0]; i++ ) + { + // base address, size + pGMI(hProcess, hMods[i], &mi, sizeof mi ); + // image file name + tt[0] = 0; + pGMFNE(hProcess, hMods[i], tt, TTBUFLEN ); + // module name + tt2[0] = 0; + pGMBN(hProcess, hMods[i], tt2, TTBUFLEN ); + + DWORD dwRes = this->LoadModule(hProcess, tt, tt2, (DWORD64) mi.lpBaseOfDll, mi.SizeOfImage); + if (dwRes != ERROR_SUCCESS) + this->m_parent->OnDbgHelpErr("LoadModule", dwRes, 0); + cnt++; + } + + cleanup: + if (hPsapi != NULL) FreeLibrary(hPsapi); + if (tt2 != NULL) free(tt2); + if (tt != NULL) free(tt); + if (hMods != NULL) free(hMods); + + return cnt != 0; + } // GetModuleListPSAPI + + DWORD LoadModule(HANDLE hProcess, LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size) + { + CHAR *szImg = _strdup(img); + CHAR *szMod = _strdup(mod); + DWORD result = ERROR_SUCCESS; + if ( (szImg == NULL) || (szMod == NULL) ) + result = ERROR_NOT_ENOUGH_MEMORY; + else + { + if (pSLM(hProcess, 0, szImg, szMod, baseAddr, size) == 0) + result = GetLastError(); + } + ULONGLONG fileVersion = 0; + if ( (m_parent != NULL) && (szImg != NULL) ) + { + // try to retrive the file-version: + if ( (this->m_parent->m_options & StackWalker::RetrieveFileVersion) != 0) + { + VS_FIXEDFILEINFO *fInfo = NULL; + DWORD dwHandle; + DWORD dwSize = GetFileVersionInfoSizeA(szImg, &dwHandle); + if (dwSize > 0) + { + LPVOID vData = malloc(dwSize); + if (vData != NULL) + { + if (GetFileVersionInfoA(szImg, dwHandle, dwSize, vData) != 0) + { + UINT len; + TCHAR szSubBlock[] = _T("\\"); + if (VerQueryValue(vData, szSubBlock, (LPVOID*) &fInfo, &len) == 0) + fInfo = NULL; + else + { + fileVersion = ((ULONGLONG)fInfo->dwFileVersionLS) + ((ULONGLONG)fInfo->dwFileVersionMS << 32); + } + } + free(vData); + } + } + } + + // Retrive some additional-infos about the module + IMAGEHLP_MODULE64_V2 Module; + const char *szSymType = "-unknown-"; + if (this->GetModuleInfo(hProcess, baseAddr, &Module) != FALSE) + { + switch(Module.SymType) + { + case SymNone: + szSymType = "-nosymbols-"; + break; + case SymCoff: // 1 + szSymType = "COFF"; + break; + case SymCv: // 2 + szSymType = "CV"; + break; + case SymPdb: // 3 + szSymType = "PDB"; + break; + case SymExport: // 4 + szSymType = "-exported-"; + break; + case SymDeferred: // 5 + szSymType = "-deferred-"; + break; + case SymSym: // 6 + szSymType = "SYM"; + break; + case 7: // SymDia: + szSymType = "DIA"; + break; + case 8: //SymVirtual: + szSymType = "Virtual"; + break; + } + } + this->m_parent->OnLoadModule(img, mod, baseAddr, size, result, szSymType, Module.LoadedImageName, fileVersion); + } + if (szImg != NULL) free(szImg); + if (szMod != NULL) free(szMod); + return result; + } +public: + BOOL LoadModules(HANDLE hProcess, DWORD dwProcessId) + { + // first try toolhelp32 + if (GetModuleListTH32(hProcess, dwProcessId)) + return true; + // then try psapi + return GetModuleListPSAPI(hProcess); + } + + + BOOL GetModuleInfo(HANDLE hProcess, DWORD64 baseAddr, IMAGEHLP_MODULE64_V2 *pModuleInfo) + { + if(this->pSGMI == NULL) + { + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + // First try to use the larger ModuleInfo-Structure +// memset(pModuleInfo, 0, sizeof(IMAGEHLP_MODULE64_V3)); +// pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V3); +// if (this->pSGMI_V3 != NULL) +// { +// if (this->pSGMI_V3(hProcess, baseAddr, pModuleInfo) != FALSE) +// return TRUE; +// // check if the parameter was wrong (size is bad...) +// if (GetLastError() != ERROR_INVALID_PARAMETER) +// return FALSE; +// } + // could not retrive the bigger structure, try with the smaller one (as defined in VC7.1)... + pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2); + void *pData = malloc(4096); // reserve enough memory, so the bug in v6.3.5.1 does not lead to memory-overwrites... + if (pData == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + memcpy(pData, pModuleInfo, sizeof(IMAGEHLP_MODULE64_V2)); + if (this->pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V2*) pData) != FALSE) + { + // only copy as much memory as is reserved... + memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V2)); + pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2); + free(pData); + return TRUE; + } + free(pData); + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } +}; + +// ############################################################# +StackWalker::StackWalker(DWORD dwProcessId, HANDLE hProcess) +{ + this->m_options = OptionsAll; + this->m_modulesLoaded = FALSE; + this->m_hProcess = hProcess; + this->m_sw = new StackWalkerInternal(this, this->m_hProcess); + this->m_dwProcessId = dwProcessId; + this->m_szSymPath = NULL; + this->m_MaxRecursionCount = 1000; +} +StackWalker::StackWalker(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess) +{ + this->m_options = options; + this->m_modulesLoaded = FALSE; + this->m_hProcess = hProcess; + this->m_sw = new StackWalkerInternal(this, this->m_hProcess); + this->m_dwProcessId = dwProcessId; + if (szSymPath != NULL) + { + this->m_szSymPath = _strdup(szSymPath); + this->m_options |= SymBuildPath; + } + else + this->m_szSymPath = NULL; + this->m_MaxRecursionCount = 1000; +} + +StackWalker::~StackWalker() +{ + if (m_szSymPath != NULL) + free(m_szSymPath); + m_szSymPath = NULL; + if (this->m_sw != NULL) + delete this->m_sw; + this->m_sw = NULL; +} + +BOOL StackWalker::LoadModules() +{ + if (this->m_sw == NULL) + { + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + if (m_modulesLoaded != FALSE) + return TRUE; + + // Build the sym-path: + char *szSymPath = NULL; + if ( (this->m_options & SymBuildPath) != 0) + { + const size_t nSymPathLen = 4096; + szSymPath = (char*) malloc(nSymPathLen); + if (szSymPath == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + szSymPath[0] = 0; + // Now first add the (optional) provided sympath: + if (this->m_szSymPath != NULL) + { + strcat_s(szSymPath, nSymPathLen, this->m_szSymPath); + strcat_s(szSymPath, nSymPathLen, ";"); + } + + strcat_s(szSymPath, nSymPathLen, ".;"); + + const size_t nTempLen = 1024; + char szTemp[nTempLen]; + // Now add the current directory: + if (GetCurrentDirectoryA(nTempLen, szTemp) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + + // Now add the path for the main-module: + if (GetModuleFileNameA(NULL, szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + for (char *p = (szTemp+strlen(szTemp)-1); p >= szTemp; --p) + { + // locate the rightmost path separator + if ( (*p == '\\') || (*p == '/') || (*p == ':') ) + { + *p = 0; + break; + } + } // for (search for path separator...) + if (strlen(szTemp) > 0) + { + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + } + if (GetEnvironmentVariableA("_NT_SYMBOL_PATH", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + if (GetEnvironmentVariableA("_NT_ALTERNATE_SYMBOL_PATH", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + if (GetEnvironmentVariableA("SYSTEMROOT", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + // also add the "system32"-directory: + strcat_s(szTemp, nTempLen, "\\system32"); + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, ";"); + } + + if ( (this->m_options & SymUseSymSrv) != 0) + { + if (GetEnvironmentVariableA("SYSTEMDRIVE", szTemp, nTempLen) > 0) + { + szTemp[nTempLen-1] = 0; + strcat_s(szSymPath, nSymPathLen, "SRV*"); + strcat_s(szSymPath, nSymPathLen, szTemp); + strcat_s(szSymPath, nSymPathLen, "\\websymbols"); + strcat_s(szSymPath, nSymPathLen, "*http://msdl.microsoft.com/download/symbols;"); + } + else + strcat_s(szSymPath, nSymPathLen, "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;"); + } + } // if SymBuildPath + + // First Init the whole stuff... + BOOL bRet = this->m_sw->Init(szSymPath); + if (szSymPath != NULL) free(szSymPath); szSymPath = NULL; + if (bRet == FALSE) + { + this->OnDbgHelpErr("Error while initializing dbghelp.dll", 0, 0); + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + + bRet = this->m_sw->LoadModules(this->m_hProcess, this->m_dwProcessId); + if (bRet != FALSE) + m_modulesLoaded = TRUE; + return bRet; +} + + +// The following is used to pass the "userData"-Pointer to the user-provided readMemoryFunction +// This has to be done due to a problem with the "hProcess"-parameter in x64... +// Because this class is in no case multi-threading-enabled (because of the limitations +// of dbghelp.dll) it is "safe" to use a static-variable +static StackWalker::PReadProcessMemoryRoutine s_readMemoryFunction = NULL; +static LPVOID s_readMemoryFunction_UserData = NULL; + +BOOL StackWalker::ShowCallstack(HANDLE hThread, const CONTEXT *context, PReadProcessMemoryRoutine readMemoryFunction, LPVOID pUserData) +{ + CONTEXT c; + CallstackEntry csEntry; + IMAGEHLP_SYMBOL64 *pSym = NULL; + StackWalkerInternal::IMAGEHLP_MODULE64_V2 Module; + IMAGEHLP_LINE64 Line; + int frameNum; + bool bLastEntryCalled = true; + int curRecursionCount = 0; + + if (m_modulesLoaded == FALSE) + this->LoadModules(); // ignore the result... + + if (this->m_sw->m_hDbhHelp == NULL) + { + SetLastError(ERROR_DLL_INIT_FAILED); + return FALSE; + } + + s_readMemoryFunction = readMemoryFunction; + s_readMemoryFunction_UserData = pUserData; + + if (context == NULL) + { + // If no context is provided, capture the context + if (hThread == GetCurrentThread()) + { + GET_CURRENT_CONTEXT(c, USED_CONTEXT_FLAGS); + } + else + { + SuspendThread(hThread); + memset(&c, 0, sizeof(CONTEXT)); + c.ContextFlags = USED_CONTEXT_FLAGS; + if (GetThreadContext(hThread, &c) == FALSE) + { + ResumeThread(hThread); + return FALSE; + } + } + } + else + c = *context; + + // init STACKFRAME for first call + STACKFRAME64 s; // in/out stackframe + memset(&s, 0, sizeof(s)); + DWORD imageType; +#ifdef _M_IX86 + // normally, call ImageNtHeader() and use machine info from PE header + imageType = IMAGE_FILE_MACHINE_I386; + s.AddrPC.Offset = c.Eip; + s.AddrPC.Mode = AddrModeFlat; + s.AddrFrame.Offset = c.Ebp; + s.AddrFrame.Mode = AddrModeFlat; + s.AddrStack.Offset = c.Esp; + s.AddrStack.Mode = AddrModeFlat; +#elif _M_X64 + imageType = IMAGE_FILE_MACHINE_AMD64; + s.AddrPC.Offset = c.Rip; + s.AddrPC.Mode = AddrModeFlat; + s.AddrFrame.Offset = c.Rsp; + s.AddrFrame.Mode = AddrModeFlat; + s.AddrStack.Offset = c.Rsp; + s.AddrStack.Mode = AddrModeFlat; +#elif _M_IA64 + imageType = IMAGE_FILE_MACHINE_IA64; + s.AddrPC.Offset = c.StIIP; + s.AddrPC.Mode = AddrModeFlat; + s.AddrFrame.Offset = c.IntSp; + s.AddrFrame.Mode = AddrModeFlat; + s.AddrBStore.Offset = c.RsBSP; + s.AddrBStore.Mode = AddrModeFlat; + s.AddrStack.Offset = c.IntSp; + s.AddrStack.Mode = AddrModeFlat; +#else +#error "Platform not supported!" +#endif + + pSym = (IMAGEHLP_SYMBOL64 *) malloc(sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); + if (!pSym) goto cleanup; // not enough memory... + memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); + pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); + pSym->MaxNameLength = STACKWALK_MAX_NAMELEN; + + memset(&Line, 0, sizeof(Line)); + Line.SizeOfStruct = sizeof(Line); + + memset(&Module, 0, sizeof(Module)); + Module.SizeOfStruct = sizeof(Module); + + for (frameNum = 0; ; ++frameNum ) + { + // get next stack frame (StackWalk64(), SymFunctionTableAccess64(), SymGetModuleBase64()) + // if this returns ERROR_INVALID_ADDRESS (487) or ERROR_NOACCESS (998), you can + // assume that either you are done, or that the stack is so hosed that the next + // deeper frame could not be found. + // CONTEXT need not to be suplied if imageTyp is IMAGE_FILE_MACHINE_I386! + if ( ! this->m_sw->pSW(imageType, this->m_hProcess, hThread, &s, &c, myReadProcMem, this->m_sw->pSFTA, this->m_sw->pSGMB, NULL) ) + { + // INFO: "StackWalk64" does not set "GetLastError"... + this->OnDbgHelpErr("StackWalk64", 0, s.AddrPC.Offset); + break; + } + + csEntry.offset = s.AddrPC.Offset; + csEntry.name[0] = 0; + csEntry.undName[0] = 0; + csEntry.undFullName[0] = 0; + csEntry.offsetFromSmybol = 0; + csEntry.offsetFromLine = 0; + csEntry.lineFileName[0] = 0; + csEntry.lineNumber = 0; + csEntry.loadedImageName[0] = 0; + csEntry.moduleName[0] = 0; + if (s.AddrPC.Offset == s.AddrReturn.Offset) + { + if ( (this->m_MaxRecursionCount > 0) && (curRecursionCount > m_MaxRecursionCount) ) + { + this->OnDbgHelpErr("StackWalk64-Endless-Callstack!", 0, s.AddrPC.Offset); + break; + } + curRecursionCount++; + } + else + curRecursionCount = 0; + if (s.AddrPC.Offset != 0) + { + // we seem to have a valid PC + // show procedure info (SymGetSymFromAddr64()) + if (this->m_sw->pSGSFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromSmybol), pSym) != FALSE) + { + MyStrCpy(csEntry.name, STACKWALK_MAX_NAMELEN, pSym->Name); + // UnDecorateSymbolName() + this->m_sw->pUDSN( pSym->Name, csEntry.undName, STACKWALK_MAX_NAMELEN, UNDNAME_NAME_ONLY ); + this->m_sw->pUDSN( pSym->Name, csEntry.undFullName, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE ); + } + else + { + this->OnDbgHelpErr("SymGetSymFromAddr64", GetLastError(), s.AddrPC.Offset); + } + + // show line number info, NT5.0-method (SymGetLineFromAddr64()) + if (this->m_sw->pSGLFA != NULL ) + { // yes, we have SymGetLineFromAddr64() + if (this->m_sw->pSGLFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromLine), &Line) != FALSE) + { + csEntry.lineNumber = Line.LineNumber; + MyStrCpy(csEntry.lineFileName, STACKWALK_MAX_NAMELEN, Line.FileName); + } + else + { + this->OnDbgHelpErr("SymGetLineFromAddr64", GetLastError(), s.AddrPC.Offset); + } + } // yes, we have SymGetLineFromAddr64() + + // show module info (SymGetModuleInfo64()) + if (this->m_sw->GetModuleInfo(this->m_hProcess, s.AddrPC.Offset, &Module ) != FALSE) + { // got module info OK + switch ( Module.SymType ) + { + case SymNone: + csEntry.symTypeString = "-nosymbols-"; + break; + case SymCoff: + csEntry.symTypeString = "COFF"; + break; + case SymCv: + csEntry.symTypeString = "CV"; + break; + case SymPdb: + csEntry.symTypeString = "PDB"; + break; + case SymExport: + csEntry.symTypeString = "-exported-"; + break; + case SymDeferred: + csEntry.symTypeString = "-deferred-"; + break; + case SymSym: + csEntry.symTypeString = "SYM"; + break; +#if API_VERSION_NUMBER >= 9 + case SymDia: + csEntry.symTypeString = "DIA"; + break; +#endif + case 8: //SymVirtual: + csEntry.symTypeString = "Virtual"; + break; + default: + //_snprintf( ty, sizeof ty, "symtype=%ld", (long) Module.SymType ); + csEntry.symTypeString = NULL; + break; + } + + // TODO: Mache dies sicher...! + MyStrCpy(csEntry.moduleName, STACKWALK_MAX_NAMELEN, Module.ModuleName); + csEntry.baseOfImage = Module.BaseOfImage; + MyStrCpy(csEntry.loadedImageName, STACKWALK_MAX_NAMELEN, Module.LoadedImageName); + } // got module info OK + else + { + this->OnDbgHelpErr("SymGetModuleInfo64", GetLastError(), s.AddrPC.Offset); + } + } // we seem to have a valid PC + + CallstackEntryType et = nextEntry; + if (frameNum == 0) + et = firstEntry; + bLastEntryCalled = false; + this->OnCallstackEntry(et, csEntry); + + if (s.AddrReturn.Offset == 0) + { + bLastEntryCalled = true; + this->OnCallstackEntry(lastEntry, csEntry); + SetLastError(ERROR_SUCCESS); + break; + } + } // for ( frameNum ) + + cleanup: + if (pSym) free( pSym ); + + if (bLastEntryCalled == false) + this->OnCallstackEntry(lastEntry, csEntry); + + if (context == NULL) + ResumeThread(hThread); + + return TRUE; +} + +BOOL __stdcall StackWalker::myReadProcMem( + HANDLE hProcess, + DWORD64 qwBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead + ) +{ + if (s_readMemoryFunction == NULL) + { + SIZE_T st; + BOOL bRet = ReadProcessMemory(hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, &st); + *lpNumberOfBytesRead = (DWORD) st; + //printf("ReadMemory: hProcess: %p, baseAddr: %p, buffer: %p, size: %d, read: %d, result: %d\n", hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, (DWORD) st, (DWORD) bRet); + return bRet; + } + else + { + return s_readMemoryFunction(hProcess, qwBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead, s_readMemoryFunction_UserData); + } +} + +void StackWalker::OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + if (fileVersion == 0) + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s'\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName); + else + { + DWORD v4 = (DWORD) fileVersion & 0xFFFF; + DWORD v3 = (DWORD) (fileVersion>>16) & 0xFFFF; + DWORD v2 = (DWORD) (fileVersion>>32) & 0xFFFF; + DWORD v1 = (DWORD) (fileVersion>>48) & 0xFFFF; + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s', fileVersion: %d.%d.%d.%d\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName, v1, v2, v3, v4); + } + OnOutput(buffer); +} + +void StackWalker::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + if ( (eType != lastEntry) && (entry.offset != 0) ) + { + if (entry.name[0] == 0) + MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, "(function-name not available)"); + if (entry.undName[0] != 0) + MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undName); + if (entry.undFullName[0] != 0) + MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undFullName); + if (entry.lineFileName[0] == 0) + { + MyStrCpy(entry.lineFileName, STACKWALK_MAX_NAMELEN, "(filename not available)"); + if (entry.moduleName[0] == 0) + MyStrCpy(entry.moduleName, STACKWALK_MAX_NAMELEN, "(module-name not available)"); + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%p (%s): %s: %s\n", (LPVOID) entry.offset, entry.moduleName, entry.lineFileName, entry.name); + } + else + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s (%d): %s\n", entry.lineFileName, entry.lineNumber, entry.name); + buffer[STACKWALK_MAX_NAMELEN-1] = 0; + OnOutput(buffer); + } +} + +void StackWalker::OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "ERROR: %s, GetLastError: %d (Address: %p)\n", szFuncName, gle, (LPVOID) addr); + OnOutput(buffer); +} + +void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName) +{ + CHAR buffer[STACKWALK_MAX_NAMELEN]; + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n", szSearchPath, symOptions, szUserName); + OnOutput(buffer); + // Also display the OS-version +#if _MSC_VER <= 1200 + OSVERSIONINFOA ver; + ZeroMemory(&ver, sizeof(OSVERSIONINFOA)); + ver.dwOSVersionInfoSize = sizeof(ver); + if (GetVersionExA(&ver) != FALSE) + { + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s)\n", + ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, + ver.szCSDVersion); + OnOutput(buffer); + } +#else + OSVERSIONINFOEXA ver; + ZeroMemory(&ver, sizeof(OSVERSIONINFOEXA)); + ver.dwOSVersionInfoSize = sizeof(ver); + if (GetVersionExA( (OSVERSIONINFOA*) &ver) != FALSE) + { + _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n", + ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, + ver.szCSDVersion, ver.wSuiteMask, ver.wProductType); + OnOutput(buffer); + } +#endif +} + +void StackWalker::OnOutput(LPCSTR buffer) +{ + OutputDebugStringA(buffer); +} diff --git a/source/StackWalker.h b/source/StackWalker.h index 212e02a9f..bf47d3726 100644 --- a/source/StackWalker.h +++ b/source/StackWalker.h @@ -1,214 +1,214 @@ -/**********************************************************************
- *
- * StackWalker.h
- *
- *
- *
- * LICENSE (http://www.opensource.org/licenses/bsd-license.php)
- *
- * Copyright (c) 2005-2010, Jochen Kalmbach
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * Neither the name of Jochen Kalmbach nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * **********************************************************************/
-// #pragma once is supported starting with _MCS_VER 1000,
-// so we need not to check the version (because we only support _MSC_VER >= 1100)!
-#pragma once
-
-#include <windows.h>
-
-// special defines for VC5/6 (if no actual PSDK is installed):
-#if _MSC_VER < 1300
-typedef unsigned __int64 DWORD64, *PDWORD64;
-#if defined(_WIN64)
-typedef unsigned __int64 SIZE_T, *PSIZE_T;
-#else
-typedef unsigned long SIZE_T, *PSIZE_T;
-#endif
-#endif // _MSC_VER < 1300
-
-class StackWalkerInternal; // forward
-class StackWalker
-{
-public:
- typedef enum StackWalkOptions
- {
- // No addition info will be retrived
- // (only the address is available)
- RetrieveNone = 0,
-
- // Try to get the symbol-name
- RetrieveSymbol = 1,
-
- // Try to get the line for this symbol
- RetrieveLine = 2,
-
- // Try to retrieve the module-infos
- RetrieveModuleInfo = 4,
-
- // Also retrieve the version for the DLL/EXE
- RetrieveFileVersion = 8,
-
- // Contains all the abouve
- RetrieveVerbose = 0xF,
-
- // Generate a "good" symbol-search-path
- SymBuildPath = 0x10,
-
- // Also use the public Microsoft-Symbol-Server
- SymUseSymSrv = 0x20,
-
- // Contains all the abouve "Sym"-options
- SymAll = 0x30,
-
- // Contains all options (default)
- OptionsAll = 0x3F
- } StackWalkOptions;
-
- StackWalker(
- int options = OptionsAll, // 'int' is by design, to combine the enum-flags
- LPCSTR szSymPath = NULL,
- DWORD dwProcessId = GetCurrentProcessId(),
- HANDLE hProcess = GetCurrentProcess()
- );
- StackWalker(DWORD dwProcessId, HANDLE hProcess);
- virtual ~StackWalker();
-
- typedef BOOL (__stdcall *PReadProcessMemoryRoutine)(
- HANDLE hProcess,
- DWORD64 qwBaseAddress,
- PVOID lpBuffer,
- DWORD nSize,
- LPDWORD lpNumberOfBytesRead,
- LPVOID pUserData // optional data, which was passed in "ShowCallstack"
- );
-
- BOOL LoadModules();
-
- BOOL ShowCallstack(
- HANDLE hThread = GetCurrentThread(),
- const CONTEXT *context = NULL,
- PReadProcessMemoryRoutine readMemoryFunction = NULL,
- LPVOID pUserData = NULL // optional to identify some data in the 'readMemoryFunction'-callback
- );
-
-#if _MSC_VER >= 1300
-// due to some reasons, the "STACKWALK_MAX_NAMELEN" must be declared as "public"
-// in older compilers in order to use it... starting with VC7 we can declare it as "protected"
-protected:
-#endif
- enum { STACKWALK_MAX_NAMELEN = 1024 }; // max name length for found symbols
-
-protected:
- // Entry for each Callstack-Entry
- typedef struct CallstackEntry
- {
- DWORD64 offset; // if 0, we have no valid entry
- CHAR name[STACKWALK_MAX_NAMELEN];
- CHAR undName[STACKWALK_MAX_NAMELEN];
- CHAR undFullName[STACKWALK_MAX_NAMELEN];
- DWORD64 offsetFromSmybol;
- DWORD offsetFromLine;
- DWORD lineNumber;
- CHAR lineFileName[STACKWALK_MAX_NAMELEN];
- DWORD symType;
- LPCSTR symTypeString;
- CHAR moduleName[STACKWALK_MAX_NAMELEN];
- DWORD64 baseOfImage;
- CHAR loadedImageName[STACKWALK_MAX_NAMELEN];
- } CallstackEntry;
-
- typedef enum CallstackEntryType {firstEntry, nextEntry, lastEntry};
-
- virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName);
- virtual void OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion);
- virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry);
- virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr);
- virtual void OnOutput(LPCSTR szText);
-
- StackWalkerInternal *m_sw;
- HANDLE m_hProcess;
- DWORD m_dwProcessId;
- BOOL m_modulesLoaded;
- LPSTR m_szSymPath;
-
- int m_options;
- int m_MaxRecursionCount;
-
- static BOOL __stdcall myReadProcMem(HANDLE hProcess, DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead);
-
- friend StackWalkerInternal;
-};
-
-
-// The "ugly" assembler-implementation is needed for systems before XP
-// If you have a new PSDK and you only compile for XP and later, then you can use
-// the "RtlCaptureContext"
-// Currently there is no define which determines the PSDK-Version...
-// So we just use the compiler-version (and assumes that the PSDK is
-// the one which was installed by the VS-IDE)
-
-// INFO: If you want, you can use the RtlCaptureContext if you only target XP and later...
-// But I currently use it in x64/IA64 environments...
-//#if defined(_M_IX86) && (_WIN32_WINNT <= 0x0500) && (_MSC_VER < 1400)
-
-#if defined(_M_IX86)
-#ifdef CURRENT_THREAD_VIA_EXCEPTION
-// TODO: The following is not a "good" implementation,
-// because the callstack is only valid in the "__except" block...
-#define GET_CURRENT_CONTEXT(c, contextFlags) \
- do { \
- memset(&c, 0, sizeof(CONTEXT)); \
- EXCEPTION_POINTERS *pExp = NULL; \
- __try { \
- throw 0; \
- } __except( ( (pExp = GetExceptionInformation()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_EXECUTE_HANDLER)) {} \
- if (pExp != NULL) \
- memcpy(&c, pExp->ContextRecord, sizeof(CONTEXT)); \
- c.ContextFlags = contextFlags; \
- } while(0);
-#else
-// The following should be enough for walking the callstack...
-#define GET_CURRENT_CONTEXT(c, contextFlags) \
- do { \
- memset(&c, 0, sizeof(CONTEXT)); \
- c.ContextFlags = contextFlags; \
- __asm call x \
- __asm x: pop eax \
- __asm mov c.Eip, eax \
- __asm mov c.Ebp, ebp \
- __asm mov c.Esp, esp \
- } while(0);
-#endif
-
-#else
-
-// The following is defined for x86 (XP and higher), x64 and IA64:
-#define GET_CURRENT_CONTEXT(c, contextFlags) \
- do { \
- memset(&c, 0, sizeof(CONTEXT)); \
- c.ContextFlags = contextFlags; \
- RtlCaptureContext(&c); \
-} while(0);
-#endif
+/********************************************************************** + * + * StackWalker.h + * + * + * + * LICENSE (http://www.opensource.org/licenses/bsd-license.php) + * + * Copyright (c) 2005-2010, Jochen Kalmbach + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of Jochen Kalmbach nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * **********************************************************************/ +// #pragma once is supported starting with _MCS_VER 1000, +// so we need not to check the version (because we only support _MSC_VER >= 1100)! +#pragma once + +#include <windows.h> + +// special defines for VC5/6 (if no actual PSDK is installed): +#if _MSC_VER < 1300 +typedef unsigned __int64 DWORD64, *PDWORD64; +#if defined(_WIN64) +typedef unsigned __int64 SIZE_T, *PSIZE_T; +#else +typedef unsigned long SIZE_T, *PSIZE_T; +#endif +#endif // _MSC_VER < 1300 + +class StackWalkerInternal; // forward +class StackWalker +{ +public: + typedef enum StackWalkOptions + { + // No addition info will be retrived + // (only the address is available) + RetrieveNone = 0, + + // Try to get the symbol-name + RetrieveSymbol = 1, + + // Try to get the line for this symbol + RetrieveLine = 2, + + // Try to retrieve the module-infos + RetrieveModuleInfo = 4, + + // Also retrieve the version for the DLL/EXE + RetrieveFileVersion = 8, + + // Contains all the abouve + RetrieveVerbose = 0xF, + + // Generate a "good" symbol-search-path + SymBuildPath = 0x10, + + // Also use the public Microsoft-Symbol-Server + SymUseSymSrv = 0x20, + + // Contains all the abouve "Sym"-options + SymAll = 0x30, + + // Contains all options (default) + OptionsAll = 0x3F + } StackWalkOptions; + + StackWalker( + int options = OptionsAll, // 'int' is by design, to combine the enum-flags + LPCSTR szSymPath = NULL, + DWORD dwProcessId = GetCurrentProcessId(), + HANDLE hProcess = GetCurrentProcess() + ); + StackWalker(DWORD dwProcessId, HANDLE hProcess); + virtual ~StackWalker(); + + typedef BOOL (__stdcall *PReadProcessMemoryRoutine)( + HANDLE hProcess, + DWORD64 qwBaseAddress, + PVOID lpBuffer, + DWORD nSize, + LPDWORD lpNumberOfBytesRead, + LPVOID pUserData // optional data, which was passed in "ShowCallstack" + ); + + BOOL LoadModules(); + + BOOL ShowCallstack( + HANDLE hThread = GetCurrentThread(), + const CONTEXT *context = NULL, + PReadProcessMemoryRoutine readMemoryFunction = NULL, + LPVOID pUserData = NULL // optional to identify some data in the 'readMemoryFunction'-callback + ); + +#if _MSC_VER >= 1300 +// due to some reasons, the "STACKWALK_MAX_NAMELEN" must be declared as "public" +// in older compilers in order to use it... starting with VC7 we can declare it as "protected" +protected: +#endif + enum { STACKWALK_MAX_NAMELEN = 1024 }; // max name length for found symbols + +protected: + // Entry for each Callstack-Entry + typedef struct CallstackEntry + { + DWORD64 offset; // if 0, we have no valid entry + CHAR name[STACKWALK_MAX_NAMELEN]; + CHAR undName[STACKWALK_MAX_NAMELEN]; + CHAR undFullName[STACKWALK_MAX_NAMELEN]; + DWORD64 offsetFromSmybol; + DWORD offsetFromLine; + DWORD lineNumber; + CHAR lineFileName[STACKWALK_MAX_NAMELEN]; + DWORD symType; + LPCSTR symTypeString; + CHAR moduleName[STACKWALK_MAX_NAMELEN]; + DWORD64 baseOfImage; + CHAR loadedImageName[STACKWALK_MAX_NAMELEN]; + } CallstackEntry; + + typedef enum CallstackEntryType {firstEntry, nextEntry, lastEntry}; + + virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName); + virtual void OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion); + virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry); + virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr); + virtual void OnOutput(LPCSTR szText); + + StackWalkerInternal *m_sw; + HANDLE m_hProcess; + DWORD m_dwProcessId; + BOOL m_modulesLoaded; + LPSTR m_szSymPath; + + int m_options; + int m_MaxRecursionCount; + + static BOOL __stdcall myReadProcMem(HANDLE hProcess, DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead); + + friend StackWalkerInternal; +}; + + +// The "ugly" assembler-implementation is needed for systems before XP +// If you have a new PSDK and you only compile for XP and later, then you can use +// the "RtlCaptureContext" +// Currently there is no define which determines the PSDK-Version... +// So we just use the compiler-version (and assumes that the PSDK is +// the one which was installed by the VS-IDE) + +// INFO: If you want, you can use the RtlCaptureContext if you only target XP and later... +// But I currently use it in x64/IA64 environments... +//#if defined(_M_IX86) && (_WIN32_WINNT <= 0x0500) && (_MSC_VER < 1400) + +#if defined(_M_IX86) +#ifdef CURRENT_THREAD_VIA_EXCEPTION +// TODO: The following is not a "good" implementation, +// because the callstack is only valid in the "__except" block... +#define GET_CURRENT_CONTEXT(c, contextFlags) \ + do { \ + memset(&c, 0, sizeof(CONTEXT)); \ + EXCEPTION_POINTERS *pExp = NULL; \ + __try { \ + throw 0; \ + } __except( ( (pExp = GetExceptionInformation()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_EXECUTE_HANDLER)) {} \ + if (pExp != NULL) \ + memcpy(&c, pExp->ContextRecord, sizeof(CONTEXT)); \ + c.ContextFlags = contextFlags; \ + } while(0); +#else +// The following should be enough for walking the callstack... +#define GET_CURRENT_CONTEXT(c, contextFlags) \ + do { \ + memset(&c, 0, sizeof(CONTEXT)); \ + c.ContextFlags = contextFlags; \ + __asm call x \ + __asm x: pop eax \ + __asm mov c.Eip, eax \ + __asm mov c.Ebp, ebp \ + __asm mov c.Esp, esp \ + } while(0); +#endif + +#else + +// The following is defined for x86 (XP and higher), x64 and IA64: +#define GET_CURRENT_CONTEXT(c, contextFlags) \ + do { \ + memset(&c, 0, sizeof(CONTEXT)); \ + c.ContextFlags = contextFlags; \ + RtlCaptureContext(&c); \ +} while(0); +#endif diff --git a/source/StringCompression.cpp b/source/StringCompression.cpp index 96d94fe9d..b7e08cb11 100644 --- a/source/StringCompression.cpp +++ b/source/StringCompression.cpp @@ -1,55 +1,55 @@ -
-// StringCompression.cpp
-
-// Implements the wrapping functions for compression and decompression using AString as their data
-
-#include "Globals.h"
-#include "StringCompression.h"
-#include "zlib.h"
-
-
-
-
-
-/// Compresses a_Data into a_Compressed; return Z_XXX error constants same as zlib's compress2()
-int CompressString(const char * a_Data, int a_Length, AString & a_Compressed)
-{
- uLongf CompressedSize = compressBound(a_Length);
-
- // HACK: We're assuming that AString returns its internal buffer in its data() call and we're overwriting that buffer!
- // It saves us one allocation and one memcpy of the entire compressed data
- // It may not work on some STL implementations! (Confirmed working on MSVC 2008 & 2010)
- a_Compressed.resize(CompressedSize);
- int errorcode = compress2( (Bytef*)a_Compressed.data(), &CompressedSize, (const Bytef*)a_Data, a_Length, Z_DEFAULT_COMPRESSION);
- if (errorcode != Z_OK)
- {
- return errorcode;
- }
- a_Compressed.resize(CompressedSize);
- return Z_OK;
-}
-
-
-
-
-
-/// Uncompresses a_Data into a_Decompressed; returns Z_XXX error constants same as zlib's uncompress()
-int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed, int a_UncompressedSize)
-{
- // HACK: We're assuming that AString returns its internal buffer in its data() call and we're overwriting that buffer!
- // It saves us one allocation and one memcpy of the entire compressed data
- // It may not work on some STL implementations! (Confirmed working on MSVC 2008 & 2010)
- a_Uncompressed.resize(a_UncompressedSize);
- uLongf UncompressedSize = (uLongf)a_UncompressedSize; // On some architectures the uLongf is different in size to int, that may be the cause of the -5 error
- int errorcode = uncompress((Bytef*)a_Uncompressed.data(), &UncompressedSize, (const Bytef*)a_Data, a_Length);
- if (errorcode != Z_OK)
- {
- return errorcode;
- }
- a_Uncompressed.resize(UncompressedSize);
- return Z_OK;
-}
-
-
-
-
+ +// StringCompression.cpp + +// Implements the wrapping functions for compression and decompression using AString as their data + +#include "Globals.h" +#include "StringCompression.h" +#include "zlib.h" + + + + + +/// Compresses a_Data into a_Compressed; return Z_XXX error constants same as zlib's compress2() +int CompressString(const char * a_Data, int a_Length, AString & a_Compressed) +{ + uLongf CompressedSize = compressBound(a_Length); + + // HACK: We're assuming that AString returns its internal buffer in its data() call and we're overwriting that buffer! + // It saves us one allocation and one memcpy of the entire compressed data + // It may not work on some STL implementations! (Confirmed working on MSVC 2008 & 2010) + a_Compressed.resize(CompressedSize); + int errorcode = compress2( (Bytef*)a_Compressed.data(), &CompressedSize, (const Bytef*)a_Data, a_Length, Z_DEFAULT_COMPRESSION); + if (errorcode != Z_OK) + { + return errorcode; + } + a_Compressed.resize(CompressedSize); + return Z_OK; +} + + + + + +/// Uncompresses a_Data into a_Decompressed; returns Z_XXX error constants same as zlib's uncompress() +int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed, int a_UncompressedSize) +{ + // HACK: We're assuming that AString returns its internal buffer in its data() call and we're overwriting that buffer! + // It saves us one allocation and one memcpy of the entire compressed data + // It may not work on some STL implementations! (Confirmed working on MSVC 2008 & 2010) + a_Uncompressed.resize(a_UncompressedSize); + uLongf UncompressedSize = (uLongf)a_UncompressedSize; // On some architectures the uLongf is different in size to int, that may be the cause of the -5 error + int errorcode = uncompress((Bytef*)a_Uncompressed.data(), &UncompressedSize, (const Bytef*)a_Data, a_Length); + if (errorcode != Z_OK) + { + return errorcode; + } + a_Uncompressed.resize(UncompressedSize); + return Z_OK; +} + + + + diff --git a/source/StringCompression.h b/source/StringCompression.h index 976fd2ecd..5afd4c37f 100644 --- a/source/StringCompression.h +++ b/source/StringCompression.h @@ -1,17 +1,17 @@ -
-// StringCompression.h
-
-// Interfaces to the wrapping functions for compression and decompression using AString as their data
-
-
-
-
-/// Compresses a_Data into a_Compressed; return Z_XXX error constants same as zlib's compress2()
-extern int CompressString(const char * a_Data, int a_Length, AString & a_Compressed);
-
-/// Uncompresses a_Data into a_Decompressed; returns Z_XXX error constants same as zlib's decompress()
-extern int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed, int a_UncompressedSize);
-
-
-
-
+ +// StringCompression.h + +// Interfaces to the wrapping functions for compression and decompression using AString as their data + + + + +/// Compresses a_Data into a_Compressed; return Z_XXX error constants same as zlib's compress2() +extern int CompressString(const char * a_Data, int a_Length, AString & a_Compressed); + +/// Uncompresses a_Data into a_Decompressed; returns Z_XXX error constants same as zlib's decompress() +extern int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed, int a_UncompressedSize); + + + + diff --git a/source/StringUtils.cpp b/source/StringUtils.cpp index df2e72a17..652c680c7 100644 --- a/source/StringUtils.cpp +++ b/source/StringUtils.cpp @@ -1,232 +1,232 @@ -
-// StringUtils.cpp
-
-// Implements the various string helper functions:
-
-#include "Globals.h"
-
-
-
-
-
-AString & AppendVPrintf(AString & str, const char *format, va_list args)
-{
- ASSERT(format != NULL);
-
- char buffer[2048];
- size_t len;
- #ifdef _MSC_VER
- // MS CRT provides secure printf that doesn't behave like in the C99 standard
- if ((len = _vsnprintf_s(buffer, ARRAYCOUNT(buffer), _TRUNCATE, format, args)) != -1)
- #else // _MSC_VER
- if ((len = vsnprintf(buffer, ARRAYCOUNT(buffer), format, args)) < ARRAYCOUNT(buffer))
- #endif // else _MSC_VER
- {
- // The result did fit into the static buffer
- str.append(buffer, len);
- return str;
- }
-
- // The result did not fit into the static buffer
- #ifdef _MSC_VER
- // for MS CRT, we need to calculate the result length
- len = _vscprintf(format, args);
- if (len == -1)
- {
- return str;
- }
- #endif // _MSC_VER
-
- // Allocate a buffer and printf into it:
- str.resize(len + 1);
- // HACK: we're accessing AString's internal buffer in a way that is NOT guaranteed to always work. But it works on all STL implementations tested.
- // I can't think of any other way that is safe, doesn't allocate twice as much space as needed and doesn't use C++11 features like the move constructor
- #ifdef _MSC_VER
- vsprintf_s((char *)str.data(), len + 1, format, args);
- #else // _MSC_VER
- vsnprintf((char *)str.data(), len + 1, format, args);
- #endif // else _MSC_VER
- str.resize(len);
- return str;
-}
-
-
-
-
-
-AString & Printf(AString & str, const char *format, ...)
-{
- str.clear();
- va_list args;
- va_start(args, format);
- std::string &retval = AppendVPrintf(str, format, args);
- va_end(args);
- return retval;
-}
-
-
-
-
-
-AString & AppendPrintf(AString &str, const char *format, ...)
-{
- va_list args;
- va_start(args, format);
- std::string &retval = AppendVPrintf(str, format, args);
- va_end(args);
- return retval;
-}
-
-
-
-
-
-AStringVector StringSplit(const AString & str, const AString & delim)
-{
- AStringVector results;
- size_t cutAt = 0;
- size_t Prev = 0;
- while ((cutAt = str.find_first_of(delim, Prev)) != str.npos)
- {
- results.push_back(str.substr(Prev, cutAt - Prev));
- Prev = cutAt + delim.length();
- }
- if (Prev < str.length())
- {
- results.push_back(str.substr(Prev));
- }
- return results;
-}
-
-
-
-
-AString TrimString(const AString & str)
-{
- size_t len = str.length();
- size_t start = 0;
- while (start < len)
- {
- if (str[start] > 32)
- {
- break;
- }
- ++start;
- }
- if (start == len)
- {
- return "";
- }
-
- size_t end = len;
- while (end >= start)
- {
- if (str[end] > 32)
- {
- break;
- }
- --end;
- }
-
- return str.substr(start, end - start + 1);
-}
-
-
-
-
-
-AString & StrToUpper(AString & s)
-{
- AString::iterator i = s.begin();
- AString::iterator end = s.end();
-
- while (i != end)
- {
- *i = (char)toupper(*i);
- ++i;
- }
- return s;
-}
-
-
-
-
-
-int NoCaseCompare(const AString & s1, const AString & s2)
-{
- #ifdef _MSC_VER
- // MSVC has stricmp that compares case-insensitive:
- return _stricmp(s1.c_str(), s2.c_str());
- #else
- // Do it the hard way:
- AString s1Copy(s1);
- AString s2Copy(s2);
- return StrToUpper(s1Copy).compare(StrToUpper(s2Copy));
- #endif // else _MSC_VER
-}
-
-
-
-
-
-void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & iReplaceWith)
-{
- size_t pos1 = iHayStack.find(iNeedle);
- while (pos1 != AString::npos)
- {
- iHayStack.replace( pos1, iNeedle.size(), iReplaceWith);
- pos1 = iHayStack.find(iNeedle, pos1);
- }
-}
-
-
-
-
-AStringList GetDirectoryContents(const char * a_Directory)
-{
- AStringList AllFiles;
-
- #ifdef _WIN32
-
- AString FileFilter = AString(a_Directory) + "*.*";
- HANDLE hFind;
- WIN32_FIND_DATA FindFileData;
-
- if ((hFind = FindFirstFile(FileFilter.c_str(), &FindFileData)) != INVALID_HANDLE_VALUE)
- {
- do
- {
- AllFiles.push_back(FindFileData.cFileName);
- } while (FindNextFile(hFind, &FindFileData));
- FindClose(hFind);
- }
-
- #else // _WIN32
-
- DIR * dp;
- struct dirent *dirp;
- if (*a_Directory == 0)
- {
- a_Directory = ".";
- }
- if ((dp = opendir(a_Directory)) == NULL)
- {
- LOGERROR("Error (%i) opening directory \"%s\"\n", errno, a_Directory );
- }
- else
- {
- while ((dirp = readdir(dp)) != NULL)
- {
- AllFiles.push_back(dirp->d_name);
- }
- closedir(dp);
- }
-
- #endif // else _WIN32
-
- return AllFiles;
-}
-
-
-
-
+ +// StringUtils.cpp + +// Implements the various string helper functions: + +#include "Globals.h" + + + + + +AString & AppendVPrintf(AString & str, const char *format, va_list args) +{ + ASSERT(format != NULL); + + char buffer[2048]; + size_t len; + #ifdef _MSC_VER + // MS CRT provides secure printf that doesn't behave like in the C99 standard + if ((len = _vsnprintf_s(buffer, ARRAYCOUNT(buffer), _TRUNCATE, format, args)) != -1) + #else // _MSC_VER + if ((len = vsnprintf(buffer, ARRAYCOUNT(buffer), format, args)) < ARRAYCOUNT(buffer)) + #endif // else _MSC_VER + { + // The result did fit into the static buffer + str.append(buffer, len); + return str; + } + + // The result did not fit into the static buffer + #ifdef _MSC_VER + // for MS CRT, we need to calculate the result length + len = _vscprintf(format, args); + if (len == -1) + { + return str; + } + #endif // _MSC_VER + + // Allocate a buffer and printf into it: + str.resize(len + 1); + // HACK: we're accessing AString's internal buffer in a way that is NOT guaranteed to always work. But it works on all STL implementations tested. + // I can't think of any other way that is safe, doesn't allocate twice as much space as needed and doesn't use C++11 features like the move constructor + #ifdef _MSC_VER + vsprintf_s((char *)str.data(), len + 1, format, args); + #else // _MSC_VER + vsnprintf((char *)str.data(), len + 1, format, args); + #endif // else _MSC_VER + str.resize(len); + return str; +} + + + + + +AString & Printf(AString & str, const char *format, ...) +{ + str.clear(); + va_list args; + va_start(args, format); + std::string &retval = AppendVPrintf(str, format, args); + va_end(args); + return retval; +} + + + + + +AString & AppendPrintf(AString &str, const char *format, ...) +{ + va_list args; + va_start(args, format); + std::string &retval = AppendVPrintf(str, format, args); + va_end(args); + return retval; +} + + + + + +AStringVector StringSplit(const AString & str, const AString & delim) +{ + AStringVector results; + size_t cutAt = 0; + size_t Prev = 0; + while ((cutAt = str.find_first_of(delim, Prev)) != str.npos) + { + results.push_back(str.substr(Prev, cutAt - Prev)); + Prev = cutAt + delim.length(); + } + if (Prev < str.length()) + { + results.push_back(str.substr(Prev)); + } + return results; +} + + + + +AString TrimString(const AString & str) +{ + size_t len = str.length(); + size_t start = 0; + while (start < len) + { + if (str[start] > 32) + { + break; + } + ++start; + } + if (start == len) + { + return ""; + } + + size_t end = len; + while (end >= start) + { + if (str[end] > 32) + { + break; + } + --end; + } + + return str.substr(start, end - start + 1); +} + + + + + +AString & StrToUpper(AString & s) +{ + AString::iterator i = s.begin(); + AString::iterator end = s.end(); + + while (i != end) + { + *i = (char)toupper(*i); + ++i; + } + return s; +} + + + + + +int NoCaseCompare(const AString & s1, const AString & s2) +{ + #ifdef _MSC_VER + // MSVC has stricmp that compares case-insensitive: + return _stricmp(s1.c_str(), s2.c_str()); + #else + // Do it the hard way: + AString s1Copy(s1); + AString s2Copy(s2); + return StrToUpper(s1Copy).compare(StrToUpper(s2Copy)); + #endif // else _MSC_VER +} + + + + + +void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & iReplaceWith) +{ + size_t pos1 = iHayStack.find(iNeedle); + while (pos1 != AString::npos) + { + iHayStack.replace( pos1, iNeedle.size(), iReplaceWith); + pos1 = iHayStack.find(iNeedle, pos1); + } +} + + + + +AStringList GetDirectoryContents(const char * a_Directory) +{ + AStringList AllFiles; + + #ifdef _WIN32 + + AString FileFilter = AString(a_Directory) + "*.*"; + HANDLE hFind; + WIN32_FIND_DATA FindFileData; + + if ((hFind = FindFirstFile(FileFilter.c_str(), &FindFileData)) != INVALID_HANDLE_VALUE) + { + do + { + AllFiles.push_back(FindFileData.cFileName); + } while (FindNextFile(hFind, &FindFileData)); + FindClose(hFind); + } + + #else // _WIN32 + + DIR * dp; + struct dirent *dirp; + if (*a_Directory == 0) + { + a_Directory = "."; + } + if ((dp = opendir(a_Directory)) == NULL) + { + LOGERROR("Error (%i) opening directory \"%s\"\n", errno, a_Directory ); + } + else + { + while ((dirp = readdir(dp)) != NULL) + { + AllFiles.push_back(dirp->d_name); + } + closedir(dp); + } + + #endif // else _WIN32 + + return AllFiles; +} + + + + diff --git a/source/StringUtils.h b/source/StringUtils.h index be0b02445..fee71481e 100644 --- a/source/StringUtils.h +++ b/source/StringUtils.h @@ -1,62 +1,62 @@ -
-// StringUtils.h
-
-// Interfaces to various string helper functions
-
-
-
-
-#ifndef STRINGUTILS_H_INCLUDED
-#define STRINGUTILS_H_INCLUDED
-
-
-
-
-
-typedef std::string AString;
-typedef std::vector<AString> AStringVector;
-typedef std::list<AString> AStringList;
-
-
-
-
-
-/// Add the formated string to the existing data in the string
-extern AString & AppendVPrintf(AString & str, const char * format, va_list args);
-
-/// Output the formatted text into the string
-extern AString & Printf (AString & str, const char * format, ...);
-
-/// Add the formatted string to the existing data in the string
-extern AString & AppendPrintf (AString & str, const char * format, ...);
-
-/// Split the string at delimiters, return as a stringvector
-extern AStringVector StringSplit(const AString & str, const AString & delim);
-
-/// Trime whitespace at both ends of the string
-extern AString TrimString(const AString & str);
-
-/// In-place string conversion to uppercase; returns the same string
-extern AString & StrToUpper(AString & s);
-
-/// Case-insensitive string comparison; returns 0 if the strings are the same
-extern int NoCaseCompare(const AString & s1, const AString & s2);
-
-/// Replaces *each* occurence of iNeedle in iHayStack with iReplaceWith
-extern void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & iReplaceWith);
-
-/// Returns the list of all items in the specified directory (files, folders, nix pipes, whatever's there)
-extern AStringList GetDirectoryContents(const char * a_Directory);
-
-
-
-// If you have any other string helper functions, declare them here
-
-
-
-
-#endif // STRINGUTILS_H_INCLUDED
-
-
-
-
+ +// StringUtils.h + +// Interfaces to various string helper functions + + + + +#ifndef STRINGUTILS_H_INCLUDED +#define STRINGUTILS_H_INCLUDED + + + + + +typedef std::string AString; +typedef std::vector<AString> AStringVector; +typedef std::list<AString> AStringList; + + + + + +/// Add the formated string to the existing data in the string +extern AString & AppendVPrintf(AString & str, const char * format, va_list args); + +/// Output the formatted text into the string +extern AString & Printf (AString & str, const char * format, ...); + +/// Add the formatted string to the existing data in the string +extern AString & AppendPrintf (AString & str, const char * format, ...); + +/// Split the string at delimiters, return as a stringvector +extern AStringVector StringSplit(const AString & str, const AString & delim); + +/// Trime whitespace at both ends of the string +extern AString TrimString(const AString & str); + +/// In-place string conversion to uppercase; returns the same string +extern AString & StrToUpper(AString & s); + +/// Case-insensitive string comparison; returns 0 if the strings are the same +extern int NoCaseCompare(const AString & s1, const AString & s2); + +/// Replaces *each* occurence of iNeedle in iHayStack with iReplaceWith +extern void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & iReplaceWith); + +/// Returns the list of all items in the specified directory (files, folders, nix pipes, whatever's there) +extern AStringList GetDirectoryContents(const char * a_Directory); + + + +// If you have any other string helper functions, declare them here + + + + +#endif // STRINGUTILS_H_INCLUDED + + + + diff --git a/source/StructGen.cpp b/source/StructGen.cpp index 5f1d9da74..aa3632204 100644 --- a/source/StructGen.cpp +++ b/source/StructGen.cpp @@ -1,464 +1,464 @@ -
-// StructGen.h
-
-#include "Globals.h"
-#include "StructGen.h"
-#include "BlockID.h"
-#include "Trees.h"
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cStructGenOreNests configuration:
-
-const int MAX_HEIGHT_COAL = 127;
-const int NUM_NESTS_COAL = 60;
-const int NEST_SIZE_COAL = 10;
-
-const int MAX_HEIGHT_IRON = 70;
-const int NUM_NESTS_IRON = 30;
-const int NEST_SIZE_IRON = 6;
-
-const int MAX_HEIGHT_REDSTONE = 40;
-const int NUM_NESTS_REDSTONE = 10;
-const int NEST_SIZE_REDSTONE = 6;
-
-const int MAX_HEIGHT_GOLD = 35;
-const int NUM_NESTS_GOLD = 6;
-const int NEST_SIZE_GOLD = 6;
-
-const int MAX_HEIGHT_DIAMOND = 16;
-const int NUM_NESTS_DIAMOND = 6;
-const int NEST_SIZE_DIAMOND = 5;
-
-const int MAX_HEIGHT_LAPIS = 30;
-const int NUM_NESTS_LAPIS = 6;
-const int NEST_SIZE_LAPIS = 5;
-
-
-
-
-
-template <typename T> T Clamp(T a_Value, T a_Min, T a_Max)
-{
- return (a_Value < a_Min) ? a_Min : ((a_Value > a_Max) ? a_Max : a_Value);
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cStructGenTrees:
-
-void cStructGenTrees::GenStructures(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMetas, // Block meta to read and change
- cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
- cEntityList & a_Entities, // Entities may be added or deleted
- cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
-)
-{
- cChunkDef::BlockTypes WorkerBlockTypes;
- cChunkDef::BlockNibbles WorkerBlockMeta;
- cChunkDef::HeightMap WorkerHeight;
-
- cEntityList Entities;
- cBlockEntityList BlockEntities;
-
- // Generate trees:
- for (int x = 0; x <= 2; x++)
- {
- int BaseX = a_ChunkX + x - 1;
- for (int z = 0; z <= 2; z++)
- {
- int BaseZ = a_ChunkZ + z - 1;
- sSetBlockVector Outside;
-
- cChunkDef::BlockTypes * BlT;
- cChunkDef::BlockNibbles * BlM;
- cChunkDef::HeightMap * Hei;
-
- cChunkDef::BiomeMap Biomes;
- m_BiomeGen->GenBiomes(BaseX, BaseZ, Biomes);
-
- if ((x != 1) || (z != 1))
- {
- BlT = &WorkerBlockTypes;
- BlM = &WorkerBlockMeta;
- Hei = &WorkerHeight;
-
- m_HeightGen->GenHeightMap (BaseX, BaseZ, *Hei);
- m_CompositionGen->ComposeTerrain(BaseX, BaseZ, *BlT, *BlM, *Hei, Biomes, Entities, BlockEntities);
- // TODO: Free the entity lists
- }
- else
- {
- BlT = &a_BlockTypes;
- BlM = &a_BlockMetas;
- Hei = &a_HeightMap;
- }
-
- int NumTrees = GetNumTrees(BaseX, BaseZ, Biomes);
-
- for (int i = 0; i < NumTrees; i++)
- {
- GenerateSingleTree(BaseX, BaseZ, i, *BlT, *BlM, *Hei, Biomes, Outside);
- }
-
- // Integrate blocks in Outside into chunk:
- for (sSetBlockVector::const_iterator itr = Outside.begin(); itr != Outside.end(); ++itr)
- {
- if ((itr->ChunkX != a_ChunkX) || (itr->ChunkZ != a_ChunkZ))
- {
- continue;
- }
- switch (cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z))
- {
- CASE_TREE_OVERWRITTEN_BLOCKS:
- {
- cChunkDef::SetBlock (a_BlockTypes, itr->x, itr->y, itr->z, itr->BlockType);
- cChunkDef::SetNibble(a_BlockMetas, itr->x, itr->y, itr->z, itr->BlockMeta);
- break;
- }
- } // switch (GetBlock())
- } // for itr - Outside[]
- } // for z
- } // for x
-
- // Update the heightmap:
- for (int x = 0; x < cChunkDef::Width; x++)
- {
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- for (int y = cChunkDef::Height - 1; y >= 0; y--)
- {
- if (cChunkDef::GetBlock(a_BlockTypes, x, y, z) != E_BLOCK_AIR)
- {
- cChunkDef::SetHeight(a_HeightMap, x, z, y);
- break;
- }
- } // for y
- } // for z
- } // for x
-}
-
-
-
-
-
-void cStructGenTrees::GenerateSingleTree(
- int a_ChunkX, int a_ChunkZ, int a_Seq,
- cChunkDef::BlockTypes & a_BlockTypes,
- cChunkDef::BlockNibbles & a_BlockMetas,
- const cChunkDef::HeightMap & a_Height,
- const cChunkDef::BiomeMap & a_Biomes,
- sSetBlockVector & a_Blocks
-)
-{
- int x = m_Noise.IntNoise3DInt(a_ChunkX + a_ChunkZ, a_ChunkZ, a_Seq) % cChunkDef::Width;
- int z = m_Noise.IntNoise3DInt(a_ChunkX - a_ChunkZ, a_Seq, a_ChunkZ) % cChunkDef::Width;
-
- int Height = a_Height[x + cChunkDef::Width * z];
-
- if ((Height <= 0) || (Height > 240))
- {
- return;
- }
-
- // Check the block underneath the tree:
- BLOCKTYPE TopBlock = cChunkDef::GetBlock(a_BlockTypes, x, Height, z);
- if ((TopBlock != E_BLOCK_DIRT) && (TopBlock != E_BLOCK_GRASS) && (TopBlock != E_BLOCK_SOIL))
- {
- return;
- }
-
- sSetBlockVector TreeBlocks;
- GetTreeImageByBiome(a_ChunkX * cChunkDef::Width + x, Height + 1, a_ChunkZ * cChunkDef::Width + z, m_Noise, a_Seq, a_Biomes[x + cChunkDef::Width * z], TreeBlocks);
-
- // Check if the generated image fits the terrain:
- for (sSetBlockVector::const_iterator itr = TreeBlocks.begin(); itr != TreeBlocks.end(); ++itr)
- {
- if ((itr->ChunkX != a_ChunkX) || (itr->ChunkZ != a_ChunkZ) || (itr->BlockType != E_BLOCK_LOG))
- {
- // Outside the chunk, or not a log (we don't check non-logs)
- continue;
- }
-
- BLOCKTYPE Block = cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z);
- switch (Block)
- {
- CASE_TREE_ALLOWED_BLOCKS:
- {
- break;
- }
- default:
- {
- // There's something in the way, abort this tree altogether
- return;
- }
- }
- }
-
- // Put the generated image into a_BlockTypes, push things outside this chunk into a_Blocks
- for (sSetBlockVector::const_iterator itr = TreeBlocks.begin(); itr != TreeBlocks.end(); ++itr)
- {
- if ((itr->ChunkX == a_ChunkX) && (itr->ChunkZ == a_ChunkZ))
- {
- // Inside this chunk, integrate into a_BlockTypes:
- switch (cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z))
- {
- CASE_TREE_OVERWRITTEN_BLOCKS:
- {
- cChunkDef::SetBlock (a_BlockTypes, itr->x, itr->y, itr->z, itr->BlockType);
- cChunkDef::SetNibble(a_BlockMetas, itr->x, itr->y, itr->z, itr->BlockMeta);
- break;
- }
- } // switch (GetBlock())
- continue;
- }
-
- // Outside the chunk, push into a_Blocks; check if already present there:
- bool Found = false;
- for (sSetBlockVector::iterator itrB = a_Blocks.begin(); itrB != a_Blocks.end(); ++itrB)
- {
- if (
- (itr->ChunkX == itrB->ChunkX) &&
- (itr->ChunkZ == itrB->ChunkZ) &&
- (itr->x == itrB->x) &&
- (itr->y == itrB->y) &&
- (itr->z == itrB->z)
- )
- {
- // Same coords already found in a_Blocks, overwrite with wood, if requested:
- if (itr->BlockType == E_BLOCK_LOG)
- {
- itrB->BlockType = itr->BlockType;
- itrB->BlockMeta = itr->BlockMeta;
- }
- Found = true;
- break;
- }
- } // for itrB - a_Blocks[]
- if (!Found)
- {
- a_Blocks.push_back(*itr);
- }
- }
-}
-
-
-
-
-
-int cStructGenTrees::GetNumTrees(
- int a_ChunkX, int a_ChunkZ,
- const cChunkDef::BiomeMap & a_Biomes
-)
-{
- int NumTrees = 0;
- for (int x = 0; x < cChunkDef::Width; x++) for (int z = 0; z < cChunkDef::Width; z++)
- {
- int Add = 0;
- switch (a_Biomes[x + cChunkDef::Width * z])
- {
- case biPlains: Add = 1; break;
- case biExtremeHills: Add = 3; break;
- case biForest: Add = 30; break;
- case biTaiga: Add = 30; break;
- case biSwampland: Add = 8; break;
- case biIcePlains: Add = 1; break;
- case biIceMountains: Add = 1; break;
- case biMushroomIsland: Add = 3; break;
- case biMushroomShore: Add = 3; break;
- case biForestHills: Add = 20; break;
- case biTaigaHills: Add = 20; break;
- case biExtremeHillsEdge: Add = 5; break;
- case biJungle: Add = 120; break;
- case biJungleHills: Add = 90; break;
- }
- NumTrees += Add;
- }
- return NumTrees / 1024;
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cStructGenMarbleCaves:
-
-static float GetMarbleNoise( float x, float y, float z, cNoise & a_Noise )
-{
- static const float PI_2 = 1.57079633f;
- float oct1 = (a_Noise.CubicNoise3D(x * 0.1f, y * 0.1f, z * 0.1f )) * 4;
-
- oct1 = oct1 * oct1 * oct1;
- if (oct1 < 0.f) oct1 = PI_2;
- if (oct1 > PI_2) oct1 = PI_2;
-
- return oct1;
-}
-
-
-
-
-
-void cStructGenMarbleCaves::GenStructures(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change
- cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
- cEntityList & a_Entities, // Entities may be added or deleted
- cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
-)
-{
- cNoise Noise(m_Seed);
- for (int z = 0; z < cChunkDef::Width; z++)
- {
- const float zz = (float)(a_ChunkZ * cChunkDef::Width + z);
- for (int x = 0; x < cChunkDef::Width; x++)
- {
- const float xx = (float)(a_ChunkX * cChunkDef::Width + x);
-
- int Top = cChunkDef::GetHeight(a_HeightMap, x, z);
- for (int y = 1; y < Top; ++y )
- {
- if (cChunkDef::GetBlock(a_BlockTypes, x, y, z) != E_BLOCK_STONE)
- {
- continue;
- }
-
- const float yy = (float)y;
- const float WaveNoise = 1;
- if (cosf(GetMarbleNoise(xx, yy * 0.5f, zz, Noise)) * fabs(cosf(yy * 0.2f + WaveNoise * 2) * 0.75f + WaveNoise) > 0.0005f)
- {
- if (y > 4)
- {
- cChunkDef::SetBlock(a_BlockTypes, x, y, z, E_BLOCK_AIR);
- }
- else
- {
- cChunkDef::SetBlock(a_BlockTypes, x, y, z, E_BLOCK_STATIONARY_LAVA);
- }
- }
- } // for y
- } // for x
- } // for z
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cStructGenOreNests:
-
-void cStructGenOreNests::GenStructures(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change
- cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
- cEntityList & a_Entities, // Entities may be added or deleted
- cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
-)
-{
- GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_COAL_ORE, MAX_HEIGHT_COAL, NUM_NESTS_COAL, NEST_SIZE_COAL, a_BlockTypes, 1);
- GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_IRON_ORE, MAX_HEIGHT_IRON, NUM_NESTS_IRON, NEST_SIZE_IRON, a_BlockTypes, 2);
- GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_REDSTONE_ORE, MAX_HEIGHT_REDSTONE, NUM_NESTS_REDSTONE, NEST_SIZE_REDSTONE, a_BlockTypes, 3);
- GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_GOLD_ORE, MAX_HEIGHT_GOLD, NUM_NESTS_GOLD, NEST_SIZE_GOLD, a_BlockTypes, 4);
- GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_DIAMOND_ORE, MAX_HEIGHT_DIAMOND, NUM_NESTS_DIAMOND, NEST_SIZE_DIAMOND, a_BlockTypes, 5);
- GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_LAPIS_ORE, MAX_HEIGHT_LAPIS, NUM_NESTS_LAPIS, NEST_SIZE_LAPIS, a_BlockTypes, 6);
-}
-
-
-
-
-
-void cStructGenOreNests::GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, int a_Seq)
-{
- // This function generates several "nests" of ore, each nest consisting of number of ore blocks relatively adjacent to each other.
- // It does so by making a random XYZ walk and adding ore along the way in cuboids of different (random) sizes
- // Only stone gets replaced with ore, all other blocks stay (so the nest can actually be smaller than specified).
-
- for (int i = 0; i < a_NumNests; i++)
- {
- int rnd = m_Noise.IntNoise3DInt(a_ChunkX + i, a_Seq, a_ChunkZ + 64 * i) / 8;
- int BaseX = rnd % cChunkDef::Width;
- rnd /= cChunkDef::Width;
- int BaseZ = rnd % cChunkDef::Width;
- rnd /= cChunkDef::Width;
- int BaseY = rnd % a_MaxHeight;
- rnd /= a_MaxHeight;
- int NestSize = a_NestSize + (rnd % (a_NestSize / 4)); // The actual nest size may be up to 1/4 larger
- int Num = 0;
- while (Num < NestSize)
- {
- // Put a cuboid around [BaseX, BaseY, BaseZ]
- int rnd = m_Noise.IntNoise3DInt(a_ChunkX + 64 * i, 2 * a_Seq + Num, a_ChunkZ + 32 * i) / 8;
- int xsize = rnd % 2;
- int ysize = (rnd / 4) % 2;
- int zsize = (rnd / 16) % 2;
- rnd >>= 8;
- for (int x = xsize; x >= 0; --x)
- {
- int BlockX = BaseX + x;
- if ((BlockX < 0) || (BlockX >= cChunkDef::Width))
- {
- Num++; // So that the cycle finishes even if the base coords wander away from the chunk
- continue;
- }
- for (int y = ysize; y >= 0; --y)
- {
- int BlockY = BaseY + y;
- if ((BlockY < 0) || (BlockY >= cChunkDef::Height))
- {
- Num++; // So that the cycle finishes even if the base coords wander away from the chunk
- continue;
- }
- for (int z = zsize; z >= 0; --z)
- {
- int BlockZ = BaseZ + z;
- if ((BlockZ < 0) || (BlockZ >= cChunkDef::Width))
- {
- Num++; // So that the cycle finishes even if the base coords wander away from the chunk
- continue;
- }
-
- int Index = cChunkDef::MakeIndexNoCheck(BlockX, BlockY, BlockZ);
- if (a_BlockTypes[Index] == E_BLOCK_STONE)
- {
- a_BlockTypes[Index] = a_OreType;
- }
- Num++;
- } // for z
- } // for y
- } // for x
-
- // Move the base to a neighbor voxel
- switch (rnd % 4)
- {
- case 0: BaseX--; break;
- case 1: BaseX++; break;
- }
- switch ((rnd >> 3) % 4)
- {
- case 0: BaseY--; break;
- case 1: BaseY++; break;
- }
- switch ((rnd >> 6) % 4)
- {
- case 0: BaseZ--; break;
- case 1: BaseZ++; break;
- }
- } // while (Num < NumBlocks)
- } // for i - NumNests
-}
-
-
-
-
+ +// StructGen.h + +#include "Globals.h" +#include "StructGen.h" +#include "BlockID.h" +#include "Trees.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cStructGenOreNests configuration: + +const int MAX_HEIGHT_COAL = 127; +const int NUM_NESTS_COAL = 60; +const int NEST_SIZE_COAL = 10; + +const int MAX_HEIGHT_IRON = 70; +const int NUM_NESTS_IRON = 30; +const int NEST_SIZE_IRON = 6; + +const int MAX_HEIGHT_REDSTONE = 40; +const int NUM_NESTS_REDSTONE = 10; +const int NEST_SIZE_REDSTONE = 6; + +const int MAX_HEIGHT_GOLD = 35; +const int NUM_NESTS_GOLD = 6; +const int NEST_SIZE_GOLD = 6; + +const int MAX_HEIGHT_DIAMOND = 16; +const int NUM_NESTS_DIAMOND = 6; +const int NEST_SIZE_DIAMOND = 5; + +const int MAX_HEIGHT_LAPIS = 30; +const int NUM_NESTS_LAPIS = 6; +const int NEST_SIZE_LAPIS = 5; + + + + + +template <typename T> T Clamp(T a_Value, T a_Min, T a_Max) +{ + return (a_Value < a_Min) ? a_Min : ((a_Value > a_Max) ? a_Max : a_Value); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cStructGenTrees: + +void cStructGenTrees::GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMetas, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted +) +{ + cChunkDef::BlockTypes WorkerBlockTypes; + cChunkDef::BlockNibbles WorkerBlockMeta; + cChunkDef::HeightMap WorkerHeight; + + cEntityList Entities; + cBlockEntityList BlockEntities; + + // Generate trees: + for (int x = 0; x <= 2; x++) + { + int BaseX = a_ChunkX + x - 1; + for (int z = 0; z <= 2; z++) + { + int BaseZ = a_ChunkZ + z - 1; + sSetBlockVector Outside; + + cChunkDef::BlockTypes * BlT; + cChunkDef::BlockNibbles * BlM; + cChunkDef::HeightMap * Hei; + + cChunkDef::BiomeMap Biomes; + m_BiomeGen->GenBiomes(BaseX, BaseZ, Biomes); + + if ((x != 1) || (z != 1)) + { + BlT = &WorkerBlockTypes; + BlM = &WorkerBlockMeta; + Hei = &WorkerHeight; + + m_HeightGen->GenHeightMap (BaseX, BaseZ, *Hei); + m_CompositionGen->ComposeTerrain(BaseX, BaseZ, *BlT, *BlM, *Hei, Biomes, Entities, BlockEntities); + // TODO: Free the entity lists + } + else + { + BlT = &a_BlockTypes; + BlM = &a_BlockMetas; + Hei = &a_HeightMap; + } + + int NumTrees = GetNumTrees(BaseX, BaseZ, Biomes); + + for (int i = 0; i < NumTrees; i++) + { + GenerateSingleTree(BaseX, BaseZ, i, *BlT, *BlM, *Hei, Biomes, Outside); + } + + // Integrate blocks in Outside into chunk: + for (sSetBlockVector::const_iterator itr = Outside.begin(); itr != Outside.end(); ++itr) + { + if ((itr->ChunkX != a_ChunkX) || (itr->ChunkZ != a_ChunkZ)) + { + continue; + } + switch (cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z)) + { + CASE_TREE_OVERWRITTEN_BLOCKS: + { + cChunkDef::SetBlock (a_BlockTypes, itr->x, itr->y, itr->z, itr->BlockType); + cChunkDef::SetNibble(a_BlockMetas, itr->x, itr->y, itr->z, itr->BlockMeta); + break; + } + } // switch (GetBlock()) + } // for itr - Outside[] + } // for z + } // for x + + // Update the heightmap: + for (int x = 0; x < cChunkDef::Width; x++) + { + for (int z = 0; z < cChunkDef::Width; z++) + { + for (int y = cChunkDef::Height - 1; y >= 0; y--) + { + if (cChunkDef::GetBlock(a_BlockTypes, x, y, z) != E_BLOCK_AIR) + { + cChunkDef::SetHeight(a_HeightMap, x, z, y); + break; + } + } // for y + } // for z + } // for x +} + + + + + +void cStructGenTrees::GenerateSingleTree( + int a_ChunkX, int a_ChunkZ, int a_Seq, + cChunkDef::BlockTypes & a_BlockTypes, + cChunkDef::BlockNibbles & a_BlockMetas, + const cChunkDef::HeightMap & a_Height, + const cChunkDef::BiomeMap & a_Biomes, + sSetBlockVector & a_Blocks +) +{ + int x = m_Noise.IntNoise3DInt(a_ChunkX + a_ChunkZ, a_ChunkZ, a_Seq) % cChunkDef::Width; + int z = m_Noise.IntNoise3DInt(a_ChunkX - a_ChunkZ, a_Seq, a_ChunkZ) % cChunkDef::Width; + + int Height = a_Height[x + cChunkDef::Width * z]; + + if ((Height <= 0) || (Height > 240)) + { + return; + } + + // Check the block underneath the tree: + BLOCKTYPE TopBlock = cChunkDef::GetBlock(a_BlockTypes, x, Height, z); + if ((TopBlock != E_BLOCK_DIRT) && (TopBlock != E_BLOCK_GRASS) && (TopBlock != E_BLOCK_SOIL)) + { + return; + } + + sSetBlockVector TreeBlocks; + GetTreeImageByBiome(a_ChunkX * cChunkDef::Width + x, Height + 1, a_ChunkZ * cChunkDef::Width + z, m_Noise, a_Seq, a_Biomes[x + cChunkDef::Width * z], TreeBlocks); + + // Check if the generated image fits the terrain: + for (sSetBlockVector::const_iterator itr = TreeBlocks.begin(); itr != TreeBlocks.end(); ++itr) + { + if ((itr->ChunkX != a_ChunkX) || (itr->ChunkZ != a_ChunkZ) || (itr->BlockType != E_BLOCK_LOG)) + { + // Outside the chunk, or not a log (we don't check non-logs) + continue; + } + + BLOCKTYPE Block = cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z); + switch (Block) + { + CASE_TREE_ALLOWED_BLOCKS: + { + break; + } + default: + { + // There's something in the way, abort this tree altogether + return; + } + } + } + + // Put the generated image into a_BlockTypes, push things outside this chunk into a_Blocks + for (sSetBlockVector::const_iterator itr = TreeBlocks.begin(); itr != TreeBlocks.end(); ++itr) + { + if ((itr->ChunkX == a_ChunkX) && (itr->ChunkZ == a_ChunkZ)) + { + // Inside this chunk, integrate into a_BlockTypes: + switch (cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z)) + { + CASE_TREE_OVERWRITTEN_BLOCKS: + { + cChunkDef::SetBlock (a_BlockTypes, itr->x, itr->y, itr->z, itr->BlockType); + cChunkDef::SetNibble(a_BlockMetas, itr->x, itr->y, itr->z, itr->BlockMeta); + break; + } + } // switch (GetBlock()) + continue; + } + + // Outside the chunk, push into a_Blocks; check if already present there: + bool Found = false; + for (sSetBlockVector::iterator itrB = a_Blocks.begin(); itrB != a_Blocks.end(); ++itrB) + { + if ( + (itr->ChunkX == itrB->ChunkX) && + (itr->ChunkZ == itrB->ChunkZ) && + (itr->x == itrB->x) && + (itr->y == itrB->y) && + (itr->z == itrB->z) + ) + { + // Same coords already found in a_Blocks, overwrite with wood, if requested: + if (itr->BlockType == E_BLOCK_LOG) + { + itrB->BlockType = itr->BlockType; + itrB->BlockMeta = itr->BlockMeta; + } + Found = true; + break; + } + } // for itrB - a_Blocks[] + if (!Found) + { + a_Blocks.push_back(*itr); + } + } +} + + + + + +int cStructGenTrees::GetNumTrees( + int a_ChunkX, int a_ChunkZ, + const cChunkDef::BiomeMap & a_Biomes +) +{ + int NumTrees = 0; + for (int x = 0; x < cChunkDef::Width; x++) for (int z = 0; z < cChunkDef::Width; z++) + { + int Add = 0; + switch (a_Biomes[x + cChunkDef::Width * z]) + { + case biPlains: Add = 1; break; + case biExtremeHills: Add = 3; break; + case biForest: Add = 30; break; + case biTaiga: Add = 30; break; + case biSwampland: Add = 8; break; + case biIcePlains: Add = 1; break; + case biIceMountains: Add = 1; break; + case biMushroomIsland: Add = 3; break; + case biMushroomShore: Add = 3; break; + case biForestHills: Add = 20; break; + case biTaigaHills: Add = 20; break; + case biExtremeHillsEdge: Add = 5; break; + case biJungle: Add = 120; break; + case biJungleHills: Add = 90; break; + } + NumTrees += Add; + } + return NumTrees / 1024; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cStructGenMarbleCaves: + +static float GetMarbleNoise( float x, float y, float z, cNoise & a_Noise ) +{ + static const float PI_2 = 1.57079633f; + float oct1 = (a_Noise.CubicNoise3D(x * 0.1f, y * 0.1f, z * 0.1f )) * 4; + + oct1 = oct1 * oct1 * oct1; + if (oct1 < 0.f) oct1 = PI_2; + if (oct1 > PI_2) oct1 = PI_2; + + return oct1; +} + + + + + +void cStructGenMarbleCaves::GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted +) +{ + cNoise Noise(m_Seed); + for (int z = 0; z < cChunkDef::Width; z++) + { + const float zz = (float)(a_ChunkZ * cChunkDef::Width + z); + for (int x = 0; x < cChunkDef::Width; x++) + { + const float xx = (float)(a_ChunkX * cChunkDef::Width + x); + + int Top = cChunkDef::GetHeight(a_HeightMap, x, z); + for (int y = 1; y < Top; ++y ) + { + if (cChunkDef::GetBlock(a_BlockTypes, x, y, z) != E_BLOCK_STONE) + { + continue; + } + + const float yy = (float)y; + const float WaveNoise = 1; + if (cosf(GetMarbleNoise(xx, yy * 0.5f, zz, Noise)) * fabs(cosf(yy * 0.2f + WaveNoise * 2) * 0.75f + WaveNoise) > 0.0005f) + { + if (y > 4) + { + cChunkDef::SetBlock(a_BlockTypes, x, y, z, E_BLOCK_AIR); + } + else + { + cChunkDef::SetBlock(a_BlockTypes, x, y, z, E_BLOCK_STATIONARY_LAVA); + } + } + } // for y + } // for x + } // for z +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cStructGenOreNests: + +void cStructGenOreNests::GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted +) +{ + GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_COAL_ORE, MAX_HEIGHT_COAL, NUM_NESTS_COAL, NEST_SIZE_COAL, a_BlockTypes, 1); + GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_IRON_ORE, MAX_HEIGHT_IRON, NUM_NESTS_IRON, NEST_SIZE_IRON, a_BlockTypes, 2); + GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_REDSTONE_ORE, MAX_HEIGHT_REDSTONE, NUM_NESTS_REDSTONE, NEST_SIZE_REDSTONE, a_BlockTypes, 3); + GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_GOLD_ORE, MAX_HEIGHT_GOLD, NUM_NESTS_GOLD, NEST_SIZE_GOLD, a_BlockTypes, 4); + GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_DIAMOND_ORE, MAX_HEIGHT_DIAMOND, NUM_NESTS_DIAMOND, NEST_SIZE_DIAMOND, a_BlockTypes, 5); + GenerateOre(a_ChunkX, a_ChunkZ, E_BLOCK_LAPIS_ORE, MAX_HEIGHT_LAPIS, NUM_NESTS_LAPIS, NEST_SIZE_LAPIS, a_BlockTypes, 6); +} + + + + + +void cStructGenOreNests::GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, int a_Seq) +{ + // This function generates several "nests" of ore, each nest consisting of number of ore blocks relatively adjacent to each other. + // It does so by making a random XYZ walk and adding ore along the way in cuboids of different (random) sizes + // Only stone gets replaced with ore, all other blocks stay (so the nest can actually be smaller than specified). + + for (int i = 0; i < a_NumNests; i++) + { + int rnd = m_Noise.IntNoise3DInt(a_ChunkX + i, a_Seq, a_ChunkZ + 64 * i) / 8; + int BaseX = rnd % cChunkDef::Width; + rnd /= cChunkDef::Width; + int BaseZ = rnd % cChunkDef::Width; + rnd /= cChunkDef::Width; + int BaseY = rnd % a_MaxHeight; + rnd /= a_MaxHeight; + int NestSize = a_NestSize + (rnd % (a_NestSize / 4)); // The actual nest size may be up to 1/4 larger + int Num = 0; + while (Num < NestSize) + { + // Put a cuboid around [BaseX, BaseY, BaseZ] + int rnd = m_Noise.IntNoise3DInt(a_ChunkX + 64 * i, 2 * a_Seq + Num, a_ChunkZ + 32 * i) / 8; + int xsize = rnd % 2; + int ysize = (rnd / 4) % 2; + int zsize = (rnd / 16) % 2; + rnd >>= 8; + for (int x = xsize; x >= 0; --x) + { + int BlockX = BaseX + x; + if ((BlockX < 0) || (BlockX >= cChunkDef::Width)) + { + Num++; // So that the cycle finishes even if the base coords wander away from the chunk + continue; + } + for (int y = ysize; y >= 0; --y) + { + int BlockY = BaseY + y; + if ((BlockY < 0) || (BlockY >= cChunkDef::Height)) + { + Num++; // So that the cycle finishes even if the base coords wander away from the chunk + continue; + } + for (int z = zsize; z >= 0; --z) + { + int BlockZ = BaseZ + z; + if ((BlockZ < 0) || (BlockZ >= cChunkDef::Width)) + { + Num++; // So that the cycle finishes even if the base coords wander away from the chunk + continue; + } + + int Index = cChunkDef::MakeIndexNoCheck(BlockX, BlockY, BlockZ); + if (a_BlockTypes[Index] == E_BLOCK_STONE) + { + a_BlockTypes[Index] = a_OreType; + } + Num++; + } // for z + } // for y + } // for x + + // Move the base to a neighbor voxel + switch (rnd % 4) + { + case 0: BaseX--; break; + case 1: BaseX++; break; + } + switch ((rnd >> 3) % 4) + { + case 0: BaseY--; break; + case 1: BaseY++; break; + } + switch ((rnd >> 6) % 4) + { + case 0: BaseZ--; break; + case 1: BaseZ++; break; + } + } // while (Num < NumBlocks) + } // for i - NumNests +} + + + + diff --git a/source/StructGen.h b/source/StructGen.h index 3f5c2e2a2..8b799d013 100644 --- a/source/StructGen.h +++ b/source/StructGen.h @@ -1,122 +1,122 @@ -
-// StructGen.h
-
-/* Interfaces to the various structure generators:
- - cStructGenTrees
- - cStructGenMarbleCaves
- - cStructGenOres
-*/
-
-
-
-
-
-#pragma once
-
-#include "cChunkGenerator.h"
-#include "cNoise.h"
-
-
-
-
-
-class cStructGenTrees :
- public cStructureGen
-{
-public:
- cStructGenTrees(int a_Seed, cBiomeGen * a_BiomeGen, cTerrainHeightGen * a_HeightGen, cTerrainCompositionGen * a_CompositionGen) :
- m_Seed(a_Seed),
- m_Noise(a_Seed),
- m_BiomeGen(a_BiomeGen),
- m_HeightGen(a_HeightGen),
- m_CompositionGen(a_CompositionGen)
- {}
-
-protected:
-
- int m_Seed;
- cNoise m_Noise;
- cBiomeGen * m_BiomeGen;
- cTerrainHeightGen * m_HeightGen;
- cTerrainCompositionGen * m_CompositionGen;
-
- void GenerateSingleTree(
- int a_ChunkX, int a_ChunkZ, int a_Seq,
- cChunkDef::BlockTypes & a_BlockTypes,
- cChunkDef::BlockNibbles & a_BlockMetas,
- const cChunkDef::HeightMap & a_Height,
- const cChunkDef::BiomeMap & a_Biomes,
- sSetBlockVector & a_Blocks
- ) ;
-
- int GetNumTrees(
- int a_ChunkX, int a_ChunkZ,
- const cChunkDef::BiomeMap & a_Biomes
- );
-
- // cStructureGen override:
- virtual void GenStructures(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMetas, // Block meta to read and change
- cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
- cEntityList & a_Entities, // Entities may be added or deleted
- cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
- ) override;
-} ;
-
-
-
-
-
-class cStructGenMarbleCaves :
- public cStructureGen
-{
-public:
- cStructGenMarbleCaves(int a_Seed) : m_Seed(a_Seed) {}
-
-protected:
-
- int m_Seed;
-
- // cStructureGen override:
- virtual void GenStructures(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change
- cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
- cEntityList & a_Entities, // Entities may be added or deleted
- cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
- ) override;
-} ;
-
-
-
-
-
-class cStructGenOreNests :
- public cStructureGen
-{
-public:
- cStructGenOreNests(int a_Seed) : m_Noise(a_Seed), m_Seed(a_Seed) {}
-
-protected:
- cNoise m_Noise;
- int m_Seed;
-
- // cStructureGen override:
- virtual void GenStructures(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change
- cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
- cEntityList & a_Entities, // Entities may be added or deleted
- cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
- ) override;
-
- void GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, int a_Seq);
-} ;
-
-
-
-
+ +// StructGen.h + +/* Interfaces to the various structure generators: + - cStructGenTrees + - cStructGenMarbleCaves + - cStructGenOres +*/ + + + + + +#pragma once + +#include "cChunkGenerator.h" +#include "cNoise.h" + + + + + +class cStructGenTrees : + public cStructureGen +{ +public: + cStructGenTrees(int a_Seed, cBiomeGen * a_BiomeGen, cTerrainHeightGen * a_HeightGen, cTerrainCompositionGen * a_CompositionGen) : + m_Seed(a_Seed), + m_Noise(a_Seed), + m_BiomeGen(a_BiomeGen), + m_HeightGen(a_HeightGen), + m_CompositionGen(a_CompositionGen) + {} + +protected: + + int m_Seed; + cNoise m_Noise; + cBiomeGen * m_BiomeGen; + cTerrainHeightGen * m_HeightGen; + cTerrainCompositionGen * m_CompositionGen; + + void GenerateSingleTree( + int a_ChunkX, int a_ChunkZ, int a_Seq, + cChunkDef::BlockTypes & a_BlockTypes, + cChunkDef::BlockNibbles & a_BlockMetas, + const cChunkDef::HeightMap & a_Height, + const cChunkDef::BiomeMap & a_Biomes, + sSetBlockVector & a_Blocks + ) ; + + int GetNumTrees( + int a_ChunkX, int a_ChunkZ, + const cChunkDef::BiomeMap & a_Biomes + ); + + // cStructureGen override: + virtual void GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMetas, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) override; +} ; + + + + + +class cStructGenMarbleCaves : + public cStructureGen +{ +public: + cStructGenMarbleCaves(int a_Seed) : m_Seed(a_Seed) {} + +protected: + + int m_Seed; + + // cStructureGen override: + virtual void GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) override; +} ; + + + + + +class cStructGenOreNests : + public cStructureGen +{ +public: + cStructGenOreNests(int a_Seed) : m_Noise(a_Seed), m_Seed(a_Seed) {} + +protected: + cNoise m_Noise; + int m_Seed; + + // cStructureGen override: + virtual void GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) override; + + void GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, int a_Seq); +} ; + + + + diff --git a/source/Trees.cpp b/source/Trees.cpp index 7d82c3ef9..f6734d85c 100644 --- a/source/Trees.cpp +++ b/source/Trees.cpp @@ -1,538 +1,538 @@ -
-// Trees.cpp
-
-// Implements helper functions used for generating trees
-
-#include "Globals.h"
-#include "Trees.h"
-#include "BlockID.h"
-
-
-
-
-
-typedef struct
-{
- int x, z;
-} sCoords;
-
-typedef struct
-{
- int x, z;
- NIBBLETYPE Meta;
-} sMetaCoords;
-
-static const sCoords Corners[] =
-{
- {-1, -1},
- {-1, 1},
- {1, -1},
- {1, 1},
-} ;
-
-static const sCoords BigO1[] =
-{
- {0, -1},
- {-1, 0}, {1, 0},
- {0, 1},
-} ;
-
-static const sCoords BigO2[] =
-{
- {-1, -2}, {0, -2}, {1, -2},
- {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1},
- {-2, 0}, {-1, 0}, {1, 0}, {2, 0},
- {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1},
- {-1, 2}, {0, 2}, {1, 2},
-} ;
-
-static const sCoords BigO3[] =
-{
- {-2, -3}, {-1, -3}, {0, -3}, {1, -3}, {2, -3},
- {-3, -2}, {-2, -2}, {-1, -2}, {0, -2}, {1, -2}, {2, -2}, {3, -2},
- {-3, -1}, {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1},
- {-3, 0}, {-2, 0}, {-1, 0}, {1, 0}, {2, 0}, {3, 0},
- {-3, 1}, {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, {3, 1},
- {-3, 2}, {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2},
- {-2, 3}, {-1, 3}, {0, 3}, {1, 3}, {2, 3},
-} ;
-
-typedef struct
-{
- const sCoords * Coords;
- size_t Count;
-} sCoordsArr;
-
-static const sCoordsArr BigOs[] =
-{
- {BigO1, ARRAYCOUNT(BigO1)},
- {BigO2, ARRAYCOUNT(BigO2)},
- {BigO3, ARRAYCOUNT(BigO3)},
-} ;
-
-
-
-
-
-/// Pushes a specified layer of blocks of the same type around (x, h, z) into a_Blocks
-inline void PushCoordBlocks(int a_BlockX, int a_Height, int a_BlockZ, sSetBlockVector & a_Blocks, const sCoords * a_Coords, size_t a_NumCoords, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
-{
- for (size_t i = 0; i < a_NumCoords; i++)
- {
- a_Blocks.push_back(sSetBlock(a_BlockX + a_Coords[i].x, a_Height, a_BlockZ + a_Coords[i].z, a_BlockType, a_Meta));
- }
-}
-
-
-
-
-inline void PushCornerBlocks(int a_BlockX, int a_Height, int a_BlockZ, int a_Seq, cNoise & a_Noise, int a_Chance, sSetBlockVector & a_Blocks, int a_CornersDist, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
-{
- for (size_t i = 0; i < ARRAYCOUNT(Corners); i++)
- {
- int x = a_BlockX + Corners[i].x;
- int z = a_BlockZ + Corners[i].z;
- if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height, z + 64 * a_Seq) <= a_Chance)
- {
- a_Blocks.push_back(sSetBlock(x, a_Height, z, a_BlockType, a_Meta));
- }
- } // for i - Corners[]
-}
-
-
-
-
-
-inline void PushSomeColumns(int a_BlockX, int a_Height, int a_BlockZ, int a_ColumnHeight, int a_Seq, cNoise & a_Noise, int a_Chance, sSetBlockVector & a_Blocks, const sMetaCoords * a_Coords, size_t a_NumCoords, BLOCKTYPE a_BlockType)
-{
- for (size_t i = 0; i < a_NumCoords; i++)
- {
- int x = a_BlockX + a_Coords[i].x;
- int z = a_BlockZ + a_Coords[i].z;
- if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height + i, z + 64 * a_Seq) <= a_Chance)
- {
- for (int j = 0; j < a_ColumnHeight; j++)
- {
- a_Blocks.push_back(sSetBlock(x, a_Height - j, z, a_BlockType, a_Coords[i].Meta));
- }
- }
- } // for i - a_Coords[]
-}
-
-
-
-
-
-void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, EMCSBiome a_Biome, sSetBlockVector & a_Blocks)
-{
- switch (a_Biome)
- {
- case biPlains:
- case biExtremeHills:
- case biExtremeHillsEdge:
- case biForest:
- case biMushroomIsland:
- case biMushroomShore:
- case biForestHills:
- {
- // Apple or birch trees:
- if (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + 16 * a_Seq, a_BlockZ + 16 * a_Seq) < 0x5fffffff)
- {
- GetAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks);
- }
- else
- {
- GetBirchTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks);
- }
- break;
- }
-
- case biTaiga:
- case biIcePlains:
- case biIceMountains:
- case biTaigaHills:
- {
- // Conifers
- GetConiferTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks);
- break;
- }
-
- case biSwampland:
- {
- // Swamp trees:
- GetSwampTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks);
- break;
- }
-
- case biJungle:
- case biJungleHills:
- {
- // Apple bushes, jungle trees
- if (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + 16 * a_Seq, a_BlockZ + 16 * a_Seq) < 0x5fffffff)
- {
- GetAppleBushImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks);
- }
- else
- {
- GetJungleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks);
- }
- }
- }
-}
-
-
-
-
-
-void GetAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks)
-{
- if (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY + 32 * a_Seq, a_BlockZ) < 0x60000000)
- {
- GetSmallAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks);
- }
- else
- {
- GetLargeAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks);
- }
-}
-
-
-
-
-
-void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks)
-{
- /* Small apple tree has:
- - a top plus (no log)
- - optional BigO1 + random corners (log)
- - 2 layers of BigO2 + random corners (log)
- - 1 to 3 blocks of trunk
- */
-
- int Random = a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) >> 3;
-
- // Pre-alloc so that we don't realloc too often later:
- a_Blocks.reserve(ARRAYCOUNT(BigO2) * 2 + ARRAYCOUNT(BigO1) + ARRAYCOUNT(Corners) * 3 + 3 + 5);
-
- int Heights[] = {1, 2, 2, 3} ;
- int Height = 1 + Heights[Random & 3];
- Random >>= 2;
-
- // Trunk:
- for (int i = 0; i < Height; i++)
- {
- a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE));
- }
- int Hei = a_BlockY + Height;
-
- // 2 BigO2 + corners layers:
- for (int i = 0; i < 2; i++)
- {
- PushCoordBlocks (a_BlockX, Hei, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
- PushCornerBlocks(a_BlockX, Hei, a_BlockZ, a_Seq, a_Noise, 0x5000000 - i * 0x10000000, a_Blocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
- a_Blocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE));
- Hei++;
- } // for i - 2*
-
- // Optional BigO1 + corners layer:
- if ((Random & 1) == 0)
- {
- PushCoordBlocks (a_BlockX, Hei, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
- PushCornerBlocks(a_BlockX, Hei, a_BlockZ, a_Seq, a_Noise, 0x6000000, a_Blocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
- a_Blocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE));
- Hei++;
- }
-
- // Top plus:
- PushCoordBlocks(a_BlockX, Hei, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
- a_Blocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
-}
-
-
-
-
-
-void GetLargeAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks)
-{
- // TODO
-}
-
-
-
-
-
-void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks)
-{
- int Height = 5 + (a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) % 3);
-
- // Prealloc, so that we don't realloc too often later:
- a_Blocks.reserve(Height + 80);
-
- // The entire trunk, out of logs:
- for (int i = Height - 1; i >= 0; --i)
- {
- a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_BIRCH));
- }
- int h = a_BlockY + Height;
-
- // Top layer - just the Plus:
- PushCoordBlocks(a_BlockX, h, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
- a_Blocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH)); // There's no log at this layer
- h--;
-
- // Second layer - log, Plus and maybe Corners:
- PushCoordBlocks (a_BlockX, h, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
- PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_Blocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
- h--;
-
- // Third and fourth layers - BigO2 and maybe 2*Corners:
- for (int Row = 0; Row < 2; Row++)
- {
- PushCoordBlocks (a_BlockX, h, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
- PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x3fffffff + Row * 0x10000000, a_Blocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
- h--;
- } // for Row - 2*
-}
-
-
-
-
-
-void GetConiferTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks)
-{
- // Half chance for a spruce, half for a pine:
- if (a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) < 0x40000000)
- {
- GetSpruceTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks);
- }
- else
- {
- GetPineTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks);
- }
-}
-
-
-
-
-
-void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks)
-{
- // Spruces have a top section with layer sizes of (0, 1, 0) or only (1, 0),
- // then 1 - 3 sections of ascending sizes (1, 2) [most often], (1, 3) or (1, 2, 3)
- // and an optional bottom section of size 1, followed by 1 - 3 clear trunk blocks
-
- // We'll use bits from this number as partial random numbers; but the noise function has mod8 irregularities
- // (each of the mod8 remainders has a very different chance of occurrence) - that's why we divide by 8
- int MyRandom = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY + 32 * a_Seq, a_BlockZ) / 8;
-
- // Prealloc, so that we don't realloc too often later:
- a_Blocks.reserve(180);
-
- // Clear trunk blocks:
- static const int sHeights[] = {1, 2, 2, 3};
- int Height = sHeights[MyRandom & 3];
- MyRandom >>= 2;
- for (int i = 0; i < Height; i++)
- {
- a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
- }
- Height += a_BlockY;
-
- // Optional size-1 bottom leaves layer:
- if ((MyRandom & 1) == 0)
- {
- PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
- a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
- Height++;
- }
- MyRandom >>= 1;
-
- // 1 to 3 sections of leaves layers:
- static const int sNumSections[] = {1, 2, 2, 3};
- int NumSections = sNumSections[MyRandom & 3];
- MyRandom >>= 2;
- for (int i = 0; i < NumSections; i++)
- {
- switch (MyRandom & 3) // SectionType; (1, 2) twice as often as the other two
- {
- case 0:
- case 1:
- {
- PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
- PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
- a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
- a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
- Height += 2;
- break;
- }
- case 2:
- {
- PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
- PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
- a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
- a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
- Height += 2;
- break;
- }
- case 3:
- {
- PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
- PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
- PushCoordBlocks(a_BlockX, Height + 2, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
- a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
- a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
- a_Blocks.push_back(sSetBlock(a_BlockX, Height + 2, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
- Height += 3;
- break;
- }
- } // switch (SectionType)
- MyRandom >>= 2;
- } // for i - Sections
-
- if ((MyRandom & 1) == 0)
- {
- // (0, 1, 0) top:
- a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
- PushCoordBlocks (a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
- a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
- a_Blocks.push_back(sSetBlock(a_BlockX, Height + 2, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
- }
- else
- {
- // (1, 0) top:
- a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
- PushCoordBlocks (a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
- a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
- }
-}
-
-
-
-
-
-void GetPineTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks)
-{
- // Tall, little leaves on top. The top leaves are arranged in a shape of two cones joined by their bases.
- // There can be one or two layers representing the cone bases (SameSizeMax)
-
- int MyRandom = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 8;
- int TrunkHeight = 8 + (MyRandom % 3);
- int SameSizeMax = ((MyRandom & 8) == 0) ? 1 : 0;
- MyRandom >>= 3;
- int NumLeavesLayers = 2 + (MyRandom % 3); // Number of layers that have leaves in them
- if (NumLeavesLayers == 2)
- {
- SameSizeMax = 0;
- }
-
- // Pre-allocate the vector:
- a_Blocks.reserve(TrunkHeight + NumLeavesLayers * 25);
-
- // The entire trunk, out of logs:
- for (int i = TrunkHeight; i >= 0; --i)
- {
- a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
- }
- int h = a_BlockY + TrunkHeight + 2;
-
- // Top layer - just a single leaves block:
- a_Blocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
- h--;
-
- // One more layer is above the trunk, push the central leaves:
- a_Blocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
-
- // Layers expanding in size, then collapsing again:
- // LOGD("Generating %d layers of pine leaves, SameSizeMax = %d", NumLeavesLayers, SameSizeMax);
- for (int i = 0; i < NumLeavesLayers; ++i)
- {
- int LayerSize = std::min(i, NumLeavesLayers - i + SameSizeMax - 1);
- // LOGD("LayerSize %d: %d", i, LayerSize);
- if (LayerSize < 0)
- {
- break;
- }
- ASSERT(LayerSize < ARRAYCOUNT(BigOs));
- PushCoordBlocks(a_BlockX, h, a_BlockZ, a_Blocks, BigOs[LayerSize].Coords, BigOs[LayerSize].Count, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
- h--;
- }
-}
-
-
-
-
-
-void GetSwampTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks)
-{
- // Vines are around the BigO3, but not in the corners; need proper meta for direction
- static const sMetaCoords Vines[] =
- {
- {-2, -4, 1}, {-1, -4, 1}, {0, -4, 1}, {1, -4, 1}, {2, -4, 1}, // North face
- {-2, 4, 4}, {-1, 4, 4}, {0, 4, 4}, {1, 4, 4}, {2, 4, 4}, // South face
- {4, -2, 2}, {4, -1, 2}, {4, 0, 2}, {4, 1, 2}, {4, 2, 2}, // East face
- {-4, -2, 8}, {-4, -1, 8}, {-4, 0, 8}, {-4, 1, 8}, {-4, 2, 8}, // West face
- } ;
-
- int Height = 3 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 8) % 3;
-
- a_Blocks.reserve(2 * ARRAYCOUNT(BigO2) + 2 * ARRAYCOUNT(BigO3) + Height * ARRAYCOUNT(Vines) + 20);
-
- for (int i = 0; i < Height; i++)
- {
- a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE));
- }
- int hei = a_BlockY + Height - 2;
-
- // Put vines around the lowermost leaves layer:
- PushSomeColumns(a_BlockX, hei, a_BlockZ, Height, a_Seq, a_Noise, 0x3fffffff, a_Blocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES);
-
- // The lower two leaves layers are BigO3 with log in the middle and possibly corners:
- for (int i = 0; i < 2; i++)
- {
- PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
- PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_Blocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
- hei++;
- } // for i - 2*
-
- // The upper two leaves layers are BigO2 with leaves in the middle and possibly corners:
- for (int i = 0; i < 2; i++)
- {
- PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
- PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_Blocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
- a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
- hei++;
- } // for i - 2*
-}
-
-
-
-
-
-void GetAppleBushImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks)
-{
- a_Blocks.reserve(3 + ARRAYCOUNT(BigO2) + ARRAYCOUNT(BigO1));
-
- int hei = a_BlockY;
- a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_JUNGLE));
- PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
- hei++;
-
- a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
- PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
- hei++;
-
- a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
-}
-
-
-
-
-
-void GetJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks)
-{
- // TODO
-}
-
-
-
-
+ +// Trees.cpp + +// Implements helper functions used for generating trees + +#include "Globals.h" +#include "Trees.h" +#include "BlockID.h" + + + + + +typedef struct +{ + int x, z; +} sCoords; + +typedef struct +{ + int x, z; + NIBBLETYPE Meta; +} sMetaCoords; + +static const sCoords Corners[] = +{ + {-1, -1}, + {-1, 1}, + {1, -1}, + {1, 1}, +} ; + +static const sCoords BigO1[] = +{ + {0, -1}, + {-1, 0}, {1, 0}, + {0, 1}, +} ; + +static const sCoords BigO2[] = +{ + {-1, -2}, {0, -2}, {1, -2}, + {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, + {-2, 0}, {-1, 0}, {1, 0}, {2, 0}, + {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, + {-1, 2}, {0, 2}, {1, 2}, +} ; + +static const sCoords BigO3[] = +{ + {-2, -3}, {-1, -3}, {0, -3}, {1, -3}, {2, -3}, + {-3, -2}, {-2, -2}, {-1, -2}, {0, -2}, {1, -2}, {2, -2}, {3, -2}, + {-3, -1}, {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1}, + {-3, 0}, {-2, 0}, {-1, 0}, {1, 0}, {2, 0}, {3, 0}, + {-3, 1}, {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, {3, 1}, + {-3, 2}, {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2}, + {-2, 3}, {-1, 3}, {0, 3}, {1, 3}, {2, 3}, +} ; + +typedef struct +{ + const sCoords * Coords; + size_t Count; +} sCoordsArr; + +static const sCoordsArr BigOs[] = +{ + {BigO1, ARRAYCOUNT(BigO1)}, + {BigO2, ARRAYCOUNT(BigO2)}, + {BigO3, ARRAYCOUNT(BigO3)}, +} ; + + + + + +/// Pushes a specified layer of blocks of the same type around (x, h, z) into a_Blocks +inline void PushCoordBlocks(int a_BlockX, int a_Height, int a_BlockZ, sSetBlockVector & a_Blocks, const sCoords * a_Coords, size_t a_NumCoords, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) +{ + for (size_t i = 0; i < a_NumCoords; i++) + { + a_Blocks.push_back(sSetBlock(a_BlockX + a_Coords[i].x, a_Height, a_BlockZ + a_Coords[i].z, a_BlockType, a_Meta)); + } +} + + + + +inline void PushCornerBlocks(int a_BlockX, int a_Height, int a_BlockZ, int a_Seq, cNoise & a_Noise, int a_Chance, sSetBlockVector & a_Blocks, int a_CornersDist, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) +{ + for (size_t i = 0; i < ARRAYCOUNT(Corners); i++) + { + int x = a_BlockX + Corners[i].x; + int z = a_BlockZ + Corners[i].z; + if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height, z + 64 * a_Seq) <= a_Chance) + { + a_Blocks.push_back(sSetBlock(x, a_Height, z, a_BlockType, a_Meta)); + } + } // for i - Corners[] +} + + + + + +inline void PushSomeColumns(int a_BlockX, int a_Height, int a_BlockZ, int a_ColumnHeight, int a_Seq, cNoise & a_Noise, int a_Chance, sSetBlockVector & a_Blocks, const sMetaCoords * a_Coords, size_t a_NumCoords, BLOCKTYPE a_BlockType) +{ + for (size_t i = 0; i < a_NumCoords; i++) + { + int x = a_BlockX + a_Coords[i].x; + int z = a_BlockZ + a_Coords[i].z; + if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height + i, z + 64 * a_Seq) <= a_Chance) + { + for (int j = 0; j < a_ColumnHeight; j++) + { + a_Blocks.push_back(sSetBlock(x, a_Height - j, z, a_BlockType, a_Coords[i].Meta)); + } + } + } // for i - a_Coords[] +} + + + + + +void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, EMCSBiome a_Biome, sSetBlockVector & a_Blocks) +{ + switch (a_Biome) + { + case biPlains: + case biExtremeHills: + case biExtremeHillsEdge: + case biForest: + case biMushroomIsland: + case biMushroomShore: + case biForestHills: + { + // Apple or birch trees: + if (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + 16 * a_Seq, a_BlockZ + 16 * a_Seq) < 0x5fffffff) + { + GetAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } + else + { + GetBirchTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } + break; + } + + case biTaiga: + case biIcePlains: + case biIceMountains: + case biTaigaHills: + { + // Conifers + GetConiferTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + break; + } + + case biSwampland: + { + // Swamp trees: + GetSwampTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + break; + } + + case biJungle: + case biJungleHills: + { + // Apple bushes, jungle trees + if (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + 16 * a_Seq, a_BlockZ + 16 * a_Seq) < 0x5fffffff) + { + GetAppleBushImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } + else + { + GetJungleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } + } + } +} + + + + + +void GetAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + if (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY + 32 * a_Seq, a_BlockZ) < 0x60000000) + { + GetSmallAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } + else + { + GetLargeAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } +} + + + + + +void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + /* Small apple tree has: + - a top plus (no log) + - optional BigO1 + random corners (log) + - 2 layers of BigO2 + random corners (log) + - 1 to 3 blocks of trunk + */ + + int Random = a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) >> 3; + + // Pre-alloc so that we don't realloc too often later: + a_Blocks.reserve(ARRAYCOUNT(BigO2) * 2 + ARRAYCOUNT(BigO1) + ARRAYCOUNT(Corners) * 3 + 3 + 5); + + int Heights[] = {1, 2, 2, 3} ; + int Height = 1 + Heights[Random & 3]; + Random >>= 2; + + // Trunk: + for (int i = 0; i < Height; i++) + { + a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); + } + int Hei = a_BlockY + Height; + + // 2 BigO2 + corners layers: + for (int i = 0; i < 2; i++) + { + PushCoordBlocks (a_BlockX, Hei, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + PushCornerBlocks(a_BlockX, Hei, a_BlockZ, a_Seq, a_Noise, 0x5000000 - i * 0x10000000, a_Blocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + a_Blocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); + Hei++; + } // for i - 2* + + // Optional BigO1 + corners layer: + if ((Random & 1) == 0) + { + PushCoordBlocks (a_BlockX, Hei, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + PushCornerBlocks(a_BlockX, Hei, a_BlockZ, a_Seq, a_Noise, 0x6000000, a_Blocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + a_Blocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); + Hei++; + } + + // Top plus: + PushCoordBlocks(a_BlockX, Hei, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + a_Blocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); +} + + + + + +void GetLargeAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + // TODO +} + + + + + +void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + int Height = 5 + (a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) % 3); + + // Prealloc, so that we don't realloc too often later: + a_Blocks.reserve(Height + 80); + + // The entire trunk, out of logs: + for (int i = Height - 1; i >= 0; --i) + { + a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_BIRCH)); + } + int h = a_BlockY + Height; + + // Top layer - just the Plus: + PushCoordBlocks(a_BlockX, h, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); + a_Blocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH)); // There's no log at this layer + h--; + + // Second layer - log, Plus and maybe Corners: + PushCoordBlocks (a_BlockX, h, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); + PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_Blocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); + h--; + + // Third and fourth layers - BigO2 and maybe 2*Corners: + for (int Row = 0; Row < 2; Row++) + { + PushCoordBlocks (a_BlockX, h, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); + PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x3fffffff + Row * 0x10000000, a_Blocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); + h--; + } // for Row - 2* +} + + + + + +void GetConiferTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + // Half chance for a spruce, half for a pine: + if (a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) < 0x40000000) + { + GetSpruceTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } + else + { + GetPineTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_Blocks); + } +} + + + + + +void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + // Spruces have a top section with layer sizes of (0, 1, 0) or only (1, 0), + // then 1 - 3 sections of ascending sizes (1, 2) [most often], (1, 3) or (1, 2, 3) + // and an optional bottom section of size 1, followed by 1 - 3 clear trunk blocks + + // We'll use bits from this number as partial random numbers; but the noise function has mod8 irregularities + // (each of the mod8 remainders has a very different chance of occurrence) - that's why we divide by 8 + int MyRandom = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY + 32 * a_Seq, a_BlockZ) / 8; + + // Prealloc, so that we don't realloc too often later: + a_Blocks.reserve(180); + + // Clear trunk blocks: + static const int sHeights[] = {1, 2, 2, 3}; + int Height = sHeights[MyRandom & 3]; + MyRandom >>= 2; + for (int i = 0; i < Height; i++) + { + a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + } + Height += a_BlockY; + + // Optional size-1 bottom leaves layer: + if ((MyRandom & 1) == 0) + { + PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + Height++; + } + MyRandom >>= 1; + + // 1 to 3 sections of leaves layers: + static const int sNumSections[] = {1, 2, 2, 3}; + int NumSections = sNumSections[MyRandom & 3]; + MyRandom >>= 2; + for (int i = 0; i < NumSections; i++) + { + switch (MyRandom & 3) // SectionType; (1, 2) twice as often as the other two + { + case 0: + case 1: + { + PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + Height += 2; + break; + } + case 2: + { + PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + Height += 2; + break; + } + case 3: + { + PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_Blocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + PushCoordBlocks(a_BlockX, Height + 2, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + a_Blocks.push_back(sSetBlock(a_BlockX, Height + 2, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + Height += 3; + break; + } + } // switch (SectionType) + MyRandom >>= 2; + } // for i - Sections + + if ((MyRandom & 1) == 0) + { + // (0, 1, 0) top: + a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + PushCoordBlocks (a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); + a_Blocks.push_back(sSetBlock(a_BlockX, Height + 2, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); + } + else + { + // (1, 0) top: + a_Blocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); + PushCoordBlocks (a_BlockX, Height + 1, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + a_Blocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); + } +} + + + + + +void GetPineTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + // Tall, little leaves on top. The top leaves are arranged in a shape of two cones joined by their bases. + // There can be one or two layers representing the cone bases (SameSizeMax) + + int MyRandom = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 8; + int TrunkHeight = 8 + (MyRandom % 3); + int SameSizeMax = ((MyRandom & 8) == 0) ? 1 : 0; + MyRandom >>= 3; + int NumLeavesLayers = 2 + (MyRandom % 3); // Number of layers that have leaves in them + if (NumLeavesLayers == 2) + { + SameSizeMax = 0; + } + + // Pre-allocate the vector: + a_Blocks.reserve(TrunkHeight + NumLeavesLayers * 25); + + // The entire trunk, out of logs: + for (int i = TrunkHeight; i >= 0; --i) + { + a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); + } + int h = a_BlockY + TrunkHeight + 2; + + // Top layer - just a single leaves block: + a_Blocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); + h--; + + // One more layer is above the trunk, push the central leaves: + a_Blocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER)); + + // Layers expanding in size, then collapsing again: + // LOGD("Generating %d layers of pine leaves, SameSizeMax = %d", NumLeavesLayers, SameSizeMax); + for (int i = 0; i < NumLeavesLayers; ++i) + { + int LayerSize = std::min(i, NumLeavesLayers - i + SameSizeMax - 1); + // LOGD("LayerSize %d: %d", i, LayerSize); + if (LayerSize < 0) + { + break; + } + ASSERT(LayerSize < ARRAYCOUNT(BigOs)); + PushCoordBlocks(a_BlockX, h, a_BlockZ, a_Blocks, BigOs[LayerSize].Coords, BigOs[LayerSize].Count, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); + h--; + } +} + + + + + +void GetSwampTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + // Vines are around the BigO3, but not in the corners; need proper meta for direction + static const sMetaCoords Vines[] = + { + {-2, -4, 1}, {-1, -4, 1}, {0, -4, 1}, {1, -4, 1}, {2, -4, 1}, // North face + {-2, 4, 4}, {-1, 4, 4}, {0, 4, 4}, {1, 4, 4}, {2, 4, 4}, // South face + {4, -2, 2}, {4, -1, 2}, {4, 0, 2}, {4, 1, 2}, {4, 2, 2}, // East face + {-4, -2, 8}, {-4, -1, 8}, {-4, 0, 8}, {-4, 1, 8}, {-4, 2, 8}, // West face + } ; + + int Height = 3 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 8) % 3; + + a_Blocks.reserve(2 * ARRAYCOUNT(BigO2) + 2 * ARRAYCOUNT(BigO3) + Height * ARRAYCOUNT(Vines) + 20); + + for (int i = 0; i < Height; i++) + { + a_Blocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); + } + int hei = a_BlockY + Height - 2; + + // Put vines around the lowermost leaves layer: + PushSomeColumns(a_BlockX, hei, a_BlockZ, Height, a_Seq, a_Noise, 0x3fffffff, a_Blocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES); + + // The lower two leaves layers are BigO3 with log in the middle and possibly corners: + for (int i = 0; i < 2; i++) + { + PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_Blocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + hei++; + } // for i - 2* + + // The upper two leaves layers are BigO2 with leaves in the middle and possibly corners: + for (int i = 0; i < 2; i++) + { + PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_Blocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); + hei++; + } // for i - 2* +} + + + + + +void GetAppleBushImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + a_Blocks.reserve(3 + ARRAYCOUNT(BigO2) + ARRAYCOUNT(BigO1)); + + int hei = a_BlockY; + a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_JUNGLE)); + PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + hei++; + + a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); + PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_Blocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); + hei++; + + a_Blocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); +} + + + + + +void GetJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks) +{ + // TODO +} + + + + diff --git a/source/Trees.h b/source/Trees.h index 84f1c51ea..aa8190e44 100644 --- a/source/Trees.h +++ b/source/Trees.h @@ -1,85 +1,85 @@ -
-// Trees.h
-
-// Interfaces to helper functions used for generating trees
-
-/*
-Note that all of these functions must generate the same tree image for the same input (x, y, z, seq)
- - cStructGenTrees depends on this
-To generate a random image for the (x, y, z) coords, pass an arbitrary value as (seq).
-*/
-
-
-
-
-
-#pragma once
-
-#include "ChunkDef.h"
-#include "cNoise.h"
-
-
-
-
-
-// Blocks that don't block tree growth:
-#define CASE_TREE_ALLOWED_BLOCKS \
- case E_BLOCK_AIR: \
- case E_BLOCK_LEAVES: \
- case E_BLOCK_SNOW: \
- case E_BLOCK_TALL_GRASS: \
- case E_BLOCK_DEAD_BUSH: \
- case E_BLOCK_SAPLING: \
- case E_BLOCK_VINES
-
-// Blocks that a tree may overwrite when growing:
-#define CASE_TREE_OVERWRITTEN_BLOCKS \
- case E_BLOCK_AIR: \
- case E_BLOCK_LEAVES: \
- case E_BLOCK_SNOW: \
- case E_BLOCK_TALL_GRASS: \
- case E_BLOCK_DEAD_BUSH: \
- case E_BLOCK_SAPLING: \
- case E_BLOCK_VINES
-
-
-
-
-
-/// Generates an image of a tree at the specified coords (lowest trunk block) in the specified biome
-void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, EMCSBiome a_Biome, sSetBlockVector & a_Blocks);
-
-/// Generates an image of a random apple tree
-void GetAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks);
-
-/// Generates an image of a small (nonbranching) apple tree
-void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks);
-
-/// Generates an image of a large (branching) apple tree
-void GetLargeAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks);
-
-/// Generates an image of a random birch tree
-void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks);
-
-/// Generates an image of a random conifer tree
-void GetConiferTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks);
-
-/// Generates an image of a random spruce (short conifer, two layers of leaves)
-void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks);
-
-/// Generates an image of a random pine (tall conifer, little leaves at top)
-void GetPineTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks);
-
-/// Generates an image of a random swampland tree
-void GetSwampTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks);
-
-/// Generates an image of a random apple bush (for jungles)
-void GetAppleBushImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks);
-
-/// Generates an image of a random jungle tree
-void GetJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks);
-
-
-
-
-
+ +// Trees.h + +// Interfaces to helper functions used for generating trees + +/* +Note that all of these functions must generate the same tree image for the same input (x, y, z, seq) + - cStructGenTrees depends on this +To generate a random image for the (x, y, z) coords, pass an arbitrary value as (seq). +*/ + + + + + +#pragma once + +#include "ChunkDef.h" +#include "cNoise.h" + + + + + +// Blocks that don't block tree growth: +#define CASE_TREE_ALLOWED_BLOCKS \ + case E_BLOCK_AIR: \ + case E_BLOCK_LEAVES: \ + case E_BLOCK_SNOW: \ + case E_BLOCK_TALL_GRASS: \ + case E_BLOCK_DEAD_BUSH: \ + case E_BLOCK_SAPLING: \ + case E_BLOCK_VINES + +// Blocks that a tree may overwrite when growing: +#define CASE_TREE_OVERWRITTEN_BLOCKS \ + case E_BLOCK_AIR: \ + case E_BLOCK_LEAVES: \ + case E_BLOCK_SNOW: \ + case E_BLOCK_TALL_GRASS: \ + case E_BLOCK_DEAD_BUSH: \ + case E_BLOCK_SAPLING: \ + case E_BLOCK_VINES + + + + + +/// Generates an image of a tree at the specified coords (lowest trunk block) in the specified biome +void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, EMCSBiome a_Biome, sSetBlockVector & a_Blocks); + +/// Generates an image of a random apple tree +void GetAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a small (nonbranching) apple tree +void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a large (branching) apple tree +void GetLargeAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a random birch tree +void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a random conifer tree +void GetConiferTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a random spruce (short conifer, two layers of leaves) +void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a random pine (tall conifer, little leaves at top) +void GetPineTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a random swampland tree +void GetSwampTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a random apple bush (for jungles) +void GetAppleBushImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + +/// Generates an image of a random jungle tree +void GetJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_Blocks); + + + + + diff --git a/source/Vector3d.cpp b/source/Vector3d.cpp index 075034605..987c380dc 100644 --- a/source/Vector3d.cpp +++ b/source/Vector3d.cpp @@ -1,23 +1,23 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "Vector3d.h"
-#include "Vector3f.h"
-
-
-
-
-
-Vector3d::Vector3d(const Vector3f & v )
- : x( v.x )
- , y( v.y )
- , z( v.z )
-{
-}
-
-Vector3d::Vector3d(const Vector3f * v )
- : x( v->x )
- , y( v->y )
- , z( v->z )
-{
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "Vector3d.h" +#include "Vector3f.h" + + + + + +Vector3d::Vector3d(const Vector3f & v ) + : x( v.x ) + , y( v.y ) + , z( v.z ) +{ +} + +Vector3d::Vector3d(const Vector3f * v ) + : x( v->x ) + , y( v->y ) + , z( v->z ) +{ }
\ No newline at end of file diff --git a/source/Vector3d.h b/source/Vector3d.h index f93c2c763..5d3a7ad2c 100644 --- a/source/Vector3d.h +++ b/source/Vector3d.h @@ -1,42 +1,42 @@ -#pragma once
-
-#include <math.h>
-
-class Vector3f;
-class Vector3d //tolua_export
-{ //tolua_export
-public: //tolua_export
- // convert from float
- Vector3d(const Vector3f & v ); //tolua_export
- Vector3d(const Vector3f * v ); //tolua_export
-
- Vector3d() : x(0), y(0), z(0) {} //tolua_export
- Vector3d(double a_x, double a_y, double a_z) : x(a_x), y(a_y), z(a_z) {} //tolua_export
-
- inline void Set(double a_x, double a_y, double a_z) { x = a_x, y = a_y, z = a_z; } //tolua_export
- inline void Normalize() { double l = 1.0f / Length(); x *= l; y *= l; z *= l; } //tolua_export
- inline Vector3d NormalizeCopy() { double l = 1.0f / Length(); return Vector3d( x * l, y * l, z * l ); } //tolua_export
- inline void NormalizeCopy(Vector3d & a_V) { double l = 1.0f / Length(); a_V.Set(x*l, y*l, z*l ); } //tolua_export
- inline double Length() const { return (double)sqrt( x * x + y * y + z * z ); } //tolua_export
- inline double SqrLength() const { return x * x + y * y + z * z; } //tolua_export
- inline double Dot( const Vector3d & a_V ) const { return x * a_V.x + y * a_V.y + z * a_V.z; } //tolua_export
- inline Vector3d Cross( const Vector3d & v ) const { return Vector3d( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); } //tolua_export
-
- inline bool Equals( const Vector3d & v ) const { return (x == v.x && y == v.y && z == v.z ); } //tolua_export
-
- void operator += ( const Vector3d& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; }
- void operator += ( Vector3d* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; }
- void operator -= ( const Vector3d& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; }
- void operator -= ( Vector3d* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; }
- void operator *= ( double a_f ) { x *= a_f; y *= a_f; z *= a_f; }
-
- Vector3d operator + ( const Vector3d& v2 ) const { return Vector3d( x + v2.x, y + v2.y, z + v2.z ); } //tolua_export
- Vector3d operator + ( const Vector3d* v2 ) const { return Vector3d( x + v2->x, y + v2->y, z + v2->z ); } //tolua_export
- Vector3d operator - ( const Vector3d& v2 ) const { return Vector3d( x - v2.x, y - v2.y, z - v2.z ); } //tolua_export
- Vector3d operator - ( const Vector3d* v2 ) const { return Vector3d( x - v2->x, y - v2->y, z - v2->z ); } //tolua_export
- Vector3d operator * ( const double f ) const { return Vector3d( x * f, y * f, z * f ); } //tolua_export
- Vector3d operator * ( const Vector3d& v2 ) const { return Vector3d( x * v2.x, y * v2.y, z * v2.z ); } //tolua_export
-
- double x, y, z; //tolua_export
-
+#pragma once + +#include <math.h> + +class Vector3f; +class Vector3d //tolua_export +{ //tolua_export +public: //tolua_export + // convert from float + Vector3d(const Vector3f & v ); //tolua_export + Vector3d(const Vector3f * v ); //tolua_export + + Vector3d() : x(0), y(0), z(0) {} //tolua_export + Vector3d(double a_x, double a_y, double a_z) : x(a_x), y(a_y), z(a_z) {} //tolua_export + + inline void Set(double a_x, double a_y, double a_z) { x = a_x, y = a_y, z = a_z; } //tolua_export + inline void Normalize() { double l = 1.0f / Length(); x *= l; y *= l; z *= l; } //tolua_export + inline Vector3d NormalizeCopy() { double l = 1.0f / Length(); return Vector3d( x * l, y * l, z * l ); } //tolua_export + inline void NormalizeCopy(Vector3d & a_V) { double l = 1.0f / Length(); a_V.Set(x*l, y*l, z*l ); } //tolua_export + inline double Length() const { return (double)sqrt( x * x + y * y + z * z ); } //tolua_export + inline double SqrLength() const { return x * x + y * y + z * z; } //tolua_export + inline double Dot( const Vector3d & a_V ) const { return x * a_V.x + y * a_V.y + z * a_V.z; } //tolua_export + inline Vector3d Cross( const Vector3d & v ) const { return Vector3d( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); } //tolua_export + + inline bool Equals( const Vector3d & v ) const { return (x == v.x && y == v.y && z == v.z ); } //tolua_export + + void operator += ( const Vector3d& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; } + void operator += ( Vector3d* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; } + void operator -= ( const Vector3d& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; } + void operator -= ( Vector3d* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; } + void operator *= ( double a_f ) { x *= a_f; y *= a_f; z *= a_f; } + + Vector3d operator + ( const Vector3d& v2 ) const { return Vector3d( x + v2.x, y + v2.y, z + v2.z ); } //tolua_export + Vector3d operator + ( const Vector3d* v2 ) const { return Vector3d( x + v2->x, y + v2->y, z + v2->z ); } //tolua_export + Vector3d operator - ( const Vector3d& v2 ) const { return Vector3d( x - v2.x, y - v2.y, z - v2.z ); } //tolua_export + Vector3d operator - ( const Vector3d* v2 ) const { return Vector3d( x - v2->x, y - v2->y, z - v2->z ); } //tolua_export + Vector3d operator * ( const double f ) const { return Vector3d( x * f, y * f, z * f ); } //tolua_export + Vector3d operator * ( const Vector3d& v2 ) const { return Vector3d( x * v2.x, y * v2.y, z * v2.z ); } //tolua_export + + double x, y, z; //tolua_export + };//tolua_export
\ No newline at end of file diff --git a/source/Vector3f.cpp b/source/Vector3f.cpp index c23644065..59d71d371 100644 --- a/source/Vector3f.cpp +++ b/source/Vector3f.cpp @@ -1,34 +1,34 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "Vector3f.h"
-#include "Vector3d.h"
-#include "Vector3i.h"
-
-Vector3f::Vector3f( const Vector3d & v )
- : x( (float)v.x )
- , y( (float)v.y )
- , z( (float)v.z )
-{
-}
-
-Vector3f::Vector3f( const Vector3d * v )
- : x( (float)v->x )
- , y( (float)v->y )
- , z( (float)v->z )
-{
-}
-
-Vector3f::Vector3f( const Vector3i & v )
- : x( (float)v.x )
- , y( (float)v.y )
- , z( (float)v.z )
-{
-}
-
-Vector3f::Vector3f( const Vector3i * v )
- : x( (float)v->x )
- , y( (float)v->y )
- , z( (float)v->z )
-{
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "Vector3f.h" +#include "Vector3d.h" +#include "Vector3i.h" + +Vector3f::Vector3f( const Vector3d & v ) + : x( (float)v.x ) + , y( (float)v.y ) + , z( (float)v.z ) +{ +} + +Vector3f::Vector3f( const Vector3d * v ) + : x( (float)v->x ) + , y( (float)v->y ) + , z( (float)v->z ) +{ +} + +Vector3f::Vector3f( const Vector3i & v ) + : x( (float)v.x ) + , y( (float)v.y ) + , z( (float)v.z ) +{ +} + +Vector3f::Vector3f( const Vector3i * v ) + : x( (float)v->x ) + , y( (float)v->y ) + , z( (float)v->z ) +{ }
\ No newline at end of file diff --git a/source/Vector3f.h b/source/Vector3f.h index ed1a6ef07..4c95e20de 100644 --- a/source/Vector3f.h +++ b/source/Vector3f.h @@ -1,47 +1,47 @@ -#pragma once
-
-#include <math.h>
-
-class Vector3i;
-class Vector3d;
-class Vector3f //tolua_export
-{ //tolua_export
-public: //tolua_export
- Vector3f( const Vector3d & v ); //tolua_export
- Vector3f( const Vector3d * v ); //tolua_export
- Vector3f( const Vector3i & v ); //tolua_export
- Vector3f( const Vector3i * v ); //tolua_export
-
-
- Vector3f() : x(0), y(0), z(0) {} //tolua_export
- Vector3f(float a_x, float a_y, float a_z) : x(a_x), y(a_y), z(a_z) {} //tolua_export
-
- inline void Set(float a_x, float a_y, float a_z) { x = a_x, y = a_y, z = a_z; } //tolua_export
- inline void Normalize() { float l = 1.0f / Length(); x *= l; y *= l; z *= l; } //tolua_export
- inline Vector3f NormalizeCopy() const { float l = 1.0f / Length(); return Vector3f( x * l, y * l, z * l ); }//tolua_export
- inline void NormalizeCopy(Vector3f & a_V) const { float l = 1.0f / Length(); a_V.Set(x*l, y*l, z*l ); } //tolua_export
- inline float Length() const { return (float)sqrtf( x * x + y * y + z * z ); } //tolua_export
- inline float SqrLength() const { return x * x + y * y + z * z; } //tolua_export
- inline float Dot( const Vector3f & a_V ) const { return x * a_V.x + y * a_V.y + z * a_V.z; } //tolua_export
- inline Vector3f Cross( const Vector3f & v ) const { return Vector3f( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); } //tolua_export
-
- inline bool Equals( const Vector3f & v ) const { return (x == v.x && y == v.y && z == v.z ); } //tolua_export
-
- void operator += ( const Vector3f& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; }
- void operator += ( Vector3f* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; }
- void operator -= ( const Vector3f& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; }
- void operator -= ( Vector3f* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; }
- void operator *= ( float a_f ) { x *= a_f; y *= a_f; z *= a_f; }
- void operator *= ( Vector3f* a_V ) { x *= a_V->x; y *= a_V->y; z *= a_V->z; }
- void operator *= ( const Vector3f& a_V ) { x *= a_V.x; y *= a_V.y; z *= a_V.z; }
-
- Vector3f operator + ( const Vector3f& v2 ) const { return Vector3f( x + v2.x, y + v2.y, z + v2.z ); } //tolua_export
- Vector3f operator + ( const Vector3f* v2 ) const { return Vector3f( x + v2->x, y + v2->y, z + v2->z ); } //tolua_export
- Vector3f operator - ( const Vector3f& v2 ) const { return Vector3f( x - v2.x, y - v2.y, z - v2.z ); } //tolua_export
- Vector3f operator - ( const Vector3f* v2 ) const { return Vector3f( x - v2->x, y - v2->y, z - v2->z ); } //tolua_export
- Vector3f operator * ( const float f ) const { return Vector3f( x * f, y * f, z * f ); } //tolua_export
- Vector3f operator * ( const Vector3f& v2 ) const { return Vector3f( x * v2.x, y * v2.y, z * v2.z ); } //tolua_export
-
- float x, y, z; //tolua_export
-
+#pragma once + +#include <math.h> + +class Vector3i; +class Vector3d; +class Vector3f //tolua_export +{ //tolua_export +public: //tolua_export + Vector3f( const Vector3d & v ); //tolua_export + Vector3f( const Vector3d * v ); //tolua_export + Vector3f( const Vector3i & v ); //tolua_export + Vector3f( const Vector3i * v ); //tolua_export + + + Vector3f() : x(0), y(0), z(0) {} //tolua_export + Vector3f(float a_x, float a_y, float a_z) : x(a_x), y(a_y), z(a_z) {} //tolua_export + + inline void Set(float a_x, float a_y, float a_z) { x = a_x, y = a_y, z = a_z; } //tolua_export + inline void Normalize() { float l = 1.0f / Length(); x *= l; y *= l; z *= l; } //tolua_export + inline Vector3f NormalizeCopy() const { float l = 1.0f / Length(); return Vector3f( x * l, y * l, z * l ); }//tolua_export + inline void NormalizeCopy(Vector3f & a_V) const { float l = 1.0f / Length(); a_V.Set(x*l, y*l, z*l ); } //tolua_export + inline float Length() const { return (float)sqrtf( x * x + y * y + z * z ); } //tolua_export + inline float SqrLength() const { return x * x + y * y + z * z; } //tolua_export + inline float Dot( const Vector3f & a_V ) const { return x * a_V.x + y * a_V.y + z * a_V.z; } //tolua_export + inline Vector3f Cross( const Vector3f & v ) const { return Vector3f( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); } //tolua_export + + inline bool Equals( const Vector3f & v ) const { return (x == v.x && y == v.y && z == v.z ); } //tolua_export + + void operator += ( const Vector3f& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; } + void operator += ( Vector3f* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; } + void operator -= ( const Vector3f& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; } + void operator -= ( Vector3f* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; } + void operator *= ( float a_f ) { x *= a_f; y *= a_f; z *= a_f; } + void operator *= ( Vector3f* a_V ) { x *= a_V->x; y *= a_V->y; z *= a_V->z; } + void operator *= ( const Vector3f& a_V ) { x *= a_V.x; y *= a_V.y; z *= a_V.z; } + + Vector3f operator + ( const Vector3f& v2 ) const { return Vector3f( x + v2.x, y + v2.y, z + v2.z ); } //tolua_export + Vector3f operator + ( const Vector3f* v2 ) const { return Vector3f( x + v2->x, y + v2->y, z + v2->z ); } //tolua_export + Vector3f operator - ( const Vector3f& v2 ) const { return Vector3f( x - v2.x, y - v2.y, z - v2.z ); } //tolua_export + Vector3f operator - ( const Vector3f* v2 ) const { return Vector3f( x - v2->x, y - v2->y, z - v2->z ); } //tolua_export + Vector3f operator * ( const float f ) const { return Vector3f( x * f, y * f, z * f ); } //tolua_export + Vector3f operator * ( const Vector3f& v2 ) const { return Vector3f( x * v2.x, y * v2.y, z * v2.z ); } //tolua_export + + float x, y, z; //tolua_export + };//tolua_export
\ No newline at end of file diff --git a/source/Vector3i.cpp b/source/Vector3i.cpp index 3e812bf7c..4ce1e2cf3 100644 --- a/source/Vector3i.cpp +++ b/source/Vector3i.cpp @@ -1,16 +1,16 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "Vector3i.h"
-#include "Vector3d.h"
-
-
-
-
-
-Vector3i::Vector3i( const Vector3d & v )
- : x( (int)v.x )
- , y( (int)v.y )
- , z( (int)v.z )
-{
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "Vector3i.h" +#include "Vector3d.h" + + + + + +Vector3i::Vector3i( const Vector3d & v ) + : x( (int)v.x ) + , y( (int)v.y ) + , z( (int)v.z ) +{ }
\ No newline at end of file diff --git a/source/Vector3i.h b/source/Vector3i.h index 7fbd74b5a..85f2d7003 100644 --- a/source/Vector3i.h +++ b/source/Vector3i.h @@ -1,38 +1,38 @@ -#pragma once
-
-#include <math.h>
-
-class Vector3d;
-class Vector3i //tolua_export
-{ //tolua_export
-public: //tolua_export
- Vector3i( const Vector3d & v ); //tolua_export
-
- Vector3i() : x(0), y(0), z(0) {} //tolua_export
- Vector3i(int a_x, int a_y, int a_z) : x(a_x), y(a_y), z(a_z) {} //tolua_export
-
- inline void Set(int a_x, int a_y, int a_z) { x = a_x, y = a_y, z = a_z; } //tolua_export
- inline float Length() const { return sqrtf( (float)( x * x + y * y + z * z) ); } //tolua_export
- inline int SqrLength() const { return x * x + y * y + z * z; } //tolua_export
-
- inline bool Equals( const Vector3i & v ) const { return (x == v.x && y == v.y && z == v.z ); } //tolua_export
- inline bool Equals( const Vector3i * v ) const { return (x == v->x && y == v->y && z == v->z ); } //tolua_export
-
- void operator += ( const Vector3i& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; }
- void operator += ( Vector3i* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; }
- void operator -= ( const Vector3i& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; }
- void operator -= ( Vector3i* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; }
- void operator *= ( int a_f ) { x *= a_f; y *= a_f; z *= a_f; }
-
- friend Vector3i operator + ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z ); }
- friend Vector3i operator + ( const Vector3i& v1, Vector3i* v2 ) { return Vector3i( v1.x + v2->x, v1.y + v2->y, v1.z + v2->z ); }
- friend Vector3i operator - ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x - v2.x, v1.y - v2.y, v1.z - v2.z ); }
- friend Vector3i operator - ( const Vector3i& v1, Vector3i* v2 ) { return Vector3i( v1.x - v2->x, v1.y - v2->y, v1.z - v2->z ); }
- friend Vector3i operator - ( const Vector3i* v1, Vector3i& v2 ) { return Vector3i( v1->x - v2.x, v1->y - v2.y, v1->z - v2.z ); }
- friend Vector3i operator * ( const Vector3i& v, const int f ) { return Vector3i( v.x * f, v.y * f, v.z * f ); }
- friend Vector3i operator * ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x * v2.x, v1.y * v2.y, v1.z * v2.z ); }
- friend Vector3i operator * ( const int f, const Vector3i& v ) { return Vector3i( v.x * f, v.y * f, v.z * f ); }
- friend bool operator < ( const Vector3i& v1, const Vector3i& v2 ) { return (v1.x<v2.x)||(v1.x==v2.x && v1.y<v2.y)||(v1.x==v2.x && v1.y == v2.y && v1.z<v2.z); }
-
- int x, y, z; //tolua_export
+#pragma once + +#include <math.h> + +class Vector3d; +class Vector3i //tolua_export +{ //tolua_export +public: //tolua_export + Vector3i( const Vector3d & v ); //tolua_export + + Vector3i() : x(0), y(0), z(0) {} //tolua_export + Vector3i(int a_x, int a_y, int a_z) : x(a_x), y(a_y), z(a_z) {} //tolua_export + + inline void Set(int a_x, int a_y, int a_z) { x = a_x, y = a_y, z = a_z; } //tolua_export + inline float Length() const { return sqrtf( (float)( x * x + y * y + z * z) ); } //tolua_export + inline int SqrLength() const { return x * x + y * y + z * z; } //tolua_export + + inline bool Equals( const Vector3i & v ) const { return (x == v.x && y == v.y && z == v.z ); } //tolua_export + inline bool Equals( const Vector3i * v ) const { return (x == v->x && y == v->y && z == v->z ); } //tolua_export + + void operator += ( const Vector3i& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; } + void operator += ( Vector3i* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; } + void operator -= ( const Vector3i& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; } + void operator -= ( Vector3i* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; } + void operator *= ( int a_f ) { x *= a_f; y *= a_f; z *= a_f; } + + friend Vector3i operator + ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z ); } + friend Vector3i operator + ( const Vector3i& v1, Vector3i* v2 ) { return Vector3i( v1.x + v2->x, v1.y + v2->y, v1.z + v2->z ); } + friend Vector3i operator - ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x - v2.x, v1.y - v2.y, v1.z - v2.z ); } + friend Vector3i operator - ( const Vector3i& v1, Vector3i* v2 ) { return Vector3i( v1.x - v2->x, v1.y - v2->y, v1.z - v2->z ); } + friend Vector3i operator - ( const Vector3i* v1, Vector3i& v2 ) { return Vector3i( v1->x - v2.x, v1->y - v2.y, v1->z - v2.z ); } + friend Vector3i operator * ( const Vector3i& v, const int f ) { return Vector3i( v.x * f, v.y * f, v.z * f ); } + friend Vector3i operator * ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x * v2.x, v1.y * v2.y, v1.z * v2.z ); } + friend Vector3i operator * ( const int f, const Vector3i& v ) { return Vector3i( v.x * f, v.y * f, v.z * f ); } + friend bool operator < ( const Vector3i& v1, const Vector3i& v2 ) { return (v1.x<v2.x)||(v1.x==v2.x && v1.y<v2.y)||(v1.x==v2.x && v1.y == v2.y && v1.z<v2.z); } + + int x, y, z; //tolua_export }; //tolua_export
\ No newline at end of file diff --git a/source/WSSAnvil.cpp b/source/WSSAnvil.cpp index 56f8dac7a..435b8007d 100644 --- a/source/WSSAnvil.cpp +++ b/source/WSSAnvil.cpp @@ -1,955 +1,955 @@ -
-// WSSAnvil.cpp
-
-// Implements the cWSSAnvil class representing the Anvil world storage scheme
-
-#include "Globals.h"
-#include "WSSAnvil.h"
-#include "cWorld.h"
-#include "zlib.h"
-#include "BlockID.h"
-#include "cChestEntity.h"
-#include "cFurnaceEntity.h"
-#include "cItem.h"
-#include "StringCompression.h"
-#include "cEntity.h"
-#include "cBlockEntity.h"
-#include "cMakeDir.h"
-#include "FastNBT.h"
-
-
-
-
-
-/** Maximum number of MCA files that are cached in memory.
-Since only the header is actually in the memory, this number can be high, but still, each file means an OS FS handle.
-*/
-#define MAX_MCA_FILES 32
-
-/// The maximum size of an inflated chunk; raw chunk data is 192 KiB, allow 64 KiB more of entities
-#define CHUNK_INFLATE_MAX 256 KiB
-
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cNBTChunkSerializer
-
-class cNBTChunkSerializer :
- public cChunkDataSeparateCollector
-{
-public:
- cNBTChunkSerializer(cFastNBTWriter & a_Writer) :
- m_Writer(a_Writer),
- m_IsTagOpen(false),
- m_HasHadEntity(false),
- m_HasHadBlockEntity(false),
- m_IsLightValid(false)
- {
- }
-
-
- /// Close NBT tags that we've opened
- void Finish(void)
- {
- if (m_IsTagOpen)
- {
- m_Writer.EndList();
- }
- }
-
-
- bool IsLightValid(void) const {return m_IsLightValid; }
-
-protected:
-
- /* From cChunkDataSeparateCollector we inherit:
- - m_BlockTypes[]
- - m_BlockMetas[]
- - m_BlockLight[]
- - m_BlockSkyLight[]
- */
-
- // TODO: Biomes
-
- cFastNBTWriter & m_Writer;
-
- bool m_IsTagOpen; // True if a tag has been opened in the callbacks and not yet closed.
- bool m_HasHadEntity; // True if any Entity has already been received and processed
- bool m_HasHadBlockEntity; // True if any BlockEntity has already been received and processed
- bool m_IsLightValid; // True if the chunk lighting is valid
-
-
- void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID)
- {
- m_Writer.AddInt ("x", a_Entity->GetPosX());
- m_Writer.AddInt ("y", a_Entity->GetPosY());
- m_Writer.AddInt ("z", a_Entity->GetPosZ());
- m_Writer.AddString("id", a_EntityTypeID);
- }
-
-
- void AddItem(const cItem * a_Item, int a_Slot)
- {
- m_Writer.BeginCompound("");
- m_Writer.AddShort("id", (short)(a_Item->m_ItemID));
- m_Writer.AddShort("Damage", a_Item->m_ItemHealth);
- m_Writer.AddByte ("Count", a_Item->m_ItemCount);
- m_Writer.AddByte ("Slot", (unsigned char)a_Slot);
- m_Writer.EndCompound();
- }
-
-
- void AddChestEntity(cChestEntity * a_Entity)
- {
- m_Writer.BeginCompound("");
- AddBasicTileEntity(a_Entity, "Chest");
- m_Writer.BeginList("Items", TAG_Compound);
- for (int i = 0; i < cChestEntity::c_ChestHeight * cChestEntity::c_ChestWidth; i++)
- {
- const cItem * Item = a_Entity->GetSlot(i);
- if ((Item == NULL) || Item->IsEmpty())
- {
- continue;
- }
- AddItem(Item, i);
- }
- m_Writer.EndList();
- m_Writer.EndCompound();
- }
-
-
- void AddFurnaceEntity(cFurnaceEntity * a_Furnace)
- {
- m_Writer.BeginCompound("");
- AddBasicTileEntity(a_Furnace, "Furnace");
- m_Writer.BeginList("Items", TAG_Compound);
- AddItem(&a_Furnace->GetSlot(0), 0);
- AddItem(&a_Furnace->GetSlot(1), 1);
- AddItem(&a_Furnace->GetSlot(2), 2);
- m_Writer.EndList();
- m_Writer.AddShort("BurnTime", (Int16)(a_Furnace->GetTimeToBurn() / 50.0));
- m_Writer.AddShort("CookTime", (Int16)(a_Furnace->GetTimeCooked() / 50.0));
- m_Writer.EndCompound();
- }
-
-
- virtual bool LightIsValid(bool a_IsLightValid) override
- {
- m_IsLightValid = a_IsLightValid;
- return a_IsLightValid; // We want lighting only if it's valid, otherwise don't bother
- }
-
-
- virtual void Entity(cEntity * a_Entity) override
- {
- // TODO: Add entity into NBT:
- }
-
-
- virtual void BlockEntity(cBlockEntity * a_Entity)
- {
- if (m_IsTagOpen)
- {
- if (!m_HasHadBlockEntity)
- {
- m_Writer.EndList();
- m_Writer.BeginList("TileEntities", TAG_Compound);
- }
- }
- else
- {
- m_Writer.BeginList("TileEntities", TAG_Compound);
- }
- m_IsTagOpen = true;
-
- // Add tile-entity into NBT:
- switch (a_Entity->GetBlockType())
- {
- case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity); break;
- case E_BLOCK_FURNACE: AddFurnaceEntity((cFurnaceEntity *)a_Entity); break;
- default:
- {
- ASSERT(!"Unhandled block entity saved into Anvil");
- }
- }
- m_HasHadBlockEntity = true;
- }
-} ; // class cNBTChunkSerializer
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cWSSAnvil:
-
-cWSSAnvil::cWSSAnvil(cWorld * a_World) :
- super(a_World)
-{
- // Create a level.dat file for mapping tools, if it doesn't already exist:
- AString fnam;
- Printf(fnam, "%s/level.dat", a_World->GetName().c_str());
- if (!cFile::Exists(fnam))
- {
- cFastNBTWriter Writer;
- Writer.BeginCompound("");
- Writer.AddInt("SpawnX", (int)(a_World->GetSpawnX()));
- Writer.AddInt("SpawnY", (int)(a_World->GetSpawnY()));
- Writer.AddInt("SpawnZ", (int)(a_World->GetSpawnZ()));
- Writer.EndCompound();
- Writer.Finish();
-
- #ifdef _DEBUG
- cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size());
- ASSERT(TestParse.IsValid());
- #endif // _DEBUG
-
- gzFile gz = gzopen(fnam.c_str(), "wb");
- if (gz != NULL)
- {
- gzwrite(gz, Writer.GetResult().data(), Writer.GetResult().size());
- }
- gzclose(gz);
- }
-}
-
-
-
-
-
-cWSSAnvil::~cWSSAnvil()
-{
- cCSLock Lock(m_CS);
- for (cMCAFiles::iterator itr = m_Files.begin(); itr != m_Files.end(); ++itr)
- {
- delete *itr;
- } // for itr - m_Files[]
-}
-
-
-
-
-
-bool cWSSAnvil::LoadChunk(const cChunkCoords & a_Chunk)
-{
- AString ChunkData;
- if (!GetChunkData(a_Chunk, ChunkData))
- {
- // The reason for failure is already printed in GetChunkData()
- return false;
- }
-
- return LoadChunkFromData(a_Chunk, ChunkData);
-}
-
-
-
-
-
-bool cWSSAnvil::SaveChunk(const cChunkCoords & a_Chunk)
-{
- AString ChunkData;
- if (!SaveChunkToData(a_Chunk, ChunkData))
- {
- return false;
- }
- if (!SetChunkData(a_Chunk, ChunkData))
- {
- return false;
- }
-
- // Everything successful
- return true;
-}
-
-
-
-
-
-bool cWSSAnvil::GetChunkData(const cChunkCoords & a_Chunk, AString & a_Data)
-{
- cCSLock Lock(m_CS);
- cMCAFile * File = LoadMCAFile(a_Chunk);
- if (File == NULL)
- {
- return false;
- }
- return File->GetChunkData(a_Chunk, a_Data);
-}
-
-
-
-
-
-bool cWSSAnvil::SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Data)
-{
- cCSLock Lock(m_CS);
- cMCAFile * File = LoadMCAFile(a_Chunk);
- if (File == NULL)
- {
- return false;
- }
- return File->SetChunkData(a_Chunk, a_Data);
-}
-
-
-
-
-
-cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk)
-{
- // ASSUME m_CS is locked
-
- const int RegionX = (int)(floorf((float)a_Chunk.m_ChunkX / 32.0f));
- const int RegionZ = (int)(floorf((float)a_Chunk.m_ChunkZ / 32.0f));
-
- // Is it already cached?
- for (cMCAFiles::iterator itr = m_Files.begin(); itr != m_Files.end(); ++itr)
- {
- if (((*itr) != NULL) && ((*itr)->GetRegionX() == RegionX) && ((*itr)->GetRegionZ() == RegionZ))
- {
- // Move the file to front and return it:
- cMCAFile * f = *itr;
- if (itr != m_Files.begin())
- {
- m_Files.erase(itr);
- m_Files.push_front(f);
- }
- return f;
- }
- }
-
- // Load it anew:
- AString FileName;
- Printf(FileName, "%s/region", m_World->GetName().c_str());
- cMakeDir::MakeDir(FileName);
- AppendPrintf(FileName, "/r.%d.%d.mca", RegionX, RegionZ);
- cMCAFile * f = new cMCAFile(FileName, RegionX, RegionZ);
- if (f == NULL)
- {
- return NULL;
- }
- m_Files.push_front(f);
-
- // If there are too many MCA files cached, delete the last one used:
- if (m_Files.size() > MAX_MCA_FILES)
- {
- delete m_Files.back();
- m_Files.pop_back();
- }
- return f;
-}
-
-
-
-
-
-bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & a_Data)
-{
- // Decompress the data:
- char Uncompressed[CHUNK_INFLATE_MAX];
- z_stream strm;
- strm.zalloc = (alloc_func)NULL;
- strm.zfree = (free_func)NULL;
- strm.opaque = NULL;
- inflateInit(&strm);
- strm.next_out = (Bytef *)Uncompressed;
- strm.avail_out = sizeof(Uncompressed);
- strm.next_in = (Bytef *)a_Data.data();
- strm.avail_in = a_Data.size();
- int res = inflate(&strm, Z_FINISH);
- inflateEnd(&strm);
- if (res != Z_STREAM_END)
- {
- return false;
- }
-
- // Parse the NBT data:
- cParsedNBT NBT(Uncompressed, strm.total_out);
- if (!NBT.IsValid())
- {
- // NBT Parsing failed
- return false;
- }
-
- // Load the data from NBT:
- return LoadChunkFromNBT(a_Chunk, NBT);
-}
-
-
-
-
-
-bool cWSSAnvil::SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data)
-{
- cFastNBTWriter Writer;
- if (!SaveChunkToNBT(a_Chunk, Writer))
- {
- return false;
- }
- Writer.Finish();
- CompressString(Writer.GetResult().data(), Writer.GetResult().size(), a_Data);
- return true;
-}
-
-
-
-
-
-bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT & a_NBT)
-{
- // The data arrays, in MCA-native y/z/x ordering (will be reordered for the final chunk data)
- cChunkDef::BlockTypes BlockTypes;
- cChunkDef::BlockNibbles MetaData;
- cChunkDef::BlockNibbles BlockLight;
- cChunkDef::BlockNibbles SkyLight;
-
- memset(BlockTypes, E_BLOCK_AIR, sizeof(BlockTypes));
- memset(MetaData, 0, sizeof(MetaData));
- memset(SkyLight, 0xff, sizeof(SkyLight)); // By default, data not present in the NBT means air, which means full skylight
- memset(BlockLight, 0x00, sizeof(BlockLight));
-
- // Load the blockdata, blocklight and skylight:
- int Level = a_NBT.FindChildByName(0, "Level");
- if (Level < 0)
- {
- return false;
- }
- int Sections = a_NBT.FindChildByName(Level, "Sections");
- if ((Sections < 0) || (a_NBT.GetType(Sections) != TAG_List) || (a_NBT.GetChildrenType(Sections) != TAG_Compound))
- {
- return false;
- }
- for (int Child = a_NBT.GetFirstChild(Sections); Child >= 0; Child = a_NBT.GetNextSibling(Child))
- {
- int y = 0;
- int SectionY = a_NBT.FindChildByName(Child, "Y");
- if ((SectionY < 0) || (a_NBT.GetType(SectionY) != TAG_Byte))
- {
- continue;
- }
- y = a_NBT.GetByte(SectionY);
- if ((y < 0) || (y > 15))
- {
- continue;
- }
- CopyNBTData(a_NBT, Child, "Blocks", (char *)&(BlockTypes[y * 4096]), 4096);
- CopyNBTData(a_NBT, Child, "Data", (char *)&(MetaData[y * 2048]), 2048);
- CopyNBTData(a_NBT, Child, "SkyLight", (char *)&(SkyLight[y * 2048]), 2048);
- CopyNBTData(a_NBT, Child, "BlockLight", (char *)&(BlockLight[y * 2048]), 2048);
- } // for itr - LevelSections[]
-
- // Load the biomes from NBT, if present and valid:
- cChunkDef::BiomeMap BiomeMap;
- cChunkDef::BiomeMap * Biomes = LoadBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "Biomes"));
-
- // Load the entities from NBT:
- cEntityList Entities;
- cBlockEntityList BlockEntities;
- LoadEntitiesFromNBT (Entities, a_NBT, a_NBT.FindChildByName(Level, "Entities"));
- LoadBlockEntitiesFromNBT(BlockEntities, a_NBT, a_NBT.FindChildByName(Level, "TileEntities"));
-
- bool IsLightValid = (a_NBT.FindChildByName(Level, "MCSIsLightValid") > 0);
-
- /*
- // Uncomment this block for really cool stuff :)
- // DEBUG magic: Invert the underground, so that we can see the MC generator in action :)
- bool ShouldInvert[cChunkDef::Width * cChunkDef::Width];
- memset(ShouldInvert, 0, sizeof(ShouldInvert));
- for (int y = cChunkDef::Height - 1; y >= 0; y--)
- {
- for (int x = 0; x < cChunkDef::Width; x++) for (int z = 0; z < cChunkDef::Width; z++)
- {
- int Index = cChunkDef::MakeIndexNoCheck(x, y, z);
- if (ShouldInvert[x + cChunkDef::Width * z])
- {
- ChunkData[Index] = (ChunkData[Index] == E_BLOCK_AIR) ? E_BLOCK_STONE : E_BLOCK_AIR;
- }
- else
- {
- ShouldInvert[x + cChunkDef::Width * z] = (ChunkData[Index] != E_BLOCK_AIR);
- }
- }
- } // for y
- // Set everything alight, so that we can see:
- memset(ChunkData + cChunkDef::SkyLightOffset, 0xff, cChunkDef::NumBlocks / 2);
- //*/
-
- m_World->SetChunkData(
- a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ,
- BlockTypes, MetaData,
- IsLightValid ? BlockLight : NULL,
- IsLightValid ? SkyLight : NULL,
- NULL, Biomes,
- Entities, BlockEntities,
- false
- );
- return true;
-}
-
-
-
-
-void cWSSAnvil::CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, int a_Length)
-{
- int Child = a_NBT.FindChildByName(a_Tag, a_ChildName);
- if ((Child >= 0) && (a_NBT.GetType(Child) == TAG_ByteArray) && (a_NBT.GetDataLength(Child) == a_Length))
- {
- memcpy(a_Destination, a_NBT.GetData(Child), a_Length);
- }
-}
-
-
-
-
-
-bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_Writer)
-{
- a_Writer.BeginCompound("Level");
- a_Writer.AddInt("xPos", a_Chunk.m_ChunkX);
- a_Writer.AddInt("zPos", a_Chunk.m_ChunkZ);
- cNBTChunkSerializer Serializer(a_Writer);
- if (!m_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, Serializer))
- {
- return false;
- }
- Serializer.Finish(); // Close NBT tags
-
- // TODO: Save biomes, both MCS (IntArray) and MC-vanilla (ByteArray):
- // Level->Add(new cNBTByteArray(Level, "Biomes", AString(Serializer.m_Biomes, sizeof(Serializer.m_Biomes));
- // Level->Add(new cNBTByteArray(Level, "MCSBiomes", AString(Serializer.m_Biomes, sizeof(Serializer.m_Biomes));
-
- // Save blockdata:
- a_Writer.BeginList("Sections", TAG_Compound);
- int SliceSizeBlock = cChunkDef::Width * cChunkDef::Width * 16;
- int SliceSizeNibble = SliceSizeBlock / 2;
- const char * BlockTypes = (const char *)(Serializer.m_BlockTypes);
- const char * BlockMetas = (const char *)(Serializer.m_BlockMetas);
- const char * BlockLight = (const char *)(Serializer.m_BlockLight);
- const char * BlockSkyLight = (const char *)(Serializer.m_BlockSkyLight);
- for (int Y = 0; Y < 16; Y++)
- {
- a_Writer.BeginCompound("");
- a_Writer.AddByteArray("Blocks", BlockTypes + Y * SliceSizeBlock, SliceSizeBlock);
- a_Writer.AddByteArray("Data", BlockMetas + Y * SliceSizeNibble, SliceSizeNibble);
- a_Writer.AddByteArray("SkyLight", BlockSkyLight + Y * SliceSizeNibble, SliceSizeNibble);
- a_Writer.AddByteArray("BlockLight", BlockLight + Y * SliceSizeNibble, SliceSizeNibble);
- a_Writer.AddByte("Y", (unsigned char)Y);
- a_Writer.EndCompound();
- }
- a_Writer.EndList(); // "Sections"
-
- // Store the information that the lighting is valid.
- // For compatibility reason, the default is "invalid" (missing) - this means older data is re-lighted upon loading.
- if (Serializer.IsLightValid())
- {
- a_Writer.AddByte("MCSIsLightValid", 1);
- }
-
- a_Writer.EndCompound(); // "Level"
- return true;
-}
-
-
-
-
-
-cChunkDef::BiomeMap * cWSSAnvil::LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx)
-{
- if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_ByteArray))
- {
- return NULL;
- }
- if (a_NBT.GetDataLength(a_TagIdx) != sizeof(*a_BiomeMap))
- {
- // The biomes stored don't match in size
- return NULL;
- }
- memcpy(a_BiomeMap, a_NBT.GetData(a_TagIdx), sizeof(*a_BiomeMap));
- for (int i = 0; i < ARRAYCOUNT(*a_BiomeMap); i++)
- {
- if ((*a_BiomeMap)[i] == 0xff)
- {
- // Unassigned biomes
- return NULL;
- }
- }
- return a_BiomeMap;
-}
-
-
-
-
-
-void cWSSAnvil::LoadEntitiesFromNBT(cEntityList & a_Entitites, const cParsedNBT & a_NBT, int a_TagIdx)
-{
- // TODO: Load the entities
-}
-
-
-
-
-
-void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
-{
- if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_List))
- {
- return;
- }
-
- for (int Child = a_NBT.GetFirstChild(a_TagIdx); Child != -1; Child = a_NBT.GetNextSibling(Child))
- {
- if (a_NBT.GetType(Child) != TAG_Compound)
- {
- continue;
- }
- int sID = a_NBT.FindChildByName(Child, "id");
- if (sID < 0)
- {
- continue;
- }
- if (strncmp(a_NBT.GetData(sID), "Chest", a_NBT.GetDataLength(sID)) == 0)
- {
- LoadChestFromNBT(a_BlockEntities, a_NBT, Child);
- }
- else if (strncmp(a_NBT.GetData(sID), "Furnace", a_NBT.GetDataLength(sID)) == 0)
- {
- LoadFurnaceFromNBT(a_BlockEntities, a_NBT, Child);
- }
- // TODO: Other block entities
- } // for Child - tag children
-}
-
-
-
-
-
-void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
-{
- ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
- int x, y, z;
- if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
- {
- return;
- }
- int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
- if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
- {
- return; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this
- }
- std::auto_ptr<cChestEntity> Chest(new cChestEntity(x, y, z, m_World));
- for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child))
- {
- int Slot = a_NBT.FindChildByName(Child, "Slot");
- if ((Slot < 0) || (a_NBT.GetType(Slot) != TAG_Byte))
- {
- continue;
- }
- cItem Item;
- int ID = a_NBT.FindChildByName(Child, "id");
- if ((ID < 0) || (a_NBT.GetType(ID) != TAG_Short))
- {
- continue;
- }
- Item.m_ItemID = (ENUM_ITEM_ID)(a_NBT.GetShort(ID));
- int Damage = a_NBT.FindChildByName(Child, "Damage");
- if ((Damage < 0) || (a_NBT.GetType(Damage) != TAG_Short))
- {
- continue;
- }
- Item.m_ItemHealth = a_NBT.GetShort(Damage);
- int Count = a_NBT.FindChildByName(Child, "Count");
- if ((Count < 0) || (a_NBT.GetType(Count) != TAG_Byte))
- {
- continue;
- }
- Item.m_ItemCount = a_NBT.GetByte(Count);
- Chest->SetSlot(a_NBT.GetByte(Slot), Item);
- } // for itr - ItemDefs[]
- a_BlockEntities.push_back(Chest.release());
-}
-
-
-
-
-
-void cWSSAnvil::LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
-{
- ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
- int x, y, z;
- if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
- {
- return;
- }
- int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
- if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
- {
- return; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this
- }
- std::auto_ptr<cFurnaceEntity> Furnace(new cFurnaceEntity(x, y, z, m_World));
- for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child))
- {
- int Slot = a_NBT.FindChildByName(Child, "Slot");
- if ((Slot < 0) || (a_NBT.GetType(Slot) != TAG_Byte))
- {
- continue;
- }
- cItem Item;
- int ID = a_NBT.FindChildByName(Child, "id");
- if ((ID < 0) || (a_NBT.GetType(ID) != TAG_Short))
- {
- continue;
- }
- Item.m_ItemID = (ENUM_ITEM_ID)(a_NBT.GetShort(ID));
- int Damage = a_NBT.FindChildByName(Child, "Damage");
- if ((Damage < 0) || (a_NBT.GetType(Damage) != TAG_Short))
- {
- continue;
- }
- Item.m_ItemHealth = a_NBT.GetShort(Damage);
- int Count = a_NBT.FindChildByName(Child, "Count");
- if ((Count < 0) || (a_NBT.GetType(Count) != TAG_Byte))
- {
- continue;
- }
- Item.m_ItemCount = a_NBT.GetByte(Count);
- Furnace->SetSlot(a_NBT.GetByte(Slot), Item);
- } // for itr - ItemDefs[]
- int BurnTime = a_NBT.FindChildByName(a_TagIdx, "BurnTime");
- if (BurnTime >= 0)
- {
- Int16 bt = a_NBT.GetShort(BurnTime);
- // Anvil doesn't store the time that the fuel can burn. We simply "reset" the current value to be the 100%
- Furnace->SetBurnTimes((float)(bt * 50.0), (float)(bt * 50.0));
- }
- int CookTime = a_NBT.FindChildByName(a_TagIdx, "CookTime");
- if (CookTime >= 0)
- {
- Int16 ct = a_NBT.GetShort(CookTime);
- // Anvil doesn't store the time that an item takes to cook. We simply use the default - 10 seconds
- Furnace->SetCookTimes(10000.0, (float)(ct * 50.0));
- }
- Furnace->ContinueCooking();
- a_BlockEntities.push_back(Furnace.release());
-}
-
-
-
-
-
-bool cWSSAnvil::GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z)
-{
- int x = a_NBT.FindChildByName(a_TagIdx, "x");
- if ((x < 0) || (a_NBT.GetType(x) != TAG_Int))
- {
- return false;
- }
- int y = a_NBT.FindChildByName(a_TagIdx, "y");
- if ((y < 0) || (a_NBT.GetType(y) != TAG_Int))
- {
- return false;
- }
- int z = a_NBT.FindChildByName(a_TagIdx, "z");
- if ((z < 0) || (a_NBT.GetType(z) != TAG_Int))
- {
- return false;
- }
- a_X = a_NBT.GetInt(x);
- a_Y = a_NBT.GetInt(y);
- a_Z = a_NBT.GetInt(z);
- return true;
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cWSSAnvil::cMCAFile:
-
-cWSSAnvil::cMCAFile::cMCAFile(const AString & a_FileName, int a_RegionX, int a_RegionZ) :
- m_RegionX(a_RegionX),
- m_RegionZ(a_RegionZ),
- m_FileName(a_FileName)
-{
-}
-
-
-
-
-
-bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading)
-{
- if (m_File.IsOpen())
- {
- // Already open
- return true;
- }
-
- if (a_IsForReading)
- {
- if (!cFile::Exists(m_FileName))
- {
- // We want to read and the file doesn't exist. Fail.
- return false;
- }
- }
-
- if (!m_File.Open(m_FileName, cFile::fmReadWrite))
- {
- // The file failed to open
- return false;
- }
-
- // Load the header:
- if (m_File.Read(m_Header, sizeof(m_Header)) != sizeof(m_Header))
- {
- // Cannot read the header - perhaps the file has just been created?
- // Try writing a NULL header (both chunk offsets and timestamps):
- memset(m_Header, 0, sizeof(m_Header));
- if (
- (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header)) || // Real header - chunk offsets
- (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header)) // Bogus data for the chunk timestamps
- )
- {
- LOGWARNING("Cannot process MCA header in file \"%s\", chunks in that file will be lost", m_FileName.c_str());
- m_File.Close();
- return false;
- }
- }
- return true;
-}
-
-
-
-
-
-bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a_Data)
-{
- if (!OpenFile(true))
- {
- return false;
- }
-
- int LocalX = a_Chunk.m_ChunkX % 32;
- if (LocalX < 0)
- {
- LocalX = 32 + LocalX;
- }
- int LocalZ = a_Chunk.m_ChunkZ % 32;
- if (LocalZ < 0)
- {
- LocalZ = 32 + LocalZ;
- }
- unsigned ChunkLocation = ntohl(m_Header[LocalX + 32 * LocalZ]);
- unsigned ChunkOffset = ChunkLocation >> 8;
-
- m_File.Seek(ChunkOffset * 4096);
-
- int ChunkSize = 0;
- if (m_File.Read(&ChunkSize, 4) != 4)
- {
- return false;
- }
- ChunkSize = ntohl(ChunkSize);
- char CompressionType = 0;
- if (m_File.Read(&CompressionType, 1) != 1)
- {
- return false;
- }
- if (CompressionType != 2)
- {
- // Chunk is in an unknown compression
- return false;
- }
- ChunkSize--;
-
- // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly
- a_Data.assign(ChunkSize, '\0');
- return (m_File.Read((void *)a_Data.data(), ChunkSize) == ChunkSize);
-}
-
-
-
-
-
-bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Data)
-{
- if (!OpenFile(false))
- {
- return false;
- }
-
- int LocalX = a_Chunk.m_ChunkX % 32;
- if (LocalX < 0)
- {
- LocalX = 32 + LocalX;
- }
- int LocalZ = a_Chunk.m_ChunkZ % 32;
- if (LocalZ < 0)
- {
- LocalZ = 32 + LocalZ;
- }
-
- unsigned ChunkSector = FindFreeLocation(LocalX, LocalZ, a_Data);
-
- // Store the chunk data:
- m_File.Seek(ChunkSector * 4096);
- unsigned ChunkSize = htonl(a_Data.size() + 1);
- if (m_File.Write(&ChunkSize, 4) != 4)
- {
- return false;
- }
- char CompressionType = 2;
- if (m_File.Write(&CompressionType, 1) != 1)
- {
- return false;
- }
- if (m_File.Write(a_Data.data(), a_Data.size()) != (int)(a_Data.size()))
- {
- return false;
- }
-
- // Store the header:
- ChunkSize = (a_Data.size() + MCA_CHUNK_HEADER_LENGTH + 4095) / 4096; // Round data size *up* to nearest 4KB sector, make it a sector number
- ASSERT(ChunkSize < 256);
- m_Header[LocalX + 32 * LocalZ] = htonl((ChunkSector << 8) | ChunkSize);
- m_File.Seek(0);
- if (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header))
- {
- return false;
- }
-
- return true;
-}
-
-
-
-
-
-unsigned cWSSAnvil::cMCAFile::FindFreeLocation(int a_LocalX, int a_LocalZ, const AString & a_Data)
-{
- // See if it fits the current location:
- unsigned ChunkLocation = ntohl(m_Header[a_LocalX + 32 * a_LocalZ]);
- unsigned ChunkLen = ChunkLocation & 0xff;
- if (a_Data.size() + MCA_CHUNK_HEADER_LENGTH <= (ChunkLen * 4096))
- {
- return ChunkLocation >> 8;
- }
-
- // Doesn't fit, append to the end of file (we're wasting a lot of space, TODO: fix this later)
- unsigned MaxLocation = 2 << 8; // Minimum sector is #2 - after the headers
- for (int i = 0; i < ARRAYCOUNT(m_Header); i++)
- {
- ChunkLocation = ntohl(m_Header[i]);
- ChunkLocation = ChunkLocation + ((ChunkLocation & 0xff) << 8); // Add the number of sectors used; don't care about the 4th byte
- if (MaxLocation < ChunkLocation)
- {
- MaxLocation = ChunkLocation;
- }
- } // for i - m_Header[]
- return MaxLocation >> 8;
-}
+ +// WSSAnvil.cpp + +// Implements the cWSSAnvil class representing the Anvil world storage scheme + +#include "Globals.h" +#include "WSSAnvil.h" +#include "cWorld.h" +#include "zlib.h" +#include "BlockID.h" +#include "cChestEntity.h" +#include "cFurnaceEntity.h" +#include "cItem.h" +#include "StringCompression.h" +#include "cEntity.h" +#include "cBlockEntity.h" +#include "cMakeDir.h" +#include "FastNBT.h" + + + + + +/** Maximum number of MCA files that are cached in memory. +Since only the header is actually in the memory, this number can be high, but still, each file means an OS FS handle. +*/ +#define MAX_MCA_FILES 32 + +/// The maximum size of an inflated chunk; raw chunk data is 192 KiB, allow 64 KiB more of entities +#define CHUNK_INFLATE_MAX 256 KiB + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cNBTChunkSerializer + +class cNBTChunkSerializer : + public cChunkDataSeparateCollector +{ +public: + cNBTChunkSerializer(cFastNBTWriter & a_Writer) : + m_Writer(a_Writer), + m_IsTagOpen(false), + m_HasHadEntity(false), + m_HasHadBlockEntity(false), + m_IsLightValid(false) + { + } + + + /// Close NBT tags that we've opened + void Finish(void) + { + if (m_IsTagOpen) + { + m_Writer.EndList(); + } + } + + + bool IsLightValid(void) const {return m_IsLightValid; } + +protected: + + /* From cChunkDataSeparateCollector we inherit: + - m_BlockTypes[] + - m_BlockMetas[] + - m_BlockLight[] + - m_BlockSkyLight[] + */ + + // TODO: Biomes + + cFastNBTWriter & m_Writer; + + bool m_IsTagOpen; // True if a tag has been opened in the callbacks and not yet closed. + bool m_HasHadEntity; // True if any Entity has already been received and processed + bool m_HasHadBlockEntity; // True if any BlockEntity has already been received and processed + bool m_IsLightValid; // True if the chunk lighting is valid + + + void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID) + { + m_Writer.AddInt ("x", a_Entity->GetPosX()); + m_Writer.AddInt ("y", a_Entity->GetPosY()); + m_Writer.AddInt ("z", a_Entity->GetPosZ()); + m_Writer.AddString("id", a_EntityTypeID); + } + + + void AddItem(const cItem * a_Item, int a_Slot) + { + m_Writer.BeginCompound(""); + m_Writer.AddShort("id", (short)(a_Item->m_ItemID)); + m_Writer.AddShort("Damage", a_Item->m_ItemHealth); + m_Writer.AddByte ("Count", a_Item->m_ItemCount); + m_Writer.AddByte ("Slot", (unsigned char)a_Slot); + m_Writer.EndCompound(); + } + + + void AddChestEntity(cChestEntity * a_Entity) + { + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Entity, "Chest"); + m_Writer.BeginList("Items", TAG_Compound); + for (int i = 0; i < cChestEntity::c_ChestHeight * cChestEntity::c_ChestWidth; i++) + { + const cItem * Item = a_Entity->GetSlot(i); + if ((Item == NULL) || Item->IsEmpty()) + { + continue; + } + AddItem(Item, i); + } + m_Writer.EndList(); + m_Writer.EndCompound(); + } + + + void AddFurnaceEntity(cFurnaceEntity * a_Furnace) + { + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Furnace, "Furnace"); + m_Writer.BeginList("Items", TAG_Compound); + AddItem(&a_Furnace->GetSlot(0), 0); + AddItem(&a_Furnace->GetSlot(1), 1); + AddItem(&a_Furnace->GetSlot(2), 2); + m_Writer.EndList(); + m_Writer.AddShort("BurnTime", (Int16)(a_Furnace->GetTimeToBurn() / 50.0)); + m_Writer.AddShort("CookTime", (Int16)(a_Furnace->GetTimeCooked() / 50.0)); + m_Writer.EndCompound(); + } + + + virtual bool LightIsValid(bool a_IsLightValid) override + { + m_IsLightValid = a_IsLightValid; + return a_IsLightValid; // We want lighting only if it's valid, otherwise don't bother + } + + + virtual void Entity(cEntity * a_Entity) override + { + // TODO: Add entity into NBT: + } + + + virtual void BlockEntity(cBlockEntity * a_Entity) + { + if (m_IsTagOpen) + { + if (!m_HasHadBlockEntity) + { + m_Writer.EndList(); + m_Writer.BeginList("TileEntities", TAG_Compound); + } + } + else + { + m_Writer.BeginList("TileEntities", TAG_Compound); + } + m_IsTagOpen = true; + + // Add tile-entity into NBT: + switch (a_Entity->GetBlockType()) + { + case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity); break; + case E_BLOCK_FURNACE: AddFurnaceEntity((cFurnaceEntity *)a_Entity); break; + default: + { + ASSERT(!"Unhandled block entity saved into Anvil"); + } + } + m_HasHadBlockEntity = true; + } +} ; // class cNBTChunkSerializer + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWSSAnvil: + +cWSSAnvil::cWSSAnvil(cWorld * a_World) : + super(a_World) +{ + // Create a level.dat file for mapping tools, if it doesn't already exist: + AString fnam; + Printf(fnam, "%s/level.dat", a_World->GetName().c_str()); + if (!cFile::Exists(fnam)) + { + cFastNBTWriter Writer; + Writer.BeginCompound(""); + Writer.AddInt("SpawnX", (int)(a_World->GetSpawnX())); + Writer.AddInt("SpawnY", (int)(a_World->GetSpawnY())); + Writer.AddInt("SpawnZ", (int)(a_World->GetSpawnZ())); + Writer.EndCompound(); + Writer.Finish(); + + #ifdef _DEBUG + cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size()); + ASSERT(TestParse.IsValid()); + #endif // _DEBUG + + gzFile gz = gzopen(fnam.c_str(), "wb"); + if (gz != NULL) + { + gzwrite(gz, Writer.GetResult().data(), Writer.GetResult().size()); + } + gzclose(gz); + } +} + + + + + +cWSSAnvil::~cWSSAnvil() +{ + cCSLock Lock(m_CS); + for (cMCAFiles::iterator itr = m_Files.begin(); itr != m_Files.end(); ++itr) + { + delete *itr; + } // for itr - m_Files[] +} + + + + + +bool cWSSAnvil::LoadChunk(const cChunkCoords & a_Chunk) +{ + AString ChunkData; + if (!GetChunkData(a_Chunk, ChunkData)) + { + // The reason for failure is already printed in GetChunkData() + return false; + } + + return LoadChunkFromData(a_Chunk, ChunkData); +} + + + + + +bool cWSSAnvil::SaveChunk(const cChunkCoords & a_Chunk) +{ + AString ChunkData; + if (!SaveChunkToData(a_Chunk, ChunkData)) + { + return false; + } + if (!SetChunkData(a_Chunk, ChunkData)) + { + return false; + } + + // Everything successful + return true; +} + + + + + +bool cWSSAnvil::GetChunkData(const cChunkCoords & a_Chunk, AString & a_Data) +{ + cCSLock Lock(m_CS); + cMCAFile * File = LoadMCAFile(a_Chunk); + if (File == NULL) + { + return false; + } + return File->GetChunkData(a_Chunk, a_Data); +} + + + + + +bool cWSSAnvil::SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Data) +{ + cCSLock Lock(m_CS); + cMCAFile * File = LoadMCAFile(a_Chunk); + if (File == NULL) + { + return false; + } + return File->SetChunkData(a_Chunk, a_Data); +} + + + + + +cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk) +{ + // ASSUME m_CS is locked + + const int RegionX = (int)(floorf((float)a_Chunk.m_ChunkX / 32.0f)); + const int RegionZ = (int)(floorf((float)a_Chunk.m_ChunkZ / 32.0f)); + + // Is it already cached? + for (cMCAFiles::iterator itr = m_Files.begin(); itr != m_Files.end(); ++itr) + { + if (((*itr) != NULL) && ((*itr)->GetRegionX() == RegionX) && ((*itr)->GetRegionZ() == RegionZ)) + { + // Move the file to front and return it: + cMCAFile * f = *itr; + if (itr != m_Files.begin()) + { + m_Files.erase(itr); + m_Files.push_front(f); + } + return f; + } + } + + // Load it anew: + AString FileName; + Printf(FileName, "%s/region", m_World->GetName().c_str()); + cMakeDir::MakeDir(FileName); + AppendPrintf(FileName, "/r.%d.%d.mca", RegionX, RegionZ); + cMCAFile * f = new cMCAFile(FileName, RegionX, RegionZ); + if (f == NULL) + { + return NULL; + } + m_Files.push_front(f); + + // If there are too many MCA files cached, delete the last one used: + if (m_Files.size() > MAX_MCA_FILES) + { + delete m_Files.back(); + m_Files.pop_back(); + } + return f; +} + + + + + +bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & a_Data) +{ + // Decompress the data: + char Uncompressed[CHUNK_INFLATE_MAX]; + z_stream strm; + strm.zalloc = (alloc_func)NULL; + strm.zfree = (free_func)NULL; + strm.opaque = NULL; + inflateInit(&strm); + strm.next_out = (Bytef *)Uncompressed; + strm.avail_out = sizeof(Uncompressed); + strm.next_in = (Bytef *)a_Data.data(); + strm.avail_in = a_Data.size(); + int res = inflate(&strm, Z_FINISH); + inflateEnd(&strm); + if (res != Z_STREAM_END) + { + return false; + } + + // Parse the NBT data: + cParsedNBT NBT(Uncompressed, strm.total_out); + if (!NBT.IsValid()) + { + // NBT Parsing failed + return false; + } + + // Load the data from NBT: + return LoadChunkFromNBT(a_Chunk, NBT); +} + + + + + +bool cWSSAnvil::SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data) +{ + cFastNBTWriter Writer; + if (!SaveChunkToNBT(a_Chunk, Writer)) + { + return false; + } + Writer.Finish(); + CompressString(Writer.GetResult().data(), Writer.GetResult().size(), a_Data); + return true; +} + + + + + +bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT & a_NBT) +{ + // The data arrays, in MCA-native y/z/x ordering (will be reordered for the final chunk data) + cChunkDef::BlockTypes BlockTypes; + cChunkDef::BlockNibbles MetaData; + cChunkDef::BlockNibbles BlockLight; + cChunkDef::BlockNibbles SkyLight; + + memset(BlockTypes, E_BLOCK_AIR, sizeof(BlockTypes)); + memset(MetaData, 0, sizeof(MetaData)); + memset(SkyLight, 0xff, sizeof(SkyLight)); // By default, data not present in the NBT means air, which means full skylight + memset(BlockLight, 0x00, sizeof(BlockLight)); + + // Load the blockdata, blocklight and skylight: + int Level = a_NBT.FindChildByName(0, "Level"); + if (Level < 0) + { + return false; + } + int Sections = a_NBT.FindChildByName(Level, "Sections"); + if ((Sections < 0) || (a_NBT.GetType(Sections) != TAG_List) || (a_NBT.GetChildrenType(Sections) != TAG_Compound)) + { + return false; + } + for (int Child = a_NBT.GetFirstChild(Sections); Child >= 0; Child = a_NBT.GetNextSibling(Child)) + { + int y = 0; + int SectionY = a_NBT.FindChildByName(Child, "Y"); + if ((SectionY < 0) || (a_NBT.GetType(SectionY) != TAG_Byte)) + { + continue; + } + y = a_NBT.GetByte(SectionY); + if ((y < 0) || (y > 15)) + { + continue; + } + CopyNBTData(a_NBT, Child, "Blocks", (char *)&(BlockTypes[y * 4096]), 4096); + CopyNBTData(a_NBT, Child, "Data", (char *)&(MetaData[y * 2048]), 2048); + CopyNBTData(a_NBT, Child, "SkyLight", (char *)&(SkyLight[y * 2048]), 2048); + CopyNBTData(a_NBT, Child, "BlockLight", (char *)&(BlockLight[y * 2048]), 2048); + } // for itr - LevelSections[] + + // Load the biomes from NBT, if present and valid: + cChunkDef::BiomeMap BiomeMap; + cChunkDef::BiomeMap * Biomes = LoadBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "Biomes")); + + // Load the entities from NBT: + cEntityList Entities; + cBlockEntityList BlockEntities; + LoadEntitiesFromNBT (Entities, a_NBT, a_NBT.FindChildByName(Level, "Entities")); + LoadBlockEntitiesFromNBT(BlockEntities, a_NBT, a_NBT.FindChildByName(Level, "TileEntities")); + + bool IsLightValid = (a_NBT.FindChildByName(Level, "MCSIsLightValid") > 0); + + /* + // Uncomment this block for really cool stuff :) + // DEBUG magic: Invert the underground, so that we can see the MC generator in action :) + bool ShouldInvert[cChunkDef::Width * cChunkDef::Width]; + memset(ShouldInvert, 0, sizeof(ShouldInvert)); + for (int y = cChunkDef::Height - 1; y >= 0; y--) + { + for (int x = 0; x < cChunkDef::Width; x++) for (int z = 0; z < cChunkDef::Width; z++) + { + int Index = cChunkDef::MakeIndexNoCheck(x, y, z); + if (ShouldInvert[x + cChunkDef::Width * z]) + { + ChunkData[Index] = (ChunkData[Index] == E_BLOCK_AIR) ? E_BLOCK_STONE : E_BLOCK_AIR; + } + else + { + ShouldInvert[x + cChunkDef::Width * z] = (ChunkData[Index] != E_BLOCK_AIR); + } + } + } // for y + // Set everything alight, so that we can see: + memset(ChunkData + cChunkDef::SkyLightOffset, 0xff, cChunkDef::NumBlocks / 2); + //*/ + + m_World->SetChunkData( + a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, + BlockTypes, MetaData, + IsLightValid ? BlockLight : NULL, + IsLightValid ? SkyLight : NULL, + NULL, Biomes, + Entities, BlockEntities, + false + ); + return true; +} + + + + +void cWSSAnvil::CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, int a_Length) +{ + int Child = a_NBT.FindChildByName(a_Tag, a_ChildName); + if ((Child >= 0) && (a_NBT.GetType(Child) == TAG_ByteArray) && (a_NBT.GetDataLength(Child) == a_Length)) + { + memcpy(a_Destination, a_NBT.GetData(Child), a_Length); + } +} + + + + + +bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_Writer) +{ + a_Writer.BeginCompound("Level"); + a_Writer.AddInt("xPos", a_Chunk.m_ChunkX); + a_Writer.AddInt("zPos", a_Chunk.m_ChunkZ); + cNBTChunkSerializer Serializer(a_Writer); + if (!m_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, Serializer)) + { + return false; + } + Serializer.Finish(); // Close NBT tags + + // TODO: Save biomes, both MCS (IntArray) and MC-vanilla (ByteArray): + // Level->Add(new cNBTByteArray(Level, "Biomes", AString(Serializer.m_Biomes, sizeof(Serializer.m_Biomes)); + // Level->Add(new cNBTByteArray(Level, "MCSBiomes", AString(Serializer.m_Biomes, sizeof(Serializer.m_Biomes)); + + // Save blockdata: + a_Writer.BeginList("Sections", TAG_Compound); + int SliceSizeBlock = cChunkDef::Width * cChunkDef::Width * 16; + int SliceSizeNibble = SliceSizeBlock / 2; + const char * BlockTypes = (const char *)(Serializer.m_BlockTypes); + const char * BlockMetas = (const char *)(Serializer.m_BlockMetas); + const char * BlockLight = (const char *)(Serializer.m_BlockLight); + const char * BlockSkyLight = (const char *)(Serializer.m_BlockSkyLight); + for (int Y = 0; Y < 16; Y++) + { + a_Writer.BeginCompound(""); + a_Writer.AddByteArray("Blocks", BlockTypes + Y * SliceSizeBlock, SliceSizeBlock); + a_Writer.AddByteArray("Data", BlockMetas + Y * SliceSizeNibble, SliceSizeNibble); + a_Writer.AddByteArray("SkyLight", BlockSkyLight + Y * SliceSizeNibble, SliceSizeNibble); + a_Writer.AddByteArray("BlockLight", BlockLight + Y * SliceSizeNibble, SliceSizeNibble); + a_Writer.AddByte("Y", (unsigned char)Y); + a_Writer.EndCompound(); + } + a_Writer.EndList(); // "Sections" + + // Store the information that the lighting is valid. + // For compatibility reason, the default is "invalid" (missing) - this means older data is re-lighted upon loading. + if (Serializer.IsLightValid()) + { + a_Writer.AddByte("MCSIsLightValid", 1); + } + + a_Writer.EndCompound(); // "Level" + return true; +} + + + + + +cChunkDef::BiomeMap * cWSSAnvil::LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx) +{ + if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_ByteArray)) + { + return NULL; + } + if (a_NBT.GetDataLength(a_TagIdx) != sizeof(*a_BiomeMap)) + { + // The biomes stored don't match in size + return NULL; + } + memcpy(a_BiomeMap, a_NBT.GetData(a_TagIdx), sizeof(*a_BiomeMap)); + for (int i = 0; i < ARRAYCOUNT(*a_BiomeMap); i++) + { + if ((*a_BiomeMap)[i] == 0xff) + { + // Unassigned biomes + return NULL; + } + } + return a_BiomeMap; +} + + + + + +void cWSSAnvil::LoadEntitiesFromNBT(cEntityList & a_Entitites, const cParsedNBT & a_NBT, int a_TagIdx) +{ + // TODO: Load the entities +} + + + + + +void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_List)) + { + return; + } + + for (int Child = a_NBT.GetFirstChild(a_TagIdx); Child != -1; Child = a_NBT.GetNextSibling(Child)) + { + if (a_NBT.GetType(Child) != TAG_Compound) + { + continue; + } + int sID = a_NBT.FindChildByName(Child, "id"); + if (sID < 0) + { + continue; + } + if (strncmp(a_NBT.GetData(sID), "Chest", a_NBT.GetDataLength(sID)) == 0) + { + LoadChestFromNBT(a_BlockEntities, a_NBT, Child); + } + else if (strncmp(a_NBT.GetData(sID), "Furnace", a_NBT.GetDataLength(sID)) == 0) + { + LoadFurnaceFromNBT(a_BlockEntities, a_NBT, Child); + } + // TODO: Other block entities + } // for Child - tag children +} + + + + + +void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); + int x, y, z; + if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + { + return; + } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); + if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) + { + return; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this + } + std::auto_ptr<cChestEntity> Chest(new cChestEntity(x, y, z, m_World)); + for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child)) + { + int Slot = a_NBT.FindChildByName(Child, "Slot"); + if ((Slot < 0) || (a_NBT.GetType(Slot) != TAG_Byte)) + { + continue; + } + cItem Item; + int ID = a_NBT.FindChildByName(Child, "id"); + if ((ID < 0) || (a_NBT.GetType(ID) != TAG_Short)) + { + continue; + } + Item.m_ItemID = (ENUM_ITEM_ID)(a_NBT.GetShort(ID)); + int Damage = a_NBT.FindChildByName(Child, "Damage"); + if ((Damage < 0) || (a_NBT.GetType(Damage) != TAG_Short)) + { + continue; + } + Item.m_ItemHealth = a_NBT.GetShort(Damage); + int Count = a_NBT.FindChildByName(Child, "Count"); + if ((Count < 0) || (a_NBT.GetType(Count) != TAG_Byte)) + { + continue; + } + Item.m_ItemCount = a_NBT.GetByte(Count); + Chest->SetSlot(a_NBT.GetByte(Slot), Item); + } // for itr - ItemDefs[] + a_BlockEntities.push_back(Chest.release()); +} + + + + + +void cWSSAnvil::LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); + int x, y, z; + if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + { + return; + } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); + if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) + { + return; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this + } + std::auto_ptr<cFurnaceEntity> Furnace(new cFurnaceEntity(x, y, z, m_World)); + for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child)) + { + int Slot = a_NBT.FindChildByName(Child, "Slot"); + if ((Slot < 0) || (a_NBT.GetType(Slot) != TAG_Byte)) + { + continue; + } + cItem Item; + int ID = a_NBT.FindChildByName(Child, "id"); + if ((ID < 0) || (a_NBT.GetType(ID) != TAG_Short)) + { + continue; + } + Item.m_ItemID = (ENUM_ITEM_ID)(a_NBT.GetShort(ID)); + int Damage = a_NBT.FindChildByName(Child, "Damage"); + if ((Damage < 0) || (a_NBT.GetType(Damage) != TAG_Short)) + { + continue; + } + Item.m_ItemHealth = a_NBT.GetShort(Damage); + int Count = a_NBT.FindChildByName(Child, "Count"); + if ((Count < 0) || (a_NBT.GetType(Count) != TAG_Byte)) + { + continue; + } + Item.m_ItemCount = a_NBT.GetByte(Count); + Furnace->SetSlot(a_NBT.GetByte(Slot), Item); + } // for itr - ItemDefs[] + int BurnTime = a_NBT.FindChildByName(a_TagIdx, "BurnTime"); + if (BurnTime >= 0) + { + Int16 bt = a_NBT.GetShort(BurnTime); + // Anvil doesn't store the time that the fuel can burn. We simply "reset" the current value to be the 100% + Furnace->SetBurnTimes((float)(bt * 50.0), (float)(bt * 50.0)); + } + int CookTime = a_NBT.FindChildByName(a_TagIdx, "CookTime"); + if (CookTime >= 0) + { + Int16 ct = a_NBT.GetShort(CookTime); + // Anvil doesn't store the time that an item takes to cook. We simply use the default - 10 seconds + Furnace->SetCookTimes(10000.0, (float)(ct * 50.0)); + } + Furnace->ContinueCooking(); + a_BlockEntities.push_back(Furnace.release()); +} + + + + + +bool cWSSAnvil::GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z) +{ + int x = a_NBT.FindChildByName(a_TagIdx, "x"); + if ((x < 0) || (a_NBT.GetType(x) != TAG_Int)) + { + return false; + } + int y = a_NBT.FindChildByName(a_TagIdx, "y"); + if ((y < 0) || (a_NBT.GetType(y) != TAG_Int)) + { + return false; + } + int z = a_NBT.FindChildByName(a_TagIdx, "z"); + if ((z < 0) || (a_NBT.GetType(z) != TAG_Int)) + { + return false; + } + a_X = a_NBT.GetInt(x); + a_Y = a_NBT.GetInt(y); + a_Z = a_NBT.GetInt(z); + return true; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWSSAnvil::cMCAFile: + +cWSSAnvil::cMCAFile::cMCAFile(const AString & a_FileName, int a_RegionX, int a_RegionZ) : + m_RegionX(a_RegionX), + m_RegionZ(a_RegionZ), + m_FileName(a_FileName) +{ +} + + + + + +bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading) +{ + if (m_File.IsOpen()) + { + // Already open + return true; + } + + if (a_IsForReading) + { + if (!cFile::Exists(m_FileName)) + { + // We want to read and the file doesn't exist. Fail. + return false; + } + } + + if (!m_File.Open(m_FileName, cFile::fmReadWrite)) + { + // The file failed to open + return false; + } + + // Load the header: + if (m_File.Read(m_Header, sizeof(m_Header)) != sizeof(m_Header)) + { + // Cannot read the header - perhaps the file has just been created? + // Try writing a NULL header (both chunk offsets and timestamps): + memset(m_Header, 0, sizeof(m_Header)); + if ( + (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header)) || // Real header - chunk offsets + (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header)) // Bogus data for the chunk timestamps + ) + { + LOGWARNING("Cannot process MCA header in file \"%s\", chunks in that file will be lost", m_FileName.c_str()); + m_File.Close(); + return false; + } + } + return true; +} + + + + + +bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a_Data) +{ + if (!OpenFile(true)) + { + return false; + } + + int LocalX = a_Chunk.m_ChunkX % 32; + if (LocalX < 0) + { + LocalX = 32 + LocalX; + } + int LocalZ = a_Chunk.m_ChunkZ % 32; + if (LocalZ < 0) + { + LocalZ = 32 + LocalZ; + } + unsigned ChunkLocation = ntohl(m_Header[LocalX + 32 * LocalZ]); + unsigned ChunkOffset = ChunkLocation >> 8; + + m_File.Seek(ChunkOffset * 4096); + + int ChunkSize = 0; + if (m_File.Read(&ChunkSize, 4) != 4) + { + return false; + } + ChunkSize = ntohl(ChunkSize); + char CompressionType = 0; + if (m_File.Read(&CompressionType, 1) != 1) + { + return false; + } + if (CompressionType != 2) + { + // Chunk is in an unknown compression + return false; + } + ChunkSize--; + + // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly + a_Data.assign(ChunkSize, '\0'); + return (m_File.Read((void *)a_Data.data(), ChunkSize) == ChunkSize); +} + + + + + +bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Data) +{ + if (!OpenFile(false)) + { + return false; + } + + int LocalX = a_Chunk.m_ChunkX % 32; + if (LocalX < 0) + { + LocalX = 32 + LocalX; + } + int LocalZ = a_Chunk.m_ChunkZ % 32; + if (LocalZ < 0) + { + LocalZ = 32 + LocalZ; + } + + unsigned ChunkSector = FindFreeLocation(LocalX, LocalZ, a_Data); + + // Store the chunk data: + m_File.Seek(ChunkSector * 4096); + unsigned ChunkSize = htonl(a_Data.size() + 1); + if (m_File.Write(&ChunkSize, 4) != 4) + { + return false; + } + char CompressionType = 2; + if (m_File.Write(&CompressionType, 1) != 1) + { + return false; + } + if (m_File.Write(a_Data.data(), a_Data.size()) != (int)(a_Data.size())) + { + return false; + } + + // Store the header: + ChunkSize = (a_Data.size() + MCA_CHUNK_HEADER_LENGTH + 4095) / 4096; // Round data size *up* to nearest 4KB sector, make it a sector number + ASSERT(ChunkSize < 256); + m_Header[LocalX + 32 * LocalZ] = htonl((ChunkSector << 8) | ChunkSize); + m_File.Seek(0); + if (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header)) + { + return false; + } + + return true; +} + + + + + +unsigned cWSSAnvil::cMCAFile::FindFreeLocation(int a_LocalX, int a_LocalZ, const AString & a_Data) +{ + // See if it fits the current location: + unsigned ChunkLocation = ntohl(m_Header[a_LocalX + 32 * a_LocalZ]); + unsigned ChunkLen = ChunkLocation & 0xff; + if (a_Data.size() + MCA_CHUNK_HEADER_LENGTH <= (ChunkLen * 4096)) + { + return ChunkLocation >> 8; + } + + // Doesn't fit, append to the end of file (we're wasting a lot of space, TODO: fix this later) + unsigned MaxLocation = 2 << 8; // Minimum sector is #2 - after the headers + for (int i = 0; i < ARRAYCOUNT(m_Header); i++) + { + ChunkLocation = ntohl(m_Header[i]); + ChunkLocation = ChunkLocation + ((ChunkLocation & 0xff) << 8); // Add the number of sectors used; don't care about the 4th byte + if (MaxLocation < ChunkLocation) + { + MaxLocation = ChunkLocation; + } + } // for i - m_Header[] + return MaxLocation >> 8; +} diff --git a/source/WSSAnvil.h b/source/WSSAnvil.h index f8beea524..ab03adf5e 100644 --- a/source/WSSAnvil.h +++ b/source/WSSAnvil.h @@ -1,131 +1,131 @@ -
-// WSSAnvil.h
-
-// Interfaces to the cWSSAnvil class representing the Anvil world storage scheme
-
-
-
-
-#pragma once
-
-#include "WorldStorage.h"
-#include "FastNBT.h"
-
-
-
-
-
-enum
-{
- /// Maximum number of chunks in an MCA file - also the count of the header items
- MCA_MAX_CHUNKS = 32 * 32,
-
- /// The MCA header is 8 KiB
- MCA_HEADER_SIZE = MCA_MAX_CHUNKS * 8,
-
- /// There are 5 bytes of header in front of each chunk
- MCA_CHUNK_HEADER_LENGTH = 5,
-} ;
-
-
-
-
-
-class cWSSAnvil :
- public cWSSchema
-{
- typedef cWSSchema super;
-
-public:
-
- cWSSAnvil(cWorld * a_World);
- virtual ~cWSSAnvil();
-
-protected:
-
- class cMCAFile
- {
- public:
-
- cMCAFile(const AString & a_FileName, int a_RegionX, int a_RegionZ);
-
- bool GetChunkData (const cChunkCoords & a_Chunk, AString & a_Data);
- bool SetChunkData (const cChunkCoords & a_Chunk, const AString & a_Data);
- bool EraseChunkData(const cChunkCoords & a_Chunk);
-
- int GetRegionX (void) const {return m_RegionX; }
- int GetRegionZ (void) const {return m_RegionZ; }
- const AString & GetFileName(void) const {return m_FileName; }
-
- protected:
-
- int m_RegionX;
- int m_RegionZ;
- cFile m_File;
- AString m_FileName;
-
- // The header, copied from the file so we don't have to seek to it all the time
- // First 1024 entries are chunk locations - the 3 + 1 byte sector-offset and sector-count
- unsigned m_Header[MCA_MAX_CHUNKS];
-
- // Chunk timestamps, following the chunk headers, are unused by MCS
-
- /// Finds a free location large enough to hold a_Data. Gets a hint of the chunk coords, places the data there if it fits. Returns the sector number.
- unsigned FindFreeLocation(int a_LocalX, int a_LocalZ, const AString & a_Data);
-
- /// Opens a MCA file either for a Read operation (fails if doesn't exist) or for a Write operation (creates new if not found)
- bool OpenFile(bool a_IsForReading);
- } ;
- typedef std::list<cMCAFile *> cMCAFiles;
-
- cCriticalSection m_CS;
- cMCAFiles m_Files; // a MRU cache of MCA files
-
- /// Gets chunk data from the correct file; locks file CS as needed
- bool GetChunkData(const cChunkCoords & a_Chunk, AString & a_Data);
-
- /// Sets chunk data into the correct file; locks file CS as needed
- bool SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Data);
-
- /// Loads the chunk from the data (no locking needed)
- bool LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & a_Data);
-
- /// Saves the chunk into datastream (no locking needed)
- bool SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data);
-
- /// Loads the chunk from NBT data (no locking needed)
- bool LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT & a_NBT);
-
- /// Saves the chunk into NBT data using a_Writer; returns true on success
- bool SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_Writer);
-
- /// Loads the chunk's biome map; returns a_BiomeMap if biomes present and valid, NULL otherwise
- cChunkDef::BiomeMap * LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx);
-
- /// Loads the chunk's entities from NBT data (a_Tag is the Level\\Entities list tag; may be -1)
- void LoadEntitiesFromNBT(cEntityList & a_Entitites, const cParsedNBT & a_NBT, int a_Tag);
-
- /// Loads the chunk's BlockEntities from NBT data (a_Tag is the Level\\TileEntities list tag; may be -1)
- void LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntitites, const cParsedNBT & a_NBT, int a_Tag);
-
- void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
- void LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
-
- /// Helper function for extracting the X, Y, and Z int subtags of a NBT compound; returns true if successful
- bool GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z);
-
- /// Gets the correct MCA file either from cache or from disk, manages the m_MCAFiles cache; assumes m_CS is locked
- cMCAFile * LoadMCAFile(const cChunkCoords & a_Chunk);
-
- /// Copies a_Length bytes of data from the specified NBT Tag's Child into the a_Destination buffer
- void CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, int a_Length);
-
- // cWSSchema overrides:
- virtual bool LoadChunk(const cChunkCoords & a_Chunk) override;
- virtual bool SaveChunk(const cChunkCoords & a_Chunk) override;
- virtual const AString GetName(void) const override {return "anvil"; }
-} ;
-
-
-
-
+ +// WSSAnvil.h + +// Interfaces to the cWSSAnvil class representing the Anvil world storage scheme + + + + +#pragma once + +#include "WorldStorage.h" +#include "FastNBT.h" + + + + + +enum +{ + /// Maximum number of chunks in an MCA file - also the count of the header items + MCA_MAX_CHUNKS = 32 * 32, + + /// The MCA header is 8 KiB + MCA_HEADER_SIZE = MCA_MAX_CHUNKS * 8, + + /// There are 5 bytes of header in front of each chunk + MCA_CHUNK_HEADER_LENGTH = 5, +} ; + + + + + +class cWSSAnvil : + public cWSSchema +{ + typedef cWSSchema super; + +public: + + cWSSAnvil(cWorld * a_World); + virtual ~cWSSAnvil(); + +protected: + + class cMCAFile + { + public: + + cMCAFile(const AString & a_FileName, int a_RegionX, int a_RegionZ); + + bool GetChunkData (const cChunkCoords & a_Chunk, AString & a_Data); + bool SetChunkData (const cChunkCoords & a_Chunk, const AString & a_Data); + bool EraseChunkData(const cChunkCoords & a_Chunk); + + int GetRegionX (void) const {return m_RegionX; } + int GetRegionZ (void) const {return m_RegionZ; } + const AString & GetFileName(void) const {return m_FileName; } + + protected: + + int m_RegionX; + int m_RegionZ; + cFile m_File; + AString m_FileName; + + // The header, copied from the file so we don't have to seek to it all the time + // First 1024 entries are chunk locations - the 3 + 1 byte sector-offset and sector-count + unsigned m_Header[MCA_MAX_CHUNKS]; + + // Chunk timestamps, following the chunk headers, are unused by MCS + + /// Finds a free location large enough to hold a_Data. Gets a hint of the chunk coords, places the data there if it fits. Returns the sector number. + unsigned FindFreeLocation(int a_LocalX, int a_LocalZ, const AString & a_Data); + + /// Opens a MCA file either for a Read operation (fails if doesn't exist) or for a Write operation (creates new if not found) + bool OpenFile(bool a_IsForReading); + } ; + typedef std::list<cMCAFile *> cMCAFiles; + + cCriticalSection m_CS; + cMCAFiles m_Files; // a MRU cache of MCA files + + /// Gets chunk data from the correct file; locks file CS as needed + bool GetChunkData(const cChunkCoords & a_Chunk, AString & a_Data); + + /// Sets chunk data into the correct file; locks file CS as needed + bool SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Data); + + /// Loads the chunk from the data (no locking needed) + bool LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & a_Data); + + /// Saves the chunk into datastream (no locking needed) + bool SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data); + + /// Loads the chunk from NBT data (no locking needed) + bool LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT & a_NBT); + + /// Saves the chunk into NBT data using a_Writer; returns true on success + bool SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_Writer); + + /// Loads the chunk's biome map; returns a_BiomeMap if biomes present and valid, NULL otherwise + cChunkDef::BiomeMap * LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx); + + /// Loads the chunk's entities from NBT data (a_Tag is the Level\\Entities list tag; may be -1) + void LoadEntitiesFromNBT(cEntityList & a_Entitites, const cParsedNBT & a_NBT, int a_Tag); + + /// Loads the chunk's BlockEntities from NBT data (a_Tag is the Level\\TileEntities list tag; may be -1) + void LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntitites, const cParsedNBT & a_NBT, int a_Tag); + + void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + + /// Helper function for extracting the X, Y, and Z int subtags of a NBT compound; returns true if successful + bool GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z); + + /// Gets the correct MCA file either from cache or from disk, manages the m_MCAFiles cache; assumes m_CS is locked + cMCAFile * LoadMCAFile(const cChunkCoords & a_Chunk); + + /// Copies a_Length bytes of data from the specified NBT Tag's Child into the a_Destination buffer + void CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, int a_Length); + + // cWSSchema overrides: + virtual bool LoadChunk(const cChunkCoords & a_Chunk) override; + virtual bool SaveChunk(const cChunkCoords & a_Chunk) override; + virtual const AString GetName(void) const override {return "anvil"; } +} ; + + + + diff --git a/source/WSSCompact.cpp b/source/WSSCompact.cpp index 1064528bc..406b55d38 100644 --- a/source/WSSCompact.cpp +++ b/source/WSSCompact.cpp @@ -1,942 +1,942 @@ -
-// WSSCompact.cpp
-
-// Interfaces to the cWSSCompact class representing the "compact" storage schema (PAK-files)
-
-#include "Globals.h"
-#include "WSSCompact.h"
-#include "cWorld.h"
-#include "zlib.h"
-#include <json/json.h>
-#include "StringCompression.h"
-#include "cChestEntity.h"
-#include "cSignEntity.h"
-#include "cFurnaceEntity.h"
-#include "BlockID.h"
-
-
-
-
-
-#pragma pack(push, 1)
-/// The chunk header, as stored in the file:
-struct cWSSCompact::sChunkHeader
-{
- int m_ChunkX;
- int m_ChunkZ;
- int m_CompressedSize;
- int m_UncompressedSize;
-} ;
-#pragma pack(pop)
-
-
-
-
-
-/// The maximum number of PAK files that are cached
-const int MAX_PAK_FILES = 16;
-
-/// The maximum number of unsaved chunks before the cPAKFile saves them to disk
-const int MAX_DIRTY_CHUNKS = 16;
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cJsonChunkSerializer:
-
-cJsonChunkSerializer::cJsonChunkSerializer(void) :
- m_HasJsonData(false)
-{
-}
-
-
-
-
-
-void cJsonChunkSerializer::Entity(cEntity * a_Entity)
-{
- // TODO: a_Entity->SaveToJson(m_Root);
-}
-
-
-
-
-
-void cJsonChunkSerializer::BlockEntity(cBlockEntity * a_BlockEntity)
-{
- const char * SaveInto = NULL;
- switch (a_BlockEntity->GetBlockType())
- {
- case E_BLOCK_CHEST: SaveInto = "Chests"; break;
- case E_BLOCK_FURNACE: SaveInto = "Furnaces"; break;
- case E_BLOCK_SIGN_POST: SaveInto = "Signs"; break;
- case E_BLOCK_WALLSIGN: SaveInto = "Signs"; break;
-
- default:
- {
- ASSERT(!"Unhandled blocktype in BlockEntities list while saving to JSON");
- break;
- }
- } // switch (BlockEntity->GetBlockType())
- if (SaveInto == NULL)
- {
- return;
- }
-
- Json::Value val;
- a_BlockEntity->SaveToJson(val);
- m_Root[SaveInto].append(val);
- m_HasJsonData = true;
-}
-
-
-
-
-
-bool cJsonChunkSerializer::LightIsValid(bool a_IsLightValid)
-{
- if (!a_IsLightValid)
- {
- return false;
- }
- m_Root["IsLightValid"] = true;
- m_HasJsonData = true;
- return true;
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cWSSCompact:
-
-cWSSCompact::~cWSSCompact()
-{
- for (cPAKFiles::iterator itr = m_PAKFiles.begin(); itr != m_PAKFiles.end(); ++itr)
- {
- delete *itr;
- }
-}
-
-
-
-
-
-bool cWSSCompact::LoadChunk(const cChunkCoords & a_Chunk)
-{
- AString ChunkData;
- int UncompressedSize = 0;
- if (!GetChunkData(a_Chunk, UncompressedSize, ChunkData))
- {
- // The reason for failure is already printed in GetChunkData()
- return false;
- }
-
- return LoadChunkFromData(a_Chunk, UncompressedSize, ChunkData, m_World);
-}
-
-
-
-
-
-bool cWSSCompact::SaveChunk(const cChunkCoords & a_Chunk)
-{
- cCSLock Lock(m_CS);
-
- cPAKFile * f = LoadPAKFile(a_Chunk);
- if (f == NULL)
- {
- // For some reason we couldn't locate the file
- LOG("Cannot locate a proper PAK file for chunk [%d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
- return false;
- }
- return f->SaveChunk(a_Chunk, m_World);
-}
-
-
-
-
-
-cWSSCompact::cPAKFile * cWSSCompact::LoadPAKFile(const cChunkCoords & a_Chunk)
-{
- // ASSUMES that m_CS has been locked
-
- // We need to retain this weird conversion code, because some edge chunks are in the wrong PAK file
- const int LayerX = (int)(floorf((float)a_Chunk.m_ChunkX / 32.0f));
- const int LayerZ = (int)(floorf((float)a_Chunk.m_ChunkZ / 32.0f));
-
- // Is it already cached?
- for (cPAKFiles::iterator itr = m_PAKFiles.begin(); itr != m_PAKFiles.end(); ++itr)
- {
- if (((*itr) != NULL) && ((*itr)->GetLayerX() == LayerX) && ((*itr)->GetLayerZ() == LayerZ))
- {
- // Move the file to front and return it:
- cPAKFile * f = *itr;
- if (itr != m_PAKFiles.begin())
- {
- m_PAKFiles.erase(itr);
- m_PAKFiles.push_front(f);
- }
- return f;
- }
- }
-
- // Load it anew:
- AString FileName;
- Printf(FileName, "%s/X%i_Z%i.pak", m_World->GetName().c_str(), LayerX, LayerZ );
- cPAKFile * f = new cPAKFile(FileName, LayerX, LayerZ);
- if (f == NULL)
- {
- return NULL;
- }
- m_PAKFiles.push_front(f);
-
- // If there are too many PAK files cached, delete the last one used:
- if (m_PAKFiles.size() > MAX_PAK_FILES)
- {
- delete m_PAKFiles.back();
- m_PAKFiles.pop_back();
- }
- return f;
-}
-
-
-
-
-
-bool cWSSCompact::GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data)
-{
- cCSLock Lock(m_CS);
- cPAKFile * f = LoadPAKFile(a_Chunk);
- if (f == NULL)
- {
- return false;
- }
- return f->GetChunkData(a_Chunk, a_UncompressedSize, a_Data);
-}
-
-
-
-
-
-/*
-// TODO: Rewrite saving to use the same principles as loading
-bool cWSSCompact::SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data)
-{
- cCSLock Lock(m_CS);
- cPAKFile * f = LoadPAKFile(a_Chunk);
- if (f == NULL)
- {
- return false;
- }
- return f->SetChunkData(a_Chunk, a_UncompressedSize, a_Data);
-}
-*/
-
-
-
-
-
-bool cWSSCompact::EraseChunkData(const cChunkCoords & a_Chunk)
-{
- cCSLock Lock(m_CS);
- cPAKFile * f = LoadPAKFile(a_Chunk);
- if (f == NULL)
- {
- return false;
- }
- return f->EraseChunkData(a_Chunk);
-}
-
-
-
-
-
-void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World)
-{
- // Load chests
- Json::Value AllChests = a_Value.get("Chests", Json::nullValue);
- if (!AllChests.empty())
- {
- for (Json::Value::iterator itr = AllChests.begin(); itr != AllChests.end(); ++itr )
- {
- Json::Value & Chest = *itr;
- cChestEntity * ChestEntity = new cChestEntity(0,0,0, a_World);
- if (!ChestEntity->LoadFromJson( Chest ) )
- {
- LOGERROR("ERROR READING CHEST FROM JSON!" );
- delete ChestEntity;
- }
- else
- {
- a_BlockEntities.push_back( ChestEntity );
- }
- } // for itr - AllChests[]
- }
-
- // Load furnaces
- Json::Value AllFurnaces = a_Value.get("Furnaces", Json::nullValue);
- if( !AllFurnaces.empty() )
- {
- for( Json::Value::iterator itr = AllFurnaces.begin(); itr != AllFurnaces.end(); ++itr )
- {
- Json::Value & Furnace = *itr;
- cFurnaceEntity * FurnaceEntity = new cFurnaceEntity(0,0,0, a_World);
- if( !FurnaceEntity->LoadFromJson( Furnace ) )
- {
- LOGERROR("ERROR READING FURNACE FROM JSON!" );
- delete FurnaceEntity;
- }
- else
- {
- a_BlockEntities.push_back( FurnaceEntity );
- }
- } // for itr - AllFurnaces[]
- }
-
- // Load signs
- Json::Value AllSigns = a_Value.get("Signs", Json::nullValue);
- if( !AllSigns.empty() )
- {
- for( Json::Value::iterator itr = AllSigns.begin(); itr != AllSigns.end(); ++itr )
- {
- Json::Value & Sign = *itr;
- cSignEntity * SignEntity = new cSignEntity( E_BLOCK_SIGN_POST, 0,0,0, a_World);
- if ( !SignEntity->LoadFromJson( Sign ) )
- {
- LOGERROR("ERROR READING SIGN FROM JSON!" );
- delete SignEntity;
- }
- else
- {
- a_BlockEntities.push_back( SignEntity );
- }
- } // for itr - AllSigns[]
- }
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cWSSCompact::cPAKFile
-
-#define READ(Var) \
- if (f.Read(&Var, sizeof(Var)) != sizeof(Var)) \
- { \
- LOGERROR("ERROR READING %s FROM FILE %s (line %d); file offset %d", #Var, m_FileName.c_str(), __LINE__, f.Tell()); \
- return; \
- }
-
-cWSSCompact::cPAKFile::cPAKFile(const AString & a_FileName, int a_LayerX, int a_LayerZ) :
- m_FileName(a_FileName),
- m_LayerX(a_LayerX),
- m_LayerZ(a_LayerZ),
- m_NumDirty(0),
- m_ChunkVersion( CHUNK_VERSION ), // Init with latest version
- m_PakVersion( PAK_VERSION )
-{
- cFile f;
- if (!f.Open(m_FileName, cFile::fmRead))
- {
- return;
- }
-
- // Read headers:
- READ(m_PakVersion);
- if (m_PakVersion != 1)
- {
- LOGERROR("File \"%s\" is in an unknown pak format (%d)", m_FileName.c_str(), m_PakVersion);
- return;
- }
-
- READ(m_ChunkVersion);
- switch( m_ChunkVersion )
- {
- case 1:
- m_ChunkSize.Set(16, 128, 16);
- break;
- case 2:
- case 3:
- m_ChunkSize.Set(16, 256, 16);
- break;
- default:
- LOGERROR("File \"%s\" is in an unknown chunk format (%d)", m_FileName.c_str(), m_ChunkVersion);
- return;
- };
-
- short NumChunks = 0;
- READ(NumChunks);
-
- // Read chunk headers:
- for (int i = 0; i < NumChunks; i++)
- {
- sChunkHeader * Header = new sChunkHeader;
- READ(*Header);
- m_ChunkHeaders.push_back(Header);
- } // for i - chunk headers
-
- // Read chunk data:
- if (f.ReadRestOfFile(m_DataContents) == -1)
- {
- LOGERROR("Cannot read file \"%s\" contents", m_FileName.c_str());
- return;
- }
-
- if( m_ChunkVersion == 1 ) // Convert chunks to version 2
- {
- UpdateChunk1To2();
- }
-#if AXIS_ORDER == AXIS_ORDER_XZY
- if( m_ChunkVersion == 2 ) // Convert chunks to version 3
- {
- UpdateChunk2To3();
- }
-#endif
-}
-
-
-
-
-
-cWSSCompact::cPAKFile::~cPAKFile()
-{
- if (m_NumDirty > 0)
- {
- SynchronizeFile();
- }
- for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr)
- {
- delete *itr;
- }
-}
-
-
-
-
-
-bool cWSSCompact::cPAKFile::GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data)
-{
- int ChunkX = a_Chunk.m_ChunkX;
- int ChunkZ = a_Chunk.m_ChunkZ;
- sChunkHeader * Header = NULL;
- int Offset = 0;
- for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr)
- {
- if (((*itr)->m_ChunkX == ChunkX) && ((*itr)->m_ChunkZ == ChunkZ))
- {
- Header = *itr;
- break;
- }
- Offset += (*itr)->m_CompressedSize;
- }
- if ((Header == NULL) || (Offset + Header->m_CompressedSize > (int)m_DataContents.size()))
- {
- // Chunk not found / data invalid
- return false;
- }
-
- a_UncompressedSize = Header->m_UncompressedSize;
- a_Data.assign(m_DataContents, Offset, Header->m_CompressedSize);
- return true;
-}
-
-
-
-
-
-bool cWSSCompact::cPAKFile::SaveChunk(const cChunkCoords & a_Chunk, cWorld * a_World)
-{
- if (!SaveChunkToData(a_Chunk, a_World))
- {
- return false;
- }
- if (m_NumDirty > MAX_DIRTY_CHUNKS)
- {
- SynchronizeFile();
- }
- return true;
-}
-
-
-
-
-
-void cWSSCompact::cPAKFile::UpdateChunk1To2()
-{
- int Offset = 0;
- AString NewDataContents;
- int ChunksConverted = 0;
- for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr)
- {
- sChunkHeader * Header = *itr;
-
- if( ChunksConverted % 32 == 0 )
- {
- LOGINFO("Updating \"%s\" version 1 to version 2: %d %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() );
- }
- ChunksConverted++;
-
- AString Data;
- int UncompressedSize = Header->m_UncompressedSize;
- Data.assign(m_DataContents, Offset, Header->m_CompressedSize);
- Offset += Header->m_CompressedSize;
-
- // Crude data integrity check:
- int ExpectedSize = (16*128*16)*2 + (16*128*16)/2; // For version 1
- if (UncompressedSize < ExpectedSize)
- {
- LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing",
- Header->m_ChunkX, Header->m_ChunkZ,
- UncompressedSize, ExpectedSize
- );
- Offset += Header->m_CompressedSize;
- continue;
- }
-
- // Decompress the data:
- AString UncompressedData;
- {
- int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, UncompressedSize);
- if (errorcode != Z_OK)
- {
- LOGERROR("Error %d decompressing data for chunk [%d, %d]",
- errorcode,
- Header->m_ChunkX, Header->m_ChunkZ
- );
- Offset += Header->m_CompressedSize;
- continue;
- }
- }
-
- if (UncompressedSize != (int)UncompressedData.size())
- {
- LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]",
- UncompressedSize, UncompressedData.size(),
- Header->m_ChunkX, Header->m_ChunkZ
- );
- Offset += Header->m_CompressedSize;
- continue;
- }
-
-
- // Old version is 128 blocks high with YZX axis order
- char ConvertedData[cChunkDef::BlockDataSize];
- int Index = 0;
- unsigned int InChunkOffset = 0;
- for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z )
- {
- for( int y = 0; y < 128; ++y )
- {
- ConvertedData[Index++] = UncompressedData[y + z * 128 + x * 128 * 16 + InChunkOffset];
- }
- // Add 128 empty blocks after an old y column
- memset(ConvertedData + Index, E_BLOCK_AIR, 128);
- Index += 128;
- }
- InChunkOffset += (16 * 128 * 16);
- for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Metadata
- {
- for( int y = 0; y < 64; ++y )
- {
- ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset];
- }
- memset(ConvertedData + Index, 0, 64);
- Index += 64;
- }
- InChunkOffset += (16 * 128 * 16) / 2;
- for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Block light
- {
- for( int y = 0; y < 64; ++y )
- {
- ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset];
- }
- memset(ConvertedData + Index, 0, 64);
- Index += 64;
- }
- InChunkOffset += (16*128*16)/2;
- for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Sky light
- {
- for( int y = 0; y < 64; ++y )
- {
- ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset];
- }
- memset(ConvertedData + Index, 0, 64);
- Index += 64;
- }
- InChunkOffset += (16 * 128 * 16) / 2;
-
- AString Converted(ConvertedData, ARRAYCOUNT(ConvertedData));
-
- // Add JSON data afterwards
- if (UncompressedData.size() > InChunkOffset)
- {
- Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end() );
- }
-
- // Re-compress data
- AString CompressedData;
- {
- int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData);
- if (errorcode != Z_OK)
- {
- LOGERROR("Error %d compressing data for chunk [%d, %d]",
- errorcode,
- Header->m_ChunkX, Header->m_ChunkZ
- );
- continue;
- }
- }
-
- // Save into file's cache
- Header->m_UncompressedSize = Converted.size();
- Header->m_CompressedSize = CompressedData.size();
- NewDataContents.append( CompressedData );
- }
-
- // Done converting
- m_DataContents = NewDataContents;
- m_ChunkVersion = 2;
- SynchronizeFile();
-
- LOGINFO("Updated \"%s\" version 1 to version 2", m_FileName.c_str() );
-}
-
-
-
-
-
-void cWSSCompact::cPAKFile::UpdateChunk2To3()
-{
- int Offset = 0;
- AString NewDataContents;
- int ChunksConverted = 0;
- for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr)
- {
- sChunkHeader * Header = *itr;
-
- if( ChunksConverted % 32 == 0 )
- {
- LOGINFO("Updating \"%s\" version 2 to version 3: %d %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() );
- }
- ChunksConverted++;
-
- AString Data;
- int UncompressedSize = Header->m_UncompressedSize;
- Data.assign(m_DataContents, Offset, Header->m_CompressedSize);
- Offset += Header->m_CompressedSize;
-
- // Crude data integrity check:
- const int ExpectedSize = (16*256*16)*2 + (16*256*16)/2; // For version 2
- if (UncompressedSize < ExpectedSize)
- {
- LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing",
- Header->m_ChunkX, Header->m_ChunkZ,
- UncompressedSize, ExpectedSize
- );
- Offset += Header->m_CompressedSize;
- continue;
- }
-
- // Decompress the data:
- AString UncompressedData;
- {
- int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, UncompressedSize);
- if (errorcode != Z_OK)
- {
- LOGERROR("Error %d decompressing data for chunk [%d, %d]",
- errorcode,
- Header->m_ChunkX, Header->m_ChunkZ
- );
- Offset += Header->m_CompressedSize;
- continue;
- }
- }
-
- if (UncompressedSize != (int)UncompressedData.size())
- {
- LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]",
- UncompressedSize, UncompressedData.size(),
- Header->m_ChunkX, Header->m_ChunkZ
- );
- Offset += Header->m_CompressedSize;
- continue;
- }
-
- char ConvertedData[ExpectedSize];
- memset(ConvertedData, 0, ExpectedSize);
-
- // Cannot use cChunk::MakeIndex because it might change again?????????
- // For compatibility, use what we know is current
- #define MAKE_2_INDEX( x, y, z ) ( y + (z * 256) + (x * 256 * 16) )
- #define MAKE_3_INDEX( x, y, z ) ( x + (z * 16) + (y * 16 * 16) )
-
- unsigned int InChunkOffset = 0;
- for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) // YZX Loop order is important, in 1.1 Y was first then Z then X
- {
- ConvertedData[ MAKE_3_INDEX(x, y, z) ] = UncompressedData[InChunkOffset];
- ++InChunkOffset;
- } // for y, z, x
-
-
- unsigned int index2 = 0;
- for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y )
- {
- ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4);
- ++index2;
- }
- InChunkOffset += index2 / 2;
- index2 = 0;
-
- for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y )
- {
- ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4);
- ++index2;
- }
- InChunkOffset += index2 / 2;
- index2 = 0;
-
- for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y )
- {
- ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4);
- ++index2;
- }
- InChunkOffset += index2 / 2;
- index2 = 0;
-
- AString Converted(ConvertedData, ExpectedSize);
-
- // Add JSON data afterwards
- if (UncompressedData.size() > InChunkOffset)
- {
- Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end() );
- }
-
- // Re-compress data
- AString CompressedData;
- {
- int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData);
- if (errorcode != Z_OK)
- {
- LOGERROR("Error %d compressing data for chunk [%d, %d]",
- errorcode,
- Header->m_ChunkX, Header->m_ChunkZ
- );
- continue;
- }
- }
-
- // Save into file's cache
- Header->m_UncompressedSize = Converted.size();
- Header->m_CompressedSize = CompressedData.size();
- NewDataContents.append( CompressedData );
- }
-
- // Done converting
- m_DataContents = NewDataContents;
- m_ChunkVersion = 3;
- SynchronizeFile();
-
- LOGINFO("Updated \"%s\" version 2 to version 3", m_FileName.c_str() );
-}
-
-
-
-
-
-bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, const AString & a_Data, cWorld * a_World)
-{
- // Crude data integrity check:
- if (a_UncompressedSize < cChunkDef::BlockDataSize)
- {
- LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing",
- a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ,
- a_UncompressedSize, cChunkDef::BlockDataSize
- );
- EraseChunkData(a_Chunk);
- return false;
- }
-
- // Decompress the data:
- AString UncompressedData;
- int errorcode = UncompressString(a_Data.data(), a_Data.size(), UncompressedData, a_UncompressedSize);
- if (errorcode != Z_OK)
- {
- LOGERROR("Error %d decompressing data for chunk [%d, %d]",
- errorcode,
- a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ
- );
- return false;
- }
-
- if (a_UncompressedSize != (int)UncompressedData.size())
- {
- LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]",
- a_UncompressedSize, UncompressedData.size(),
- a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ
- );
- return false;
- }
-
- cEntityList Entities;
- cBlockEntityList BlockEntities;
- bool IsLightValid = false;
-
- if (a_UncompressedSize > cChunkDef::BlockDataSize)
- {
- Json::Value root; // will contain the root value after parsing.
- Json::Reader reader;
- if ( !reader.parse( UncompressedData.data() + cChunkDef::BlockDataSize, root, false ) )
- {
- LOGERROR("Failed to parse trailing JSON in chunk [%d, %d]!",
- a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ
- );
- }
- else
- {
- LoadEntitiesFromJson(root, Entities, BlockEntities, a_World);
- IsLightValid = root.get("IsLightValid", false).asBool();
- }
- }
-
- BLOCKTYPE * BlockData = (BLOCKTYPE *)UncompressedData.data();
- NIBBLETYPE * MetaData = (NIBBLETYPE *)(BlockData + cChunkDef::MetaOffset);
- NIBBLETYPE * BlockLight = (NIBBLETYPE *)(BlockData + cChunkDef::LightOffset);
- NIBBLETYPE * SkyLight = (NIBBLETYPE *)(BlockData + cChunkDef::SkyLightOffset);
-
- a_World->SetChunkData(
- a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ,
- BlockData, MetaData,
- IsLightValid ? BlockLight : NULL,
- IsLightValid ? SkyLight : NULL,
- NULL, NULL,
- Entities, BlockEntities,
- false
- );
-
- return true;
-}
-
-
-
-
-
-bool cWSSCompact::cPAKFile::EraseChunkData(const cChunkCoords & a_Chunk)
-{
- int ChunkX = a_Chunk.m_ChunkX;
- int ChunkZ = a_Chunk.m_ChunkZ;
- int Offset = 0;
- for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr)
- {
- if (((*itr)->m_ChunkX == ChunkX) && ((*itr)->m_ChunkZ == ChunkZ))
- {
- m_DataContents.erase(Offset, (*itr)->m_CompressedSize);
- delete *itr;
- itr = m_ChunkHeaders.erase(itr);
- return true;
- }
- Offset += (*itr)->m_CompressedSize;
- }
-
- return false;
-}
-
-
-
-
-
-bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World)
-{
- // Serialize the chunk:
- cJsonChunkSerializer Serializer;
- if (!a_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, Serializer))
- {
- // Chunk not valid
- LOG("cWSSCompact: Trying to save chunk [%d, %d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ);
- return false;
- }
-
- AString Data;
- Data.assign((const char *)Serializer.GetBlockData(), cChunkDef::BlockDataSize);
- if (Serializer.HasJsonData())
- {
- AString JsonData;
- Json::StyledWriter writer;
- JsonData = writer.write(Serializer.GetRoot());
- Data.append(JsonData);
- }
-
- // Compress the data:
- AString CompressedData;
- int errorcode = CompressString(Data.data(), Data.size(), CompressedData);
- if ( errorcode != Z_OK )
- {
- LOGERROR("Error %i compressing data for chunk [%d, %d, %d]", errorcode, a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ);
- return false;
- }
-
- // Erase any existing data for the chunk:
- EraseChunkData(a_Chunk);
-
- // Save the header:
- sChunkHeader * Header = new sChunkHeader;
- if (Header == NULL)
- {
- LOGWARNING("Cannot create a new chunk header to save chunk [%d, %d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ);
- return false;
- }
- Header->m_CompressedSize = (int)CompressedData.size();
- Header->m_ChunkX = a_Chunk.m_ChunkX;
- Header->m_ChunkZ = a_Chunk.m_ChunkZ;
- Header->m_UncompressedSize = (int)Data.size();
- m_ChunkHeaders.push_back(Header);
-
- m_DataContents.append(CompressedData.data(), CompressedData.size());
-
- m_NumDirty++;
- return true;
-}
-
-
-
-
-
-#define WRITE(Var) \
- if (f.Write(&Var, sizeof(Var)) != sizeof(Var)) \
- { \
- LOGERROR("cWSSCompact: ERROR writing %s to file \"%s\" (line %d); file offset %d", #Var, m_FileName.c_str(), __LINE__, f.Tell()); \
- return; \
- }
-
-void cWSSCompact::cPAKFile::SynchronizeFile(void)
-{
- cFile f;
- if (!f.Open(m_FileName, cFile::fmWrite))
- {
- LOGERROR("Cannot open PAK file \"%s\" for writing", m_FileName.c_str());
- return;
- }
-
- WRITE(m_PakVersion);
- WRITE(m_ChunkVersion);
- short NumChunks = (short)m_ChunkHeaders.size();
- WRITE(NumChunks);
- for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr)
- {
- WRITE(**itr);
- }
- if (f.Write(m_DataContents.data(), m_DataContents.size()) != (int)m_DataContents.size())
- {
- LOGERROR("cWSSCompact: ERROR writing chunk contents to file \"%s\" (line %d); file offset %d", m_FileName.c_str(), __LINE__, f.Tell());
- return;
- }
- m_NumDirty = 0;
-}
-
-
-
-
+ +// WSSCompact.cpp + +// Interfaces to the cWSSCompact class representing the "compact" storage schema (PAK-files) + +#include "Globals.h" +#include "WSSCompact.h" +#include "cWorld.h" +#include "zlib.h" +#include <json/json.h> +#include "StringCompression.h" +#include "cChestEntity.h" +#include "cSignEntity.h" +#include "cFurnaceEntity.h" +#include "BlockID.h" + + + + + +#pragma pack(push, 1) +/// The chunk header, as stored in the file: +struct cWSSCompact::sChunkHeader +{ + int m_ChunkX; + int m_ChunkZ; + int m_CompressedSize; + int m_UncompressedSize; +} ; +#pragma pack(pop) + + + + + +/// The maximum number of PAK files that are cached +const int MAX_PAK_FILES = 16; + +/// The maximum number of unsaved chunks before the cPAKFile saves them to disk +const int MAX_DIRTY_CHUNKS = 16; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cJsonChunkSerializer: + +cJsonChunkSerializer::cJsonChunkSerializer(void) : + m_HasJsonData(false) +{ +} + + + + + +void cJsonChunkSerializer::Entity(cEntity * a_Entity) +{ + // TODO: a_Entity->SaveToJson(m_Root); +} + + + + + +void cJsonChunkSerializer::BlockEntity(cBlockEntity * a_BlockEntity) +{ + const char * SaveInto = NULL; + switch (a_BlockEntity->GetBlockType()) + { + case E_BLOCK_CHEST: SaveInto = "Chests"; break; + case E_BLOCK_FURNACE: SaveInto = "Furnaces"; break; + case E_BLOCK_SIGN_POST: SaveInto = "Signs"; break; + case E_BLOCK_WALLSIGN: SaveInto = "Signs"; break; + + default: + { + ASSERT(!"Unhandled blocktype in BlockEntities list while saving to JSON"); + break; + } + } // switch (BlockEntity->GetBlockType()) + if (SaveInto == NULL) + { + return; + } + + Json::Value val; + a_BlockEntity->SaveToJson(val); + m_Root[SaveInto].append(val); + m_HasJsonData = true; +} + + + + + +bool cJsonChunkSerializer::LightIsValid(bool a_IsLightValid) +{ + if (!a_IsLightValid) + { + return false; + } + m_Root["IsLightValid"] = true; + m_HasJsonData = true; + return true; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWSSCompact: + +cWSSCompact::~cWSSCompact() +{ + for (cPAKFiles::iterator itr = m_PAKFiles.begin(); itr != m_PAKFiles.end(); ++itr) + { + delete *itr; + } +} + + + + + +bool cWSSCompact::LoadChunk(const cChunkCoords & a_Chunk) +{ + AString ChunkData; + int UncompressedSize = 0; + if (!GetChunkData(a_Chunk, UncompressedSize, ChunkData)) + { + // The reason for failure is already printed in GetChunkData() + return false; + } + + return LoadChunkFromData(a_Chunk, UncompressedSize, ChunkData, m_World); +} + + + + + +bool cWSSCompact::SaveChunk(const cChunkCoords & a_Chunk) +{ + cCSLock Lock(m_CS); + + cPAKFile * f = LoadPAKFile(a_Chunk); + if (f == NULL) + { + // For some reason we couldn't locate the file + LOG("Cannot locate a proper PAK file for chunk [%d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); + return false; + } + return f->SaveChunk(a_Chunk, m_World); +} + + + + + +cWSSCompact::cPAKFile * cWSSCompact::LoadPAKFile(const cChunkCoords & a_Chunk) +{ + // ASSUMES that m_CS has been locked + + // We need to retain this weird conversion code, because some edge chunks are in the wrong PAK file + const int LayerX = (int)(floorf((float)a_Chunk.m_ChunkX / 32.0f)); + const int LayerZ = (int)(floorf((float)a_Chunk.m_ChunkZ / 32.0f)); + + // Is it already cached? + for (cPAKFiles::iterator itr = m_PAKFiles.begin(); itr != m_PAKFiles.end(); ++itr) + { + if (((*itr) != NULL) && ((*itr)->GetLayerX() == LayerX) && ((*itr)->GetLayerZ() == LayerZ)) + { + // Move the file to front and return it: + cPAKFile * f = *itr; + if (itr != m_PAKFiles.begin()) + { + m_PAKFiles.erase(itr); + m_PAKFiles.push_front(f); + } + return f; + } + } + + // Load it anew: + AString FileName; + Printf(FileName, "%s/X%i_Z%i.pak", m_World->GetName().c_str(), LayerX, LayerZ ); + cPAKFile * f = new cPAKFile(FileName, LayerX, LayerZ); + if (f == NULL) + { + return NULL; + } + m_PAKFiles.push_front(f); + + // If there are too many PAK files cached, delete the last one used: + if (m_PAKFiles.size() > MAX_PAK_FILES) + { + delete m_PAKFiles.back(); + m_PAKFiles.pop_back(); + } + return f; +} + + + + + +bool cWSSCompact::GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data) +{ + cCSLock Lock(m_CS); + cPAKFile * f = LoadPAKFile(a_Chunk); + if (f == NULL) + { + return false; + } + return f->GetChunkData(a_Chunk, a_UncompressedSize, a_Data); +} + + + + + +/* +// TODO: Rewrite saving to use the same principles as loading +bool cWSSCompact::SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data) +{ + cCSLock Lock(m_CS); + cPAKFile * f = LoadPAKFile(a_Chunk); + if (f == NULL) + { + return false; + } + return f->SetChunkData(a_Chunk, a_UncompressedSize, a_Data); +} +*/ + + + + + +bool cWSSCompact::EraseChunkData(const cChunkCoords & a_Chunk) +{ + cCSLock Lock(m_CS); + cPAKFile * f = LoadPAKFile(a_Chunk); + if (f == NULL) + { + return false; + } + return f->EraseChunkData(a_Chunk); +} + + + + + +void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World) +{ + // Load chests + Json::Value AllChests = a_Value.get("Chests", Json::nullValue); + if (!AllChests.empty()) + { + for (Json::Value::iterator itr = AllChests.begin(); itr != AllChests.end(); ++itr ) + { + Json::Value & Chest = *itr; + cChestEntity * ChestEntity = new cChestEntity(0,0,0, a_World); + if (!ChestEntity->LoadFromJson( Chest ) ) + { + LOGERROR("ERROR READING CHEST FROM JSON!" ); + delete ChestEntity; + } + else + { + a_BlockEntities.push_back( ChestEntity ); + } + } // for itr - AllChests[] + } + + // Load furnaces + Json::Value AllFurnaces = a_Value.get("Furnaces", Json::nullValue); + if( !AllFurnaces.empty() ) + { + for( Json::Value::iterator itr = AllFurnaces.begin(); itr != AllFurnaces.end(); ++itr ) + { + Json::Value & Furnace = *itr; + cFurnaceEntity * FurnaceEntity = new cFurnaceEntity(0,0,0, a_World); + if( !FurnaceEntity->LoadFromJson( Furnace ) ) + { + LOGERROR("ERROR READING FURNACE FROM JSON!" ); + delete FurnaceEntity; + } + else + { + a_BlockEntities.push_back( FurnaceEntity ); + } + } // for itr - AllFurnaces[] + } + + // Load signs + Json::Value AllSigns = a_Value.get("Signs", Json::nullValue); + if( !AllSigns.empty() ) + { + for( Json::Value::iterator itr = AllSigns.begin(); itr != AllSigns.end(); ++itr ) + { + Json::Value & Sign = *itr; + cSignEntity * SignEntity = new cSignEntity( E_BLOCK_SIGN_POST, 0,0,0, a_World); + if ( !SignEntity->LoadFromJson( Sign ) ) + { + LOGERROR("ERROR READING SIGN FROM JSON!" ); + delete SignEntity; + } + else + { + a_BlockEntities.push_back( SignEntity ); + } + } // for itr - AllSigns[] + } +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWSSCompact::cPAKFile + +#define READ(Var) \ + if (f.Read(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("ERROR READING %s FROM FILE %s (line %d); file offset %d", #Var, m_FileName.c_str(), __LINE__, f.Tell()); \ + return; \ + } + +cWSSCompact::cPAKFile::cPAKFile(const AString & a_FileName, int a_LayerX, int a_LayerZ) : + m_FileName(a_FileName), + m_LayerX(a_LayerX), + m_LayerZ(a_LayerZ), + m_NumDirty(0), + m_ChunkVersion( CHUNK_VERSION ), // Init with latest version + m_PakVersion( PAK_VERSION ) +{ + cFile f; + if (!f.Open(m_FileName, cFile::fmRead)) + { + return; + } + + // Read headers: + READ(m_PakVersion); + if (m_PakVersion != 1) + { + LOGERROR("File \"%s\" is in an unknown pak format (%d)", m_FileName.c_str(), m_PakVersion); + return; + } + + READ(m_ChunkVersion); + switch( m_ChunkVersion ) + { + case 1: + m_ChunkSize.Set(16, 128, 16); + break; + case 2: + case 3: + m_ChunkSize.Set(16, 256, 16); + break; + default: + LOGERROR("File \"%s\" is in an unknown chunk format (%d)", m_FileName.c_str(), m_ChunkVersion); + return; + }; + + short NumChunks = 0; + READ(NumChunks); + + // Read chunk headers: + for (int i = 0; i < NumChunks; i++) + { + sChunkHeader * Header = new sChunkHeader; + READ(*Header); + m_ChunkHeaders.push_back(Header); + } // for i - chunk headers + + // Read chunk data: + if (f.ReadRestOfFile(m_DataContents) == -1) + { + LOGERROR("Cannot read file \"%s\" contents", m_FileName.c_str()); + return; + } + + if( m_ChunkVersion == 1 ) // Convert chunks to version 2 + { + UpdateChunk1To2(); + } +#if AXIS_ORDER == AXIS_ORDER_XZY + if( m_ChunkVersion == 2 ) // Convert chunks to version 3 + { + UpdateChunk2To3(); + } +#endif +} + + + + + +cWSSCompact::cPAKFile::~cPAKFile() +{ + if (m_NumDirty > 0) + { + SynchronizeFile(); + } + for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) + { + delete *itr; + } +} + + + + + +bool cWSSCompact::cPAKFile::GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data) +{ + int ChunkX = a_Chunk.m_ChunkX; + int ChunkZ = a_Chunk.m_ChunkZ; + sChunkHeader * Header = NULL; + int Offset = 0; + for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) + { + if (((*itr)->m_ChunkX == ChunkX) && ((*itr)->m_ChunkZ == ChunkZ)) + { + Header = *itr; + break; + } + Offset += (*itr)->m_CompressedSize; + } + if ((Header == NULL) || (Offset + Header->m_CompressedSize > (int)m_DataContents.size())) + { + // Chunk not found / data invalid + return false; + } + + a_UncompressedSize = Header->m_UncompressedSize; + a_Data.assign(m_DataContents, Offset, Header->m_CompressedSize); + return true; +} + + + + + +bool cWSSCompact::cPAKFile::SaveChunk(const cChunkCoords & a_Chunk, cWorld * a_World) +{ + if (!SaveChunkToData(a_Chunk, a_World)) + { + return false; + } + if (m_NumDirty > MAX_DIRTY_CHUNKS) + { + SynchronizeFile(); + } + return true; +} + + + + + +void cWSSCompact::cPAKFile::UpdateChunk1To2() +{ + int Offset = 0; + AString NewDataContents; + int ChunksConverted = 0; + for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) + { + sChunkHeader * Header = *itr; + + if( ChunksConverted % 32 == 0 ) + { + LOGINFO("Updating \"%s\" version 1 to version 2: %d %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() ); + } + ChunksConverted++; + + AString Data; + int UncompressedSize = Header->m_UncompressedSize; + Data.assign(m_DataContents, Offset, Header->m_CompressedSize); + Offset += Header->m_CompressedSize; + + // Crude data integrity check: + int ExpectedSize = (16*128*16)*2 + (16*128*16)/2; // For version 1 + if (UncompressedSize < ExpectedSize) + { + LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", + Header->m_ChunkX, Header->m_ChunkZ, + UncompressedSize, ExpectedSize + ); + Offset += Header->m_CompressedSize; + continue; + } + + // Decompress the data: + AString UncompressedData; + { + int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, UncompressedSize); + if (errorcode != Z_OK) + { + LOGERROR("Error %d decompressing data for chunk [%d, %d]", + errorcode, + Header->m_ChunkX, Header->m_ChunkZ + ); + Offset += Header->m_CompressedSize; + continue; + } + } + + if (UncompressedSize != (int)UncompressedData.size()) + { + LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]", + UncompressedSize, UncompressedData.size(), + Header->m_ChunkX, Header->m_ChunkZ + ); + Offset += Header->m_CompressedSize; + continue; + } + + + // Old version is 128 blocks high with YZX axis order + char ConvertedData[cChunkDef::BlockDataSize]; + int Index = 0; + unsigned int InChunkOffset = 0; + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) + { + for( int y = 0; y < 128; ++y ) + { + ConvertedData[Index++] = UncompressedData[y + z * 128 + x * 128 * 16 + InChunkOffset]; + } + // Add 128 empty blocks after an old y column + memset(ConvertedData + Index, E_BLOCK_AIR, 128); + Index += 128; + } + InChunkOffset += (16 * 128 * 16); + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Metadata + { + for( int y = 0; y < 64; ++y ) + { + ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; + } + memset(ConvertedData + Index, 0, 64); + Index += 64; + } + InChunkOffset += (16 * 128 * 16) / 2; + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Block light + { + for( int y = 0; y < 64; ++y ) + { + ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; + } + memset(ConvertedData + Index, 0, 64); + Index += 64; + } + InChunkOffset += (16*128*16)/2; + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Sky light + { + for( int y = 0; y < 64; ++y ) + { + ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; + } + memset(ConvertedData + Index, 0, 64); + Index += 64; + } + InChunkOffset += (16 * 128 * 16) / 2; + + AString Converted(ConvertedData, ARRAYCOUNT(ConvertedData)); + + // Add JSON data afterwards + if (UncompressedData.size() > InChunkOffset) + { + Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end() ); + } + + // Re-compress data + AString CompressedData; + { + int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData); + if (errorcode != Z_OK) + { + LOGERROR("Error %d compressing data for chunk [%d, %d]", + errorcode, + Header->m_ChunkX, Header->m_ChunkZ + ); + continue; + } + } + + // Save into file's cache + Header->m_UncompressedSize = Converted.size(); + Header->m_CompressedSize = CompressedData.size(); + NewDataContents.append( CompressedData ); + } + + // Done converting + m_DataContents = NewDataContents; + m_ChunkVersion = 2; + SynchronizeFile(); + + LOGINFO("Updated \"%s\" version 1 to version 2", m_FileName.c_str() ); +} + + + + + +void cWSSCompact::cPAKFile::UpdateChunk2To3() +{ + int Offset = 0; + AString NewDataContents; + int ChunksConverted = 0; + for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) + { + sChunkHeader * Header = *itr; + + if( ChunksConverted % 32 == 0 ) + { + LOGINFO("Updating \"%s\" version 2 to version 3: %d %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() ); + } + ChunksConverted++; + + AString Data; + int UncompressedSize = Header->m_UncompressedSize; + Data.assign(m_DataContents, Offset, Header->m_CompressedSize); + Offset += Header->m_CompressedSize; + + // Crude data integrity check: + const int ExpectedSize = (16*256*16)*2 + (16*256*16)/2; // For version 2 + if (UncompressedSize < ExpectedSize) + { + LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", + Header->m_ChunkX, Header->m_ChunkZ, + UncompressedSize, ExpectedSize + ); + Offset += Header->m_CompressedSize; + continue; + } + + // Decompress the data: + AString UncompressedData; + { + int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, UncompressedSize); + if (errorcode != Z_OK) + { + LOGERROR("Error %d decompressing data for chunk [%d, %d]", + errorcode, + Header->m_ChunkX, Header->m_ChunkZ + ); + Offset += Header->m_CompressedSize; + continue; + } + } + + if (UncompressedSize != (int)UncompressedData.size()) + { + LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]", + UncompressedSize, UncompressedData.size(), + Header->m_ChunkX, Header->m_ChunkZ + ); + Offset += Header->m_CompressedSize; + continue; + } + + char ConvertedData[ExpectedSize]; + memset(ConvertedData, 0, ExpectedSize); + + // Cannot use cChunk::MakeIndex because it might change again????????? + // For compatibility, use what we know is current + #define MAKE_2_INDEX( x, y, z ) ( y + (z * 256) + (x * 256 * 16) ) + #define MAKE_3_INDEX( x, y, z ) ( x + (z * 16) + (y * 16 * 16) ) + + unsigned int InChunkOffset = 0; + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) // YZX Loop order is important, in 1.1 Y was first then Z then X + { + ConvertedData[ MAKE_3_INDEX(x, y, z) ] = UncompressedData[InChunkOffset]; + ++InChunkOffset; + } // for y, z, x + + + unsigned int index2 = 0; + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) + { + ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4); + ++index2; + } + InChunkOffset += index2 / 2; + index2 = 0; + + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) + { + ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4); + ++index2; + } + InChunkOffset += index2 / 2; + index2 = 0; + + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) + { + ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4); + ++index2; + } + InChunkOffset += index2 / 2; + index2 = 0; + + AString Converted(ConvertedData, ExpectedSize); + + // Add JSON data afterwards + if (UncompressedData.size() > InChunkOffset) + { + Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end() ); + } + + // Re-compress data + AString CompressedData; + { + int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData); + if (errorcode != Z_OK) + { + LOGERROR("Error %d compressing data for chunk [%d, %d]", + errorcode, + Header->m_ChunkX, Header->m_ChunkZ + ); + continue; + } + } + + // Save into file's cache + Header->m_UncompressedSize = Converted.size(); + Header->m_CompressedSize = CompressedData.size(); + NewDataContents.append( CompressedData ); + } + + // Done converting + m_DataContents = NewDataContents; + m_ChunkVersion = 3; + SynchronizeFile(); + + LOGINFO("Updated \"%s\" version 2 to version 3", m_FileName.c_str() ); +} + + + + + +bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, const AString & a_Data, cWorld * a_World) +{ + // Crude data integrity check: + if (a_UncompressedSize < cChunkDef::BlockDataSize) + { + LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", + a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, + a_UncompressedSize, cChunkDef::BlockDataSize + ); + EraseChunkData(a_Chunk); + return false; + } + + // Decompress the data: + AString UncompressedData; + int errorcode = UncompressString(a_Data.data(), a_Data.size(), UncompressedData, a_UncompressedSize); + if (errorcode != Z_OK) + { + LOGERROR("Error %d decompressing data for chunk [%d, %d]", + errorcode, + a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ + ); + return false; + } + + if (a_UncompressedSize != (int)UncompressedData.size()) + { + LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]", + a_UncompressedSize, UncompressedData.size(), + a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ + ); + return false; + } + + cEntityList Entities; + cBlockEntityList BlockEntities; + bool IsLightValid = false; + + if (a_UncompressedSize > cChunkDef::BlockDataSize) + { + Json::Value root; // will contain the root value after parsing. + Json::Reader reader; + if ( !reader.parse( UncompressedData.data() + cChunkDef::BlockDataSize, root, false ) ) + { + LOGERROR("Failed to parse trailing JSON in chunk [%d, %d]!", + a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ + ); + } + else + { + LoadEntitiesFromJson(root, Entities, BlockEntities, a_World); + IsLightValid = root.get("IsLightValid", false).asBool(); + } + } + + BLOCKTYPE * BlockData = (BLOCKTYPE *)UncompressedData.data(); + NIBBLETYPE * MetaData = (NIBBLETYPE *)(BlockData + cChunkDef::MetaOffset); + NIBBLETYPE * BlockLight = (NIBBLETYPE *)(BlockData + cChunkDef::LightOffset); + NIBBLETYPE * SkyLight = (NIBBLETYPE *)(BlockData + cChunkDef::SkyLightOffset); + + a_World->SetChunkData( + a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, + BlockData, MetaData, + IsLightValid ? BlockLight : NULL, + IsLightValid ? SkyLight : NULL, + NULL, NULL, + Entities, BlockEntities, + false + ); + + return true; +} + + + + + +bool cWSSCompact::cPAKFile::EraseChunkData(const cChunkCoords & a_Chunk) +{ + int ChunkX = a_Chunk.m_ChunkX; + int ChunkZ = a_Chunk.m_ChunkZ; + int Offset = 0; + for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) + { + if (((*itr)->m_ChunkX == ChunkX) && ((*itr)->m_ChunkZ == ChunkZ)) + { + m_DataContents.erase(Offset, (*itr)->m_CompressedSize); + delete *itr; + itr = m_ChunkHeaders.erase(itr); + return true; + } + Offset += (*itr)->m_CompressedSize; + } + + return false; +} + + + + + +bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World) +{ + // Serialize the chunk: + cJsonChunkSerializer Serializer; + if (!a_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, Serializer)) + { + // Chunk not valid + LOG("cWSSCompact: Trying to save chunk [%d, %d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); + return false; + } + + AString Data; + Data.assign((const char *)Serializer.GetBlockData(), cChunkDef::BlockDataSize); + if (Serializer.HasJsonData()) + { + AString JsonData; + Json::StyledWriter writer; + JsonData = writer.write(Serializer.GetRoot()); + Data.append(JsonData); + } + + // Compress the data: + AString CompressedData; + int errorcode = CompressString(Data.data(), Data.size(), CompressedData); + if ( errorcode != Z_OK ) + { + LOGERROR("Error %i compressing data for chunk [%d, %d, %d]", errorcode, a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); + return false; + } + + // Erase any existing data for the chunk: + EraseChunkData(a_Chunk); + + // Save the header: + sChunkHeader * Header = new sChunkHeader; + if (Header == NULL) + { + LOGWARNING("Cannot create a new chunk header to save chunk [%d, %d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); + return false; + } + Header->m_CompressedSize = (int)CompressedData.size(); + Header->m_ChunkX = a_Chunk.m_ChunkX; + Header->m_ChunkZ = a_Chunk.m_ChunkZ; + Header->m_UncompressedSize = (int)Data.size(); + m_ChunkHeaders.push_back(Header); + + m_DataContents.append(CompressedData.data(), CompressedData.size()); + + m_NumDirty++; + return true; +} + + + + + +#define WRITE(Var) \ + if (f.Write(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("cWSSCompact: ERROR writing %s to file \"%s\" (line %d); file offset %d", #Var, m_FileName.c_str(), __LINE__, f.Tell()); \ + return; \ + } + +void cWSSCompact::cPAKFile::SynchronizeFile(void) +{ + cFile f; + if (!f.Open(m_FileName, cFile::fmWrite)) + { + LOGERROR("Cannot open PAK file \"%s\" for writing", m_FileName.c_str()); + return; + } + + WRITE(m_PakVersion); + WRITE(m_ChunkVersion); + short NumChunks = (short)m_ChunkHeaders.size(); + WRITE(NumChunks); + for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) + { + WRITE(**itr); + } + if (f.Write(m_DataContents.data(), m_DataContents.size()) != (int)m_DataContents.size()) + { + LOGERROR("cWSSCompact: ERROR writing chunk contents to file \"%s\" (line %d); file offset %d", m_FileName.c_str(), __LINE__, f.Tell()); + return; + } + m_NumDirty = 0; +} + + + + diff --git a/source/WSSCompact.h b/source/WSSCompact.h index 512cb7e5b..192d0f4b8 100644 --- a/source/WSSCompact.h +++ b/source/WSSCompact.h @@ -1,144 +1,144 @@ -
-// WSSCompact.h
-
-// Interfaces to the cWSSCompact class representing the "Compact" storage schema (PAK-files)
-
-
-
-
-
-#pragma once
-#ifndef WSSCOMPACT_H_INCLUDED
-#define WSSCOMPACT_H_INCLUDED
-
-#include "WorldStorage.h"
-#include "Vector3i.h"
-
-
-
-
-
-/// Helper class for serializing a chunk into Json
-class cJsonChunkSerializer :
- public cChunkDataCollector
-{
-public:
-
- cJsonChunkSerializer(void);
-
- Json::Value & GetRoot (void) {return m_Root; }
- BLOCKTYPE * GetBlockData(void) {return m_BlockData; }
- bool HasJsonData (void) const {return m_HasJsonData; }
-
-protected:
-
- // NOTE: block data is serialized into inherited cChunkDataCollector's m_BlockData[] array
-
- // Entities and BlockEntities are serialized to Json
- Json::Value m_Root;
- bool m_HasJsonData;
-
- // cChunkDataCollector overrides:
- virtual void Entity (cEntity * a_Entity) override;
- virtual void BlockEntity (cBlockEntity * a_Entity) override;
- virtual bool LightIsValid (bool a_IsLightValid) override;
-} ;
-
-
-
-
-
-class cWSSCompact :
- public cWSSchema
-{
-public:
- cWSSCompact(cWorld * a_World) : cWSSchema(a_World) {}
- virtual ~cWSSCompact();
-
-protected:
-
- struct sChunkHeader;
- typedef std::vector<sChunkHeader *> sChunkHeaders;
-
- /// Implements a cache for a single PAK file; implements lazy-write in order to be able to write multiple chunks fast
- class cPAKFile
- {
- public:
-
- cPAKFile(const AString & a_FileName, int a_LayerX, int a_LayerZ);
- ~cPAKFile();
-
- bool GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data);
- bool SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data);
- bool EraseChunkData(const cChunkCoords & a_Chunk);
-
- bool SaveChunk(const cChunkCoords & a_Chunk, cWorld * a_World);
-
- int GetLayerX(void) const {return m_LayerX; }
- int GetLayerZ(void) const {return m_LayerZ; }
-
- static const int PAK_VERSION = 1;
-#if AXIS_ORDER == AXIS_ORDER_XZY
- static const int CHUNK_VERSION = 3;
-#elif AXIS_ORDER == AXIS_ORDER_YZX
- static const int CHUNK_VERSION = 2;
-#endif
- protected:
-
- AString m_FileName;
- int m_LayerX;
- int m_LayerZ;
-
- sChunkHeaders m_ChunkHeaders;
- AString m_DataContents; // Data contents of the file, cached
-
- int m_NumDirty; // Number of chunks that were written into m_DataContents but not into the file
-
- Vector3i m_ChunkSize; // Is related to m_ChunkVersion
- char m_ChunkVersion;
- char m_PakVersion;
-
- bool SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World); // Saves the chunk to m_DataContents, updates headers and m_NumDirty
- void SynchronizeFile(void); // Writes m_DataContents along with the headers to file, resets m_NumDirty
-
- void UpdateChunk1To2(void); // Height from 128 to 256
- void UpdateChunk2To3(void); // Axis order from YZX to XZY
- } ;
-
- typedef std::list<cPAKFile *> cPAKFiles;
-
- cCriticalSection m_CS;
- cPAKFiles m_PAKFiles; // A MRU cache of PAK files
-
- /// Loads the correct PAK file either from cache or from disk, manages the m_PAKFiles cache
- cPAKFile * LoadPAKFile(const cChunkCoords & a_Chunk);
-
- /// Gets chunk data from the correct file; locks CS as needed
- bool GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data);
-
- /// Sets chunk data to the correct file; locks CS as needed
- bool SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data);
-
- /// Erases chunk data from the correct file; locks CS as needed
- bool EraseChunkData(const cChunkCoords & a_Chunk);
-
- /// Loads the chunk from the data (no locking needed)
- bool LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, const AString & a_Data, cWorld * a_World);
-
- void LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World);
-
- // cWSSchema overrides:
- virtual bool LoadChunk(const cChunkCoords & a_Chunk) override;
- virtual bool SaveChunk(const cChunkCoords & a_Chunk) override;
- virtual const AString GetName(void) const override {return "compact"; }
-} ;
-
-
-
-
-
-#endif // WSSCOMPACT_H_INCLUDED
-
-
-
-
+ +// WSSCompact.h + +// Interfaces to the cWSSCompact class representing the "Compact" storage schema (PAK-files) + + + + + +#pragma once +#ifndef WSSCOMPACT_H_INCLUDED +#define WSSCOMPACT_H_INCLUDED + +#include "WorldStorage.h" +#include "Vector3i.h" + + + + + +/// Helper class for serializing a chunk into Json +class cJsonChunkSerializer : + public cChunkDataCollector +{ +public: + + cJsonChunkSerializer(void); + + Json::Value & GetRoot (void) {return m_Root; } + BLOCKTYPE * GetBlockData(void) {return m_BlockData; } + bool HasJsonData (void) const {return m_HasJsonData; } + +protected: + + // NOTE: block data is serialized into inherited cChunkDataCollector's m_BlockData[] array + + // Entities and BlockEntities are serialized to Json + Json::Value m_Root; + bool m_HasJsonData; + + // cChunkDataCollector overrides: + virtual void Entity (cEntity * a_Entity) override; + virtual void BlockEntity (cBlockEntity * a_Entity) override; + virtual bool LightIsValid (bool a_IsLightValid) override; +} ; + + + + + +class cWSSCompact : + public cWSSchema +{ +public: + cWSSCompact(cWorld * a_World) : cWSSchema(a_World) {} + virtual ~cWSSCompact(); + +protected: + + struct sChunkHeader; + typedef std::vector<sChunkHeader *> sChunkHeaders; + + /// Implements a cache for a single PAK file; implements lazy-write in order to be able to write multiple chunks fast + class cPAKFile + { + public: + + cPAKFile(const AString & a_FileName, int a_LayerX, int a_LayerZ); + ~cPAKFile(); + + bool GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data); + bool SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data); + bool EraseChunkData(const cChunkCoords & a_Chunk); + + bool SaveChunk(const cChunkCoords & a_Chunk, cWorld * a_World); + + int GetLayerX(void) const {return m_LayerX; } + int GetLayerZ(void) const {return m_LayerZ; } + + static const int PAK_VERSION = 1; +#if AXIS_ORDER == AXIS_ORDER_XZY + static const int CHUNK_VERSION = 3; +#elif AXIS_ORDER == AXIS_ORDER_YZX + static const int CHUNK_VERSION = 2; +#endif + protected: + + AString m_FileName; + int m_LayerX; + int m_LayerZ; + + sChunkHeaders m_ChunkHeaders; + AString m_DataContents; // Data contents of the file, cached + + int m_NumDirty; // Number of chunks that were written into m_DataContents but not into the file + + Vector3i m_ChunkSize; // Is related to m_ChunkVersion + char m_ChunkVersion; + char m_PakVersion; + + bool SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World); // Saves the chunk to m_DataContents, updates headers and m_NumDirty + void SynchronizeFile(void); // Writes m_DataContents along with the headers to file, resets m_NumDirty + + void UpdateChunk1To2(void); // Height from 128 to 256 + void UpdateChunk2To3(void); // Axis order from YZX to XZY + } ; + + typedef std::list<cPAKFile *> cPAKFiles; + + cCriticalSection m_CS; + cPAKFiles m_PAKFiles; // A MRU cache of PAK files + + /// Loads the correct PAK file either from cache or from disk, manages the m_PAKFiles cache + cPAKFile * LoadPAKFile(const cChunkCoords & a_Chunk); + + /// Gets chunk data from the correct file; locks CS as needed + bool GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data); + + /// Sets chunk data to the correct file; locks CS as needed + bool SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data); + + /// Erases chunk data from the correct file; locks CS as needed + bool EraseChunkData(const cChunkCoords & a_Chunk); + + /// Loads the chunk from the data (no locking needed) + bool LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, const AString & a_Data, cWorld * a_World); + + void LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World); + + // cWSSchema overrides: + virtual bool LoadChunk(const cChunkCoords & a_Chunk) override; + virtual bool SaveChunk(const cChunkCoords & a_Chunk) override; + virtual const AString GetName(void) const override {return "compact"; } +} ; + + + + + +#endif // WSSCOMPACT_H_INCLUDED + + + + diff --git a/source/WorldStorage.cpp b/source/WorldStorage.cpp index c9ca69659..ce1c11322 100644 --- a/source/WorldStorage.cpp +++ b/source/WorldStorage.cpp @@ -1,379 +1,379 @@ -
-// WorldStorage.cpp
-
-// Implements the cWorldStorage class representing the chunk loading / saving thread
-
-// To add a new storage schema, implement a cWSSchema descendant and add it to cWorldStorage::InitSchemas()
-
-#include "Globals.h"
-#include "WorldStorage.h"
-#include "WSSCompact.h"
-#include "WSSAnvil.h"
-#include "cWorld.h"
-#include "cChunkGenerator.h"
-#include "cEntity.h"
-#include "cBlockEntity.h"
-#include "BlockID.h"
-
-
-
-
-
-/// Example storage schema - forgets all chunks ;)
-class cWSSForgetful :
- public cWSSchema
-{
-public:
- cWSSForgetful(cWorld * a_World) : cWSSchema(a_World) {}
-
-protected:
- // cWSSchema overrides:
- virtual bool LoadChunk(const cChunkCoords & a_Chunk) override {return false; }
- virtual bool SaveChunk(const cChunkCoords & a_Chunk) override {return true; }
- virtual const AString GetName(void) const override {return "forgetful"; }
-} ;
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cWorldStorage:
-
-cWorldStorage::cWorldStorage(void) :
- super("cWorldStorage"),
- m_World(NULL),
- m_SaveSchema(NULL)
-{
-}
-
-
-
-
-
-cWorldStorage::~cWorldStorage()
-{
- for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr)
- {
- delete *itr;
- } // for itr - m_Schemas[]
- m_LoadQueue.clear();
- m_SaveQueue.clear();
-}
-
-
-
-
-
-bool cWorldStorage::Start(cWorld * a_World, const AString & a_StorageSchemaName)
-{
- m_World = a_World;
- m_StorageSchemaName = a_StorageSchemaName;
- InitSchemas();
-
- return super::Start();
-}
-
-
-
-
-
-void cWorldStorage::WaitForFinish(void)
-{
- LOG("Waiting for the world storage to finish saving");
-
- {
- // Cancel all loading requests:
- cCSLock Lock(m_CSQueues);
- m_LoadQueue.clear();
- }
-
- // Wait for the saving to finish:
- WaitForQueuesEmpty();
-
- // Wait for the thread to finish:
- m_ShouldTerminate = true;
- m_Event.Set();
- m_evtRemoved.Set(); // Wake up anybody waiting in the WaitForQueuesEmpty() method
- super::Wait();
- LOG("World storage thread finished");
-}
-
-
-
-
-
-void cWorldStorage::WaitForQueuesEmpty(void)
-{
- cCSLock Lock(m_CSQueues);
- while (!m_ShouldTerminate && (!m_LoadQueue.empty() || !m_SaveQueue.empty()))
- {
- cCSUnlock Unlock(Lock);
- m_evtRemoved.Wait();
- }
-}
-
-
-
-
-
-int cWorldStorage::GetLoadQueueLength(void)
-{
- cCSLock Lock(m_CSQueues);
- return (int)m_LoadQueue.size();
-}
-
-
-
-
-
-int cWorldStorage::GetSaveQueueLength(void)
-{
- cCSLock Lock(m_CSQueues);
- return (int)m_SaveQueue.size();
-}
-
-
-
-
-
-void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate)
-{
- // Queues the chunk for loading; if not loaded, the chunk will be generated
- {
- cCSLock Lock(m_CSQueues);
-
- // Check if already in the queue:
- for (sChunkLoadQueue::iterator itr = m_LoadQueue.begin(); itr != m_LoadQueue.end(); ++itr)
- {
- if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ) && (itr->m_Generate == a_Generate))
- {
- return;
- }
- }
- m_LoadQueue.push_back(sChunkLoad(a_ChunkX, a_ChunkY, a_ChunkZ, a_Generate));
- }
-
- m_Event.Set();
-}
-
-
-
-
-
-void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- {
- cCSLock Lock(m_CSQueues);
- m_SaveQueue.remove (cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); // Don't add twice
- m_SaveQueue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
- }
- m_Event.Set();
-}
-
-
-
-
-
-void cWorldStorage::UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- cCSLock Lock(m_CSQueues);
- for (sChunkLoadQueue::iterator itr = m_LoadQueue.begin(); itr != m_LoadQueue.end(); ++itr)
- {
- if ((itr->m_ChunkX != a_ChunkX) || (itr->m_ChunkY != a_ChunkY) || (itr->m_ChunkZ != a_ChunkZ))
- {
- continue;
- }
- m_LoadQueue.erase(itr);
- Lock.Unlock();
- m_evtRemoved.Set();
- return;
- } // for itr - m_LoadQueue[]
-}
-
-
-
-
-
-void cWorldStorage::UnqueueSave(const cChunkCoords & a_Chunk)
-{
- {
- cCSLock Lock(m_CSQueues);
- m_SaveQueue.remove(a_Chunk);
- }
- m_evtRemoved.Set();
-}
-
-
-
-
-
-void cWorldStorage::InitSchemas(void)
-{
- // The first schema added is considered the default
- m_Schemas.push_back(new cWSSCompact (m_World));
- m_Schemas.push_back(new cWSSAnvil (m_World));
- m_Schemas.push_back(new cWSSForgetful(m_World));
- // Add new schemas here
-
- if (NoCaseCompare(m_StorageSchemaName, "default") == 0)
- {
- m_SaveSchema = m_Schemas.front();
- return;
- }
- for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr)
- {
- if (NoCaseCompare((*itr)->GetName(), m_StorageSchemaName) == 0)
- {
- m_SaveSchema = *itr;
- return;
- }
- } // for itr - m_Schemas[]
-
- // Unknown schema selected, let the admin know:
- LOGWARNING("Unknown storage schema name \"%s\". Using default (\"%s\"). Available schemas:",
- m_StorageSchemaName.c_str(), m_SaveSchema->GetName().c_str()
- );
- for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr)
- {
- LOGWARNING("\t\"%s\"", (*itr)->GetName().c_str());
- }
- m_SaveSchema = m_Schemas.front();
-}
-
-
-
-
-
-void cWorldStorage::Execute(void)
-{
- while (!m_ShouldTerminate)
- {
- m_Event.Wait();
-
- // Process both queues until they are empty again:
- bool HasMore;
- do
- {
- HasMore = false;
- if (m_ShouldTerminate)
- {
- return;
- }
-
- HasMore = LoadOneChunk();
- HasMore = HasMore | SaveOneChunk();
- m_evtRemoved.Set();
- } while (HasMore);
- }
-}
-
-
-
-
-
-bool cWorldStorage::LoadOneChunk(void)
-{
- sChunkLoad ToLoad(0, 0, 0, false);
- bool HasMore;
- bool ShouldLoad = false;
- {
- cCSLock Lock(m_CSQueues);
- if (!m_LoadQueue.empty())
- {
- ToLoad = m_LoadQueue.front();
- m_LoadQueue.pop_front();
- ShouldLoad = true;
- }
- HasMore = !m_LoadQueue.empty();
- }
-
- if (ShouldLoad && !LoadChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ))
- {
- if (ToLoad.m_Generate)
- {
- // The chunk couldn't be loaded, generate it:
- m_World->GetGenerator().QueueGenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ);
- }
- else
- {
- // TODO: Notify the world that the load has failed:
- // m_World->ChunkLoadFailed(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ);
- }
- }
- return HasMore;
-}
-
-
-
-
-
-bool cWorldStorage::SaveOneChunk(void)
-{
- cChunkCoords Save(0, 0, 0);
- bool HasMore;
- bool ShouldSave = false;
- {
- cCSLock Lock(m_CSQueues);
- if (!m_SaveQueue.empty())
- {
- Save = m_SaveQueue.front();
- m_SaveQueue.pop_front();
- ShouldSave = true;
- }
- HasMore = !m_SaveQueue.empty();
- }
- if (ShouldSave && m_World->IsChunkValid(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ))
- {
- m_World->MarkChunkSaving(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ);
- if (m_SaveSchema->SaveChunk(Save))
- {
- m_World->MarkChunkSaved(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ);
- }
- else
- {
- LOGWARNING("Cannot save chunk [%d, %d, %d]", Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ);
- }
- }
- return HasMore;
-}
-
-
-
-
-
-bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- if (m_World->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ))
- {
- // Already loaded (can happen, since the queue is async)
- return true;
- }
-
- cChunkCoords Coords(a_ChunkX, a_ChunkY, a_ChunkZ);
-
- // First try the schema that is used for saving
- if (m_SaveSchema->LoadChunk(Coords))
- {
- return true;
- }
-
- // If it didn't have the chunk, try all the other schemas:
- for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr)
- {
- if (((*itr) != m_SaveSchema) && (*itr)->LoadChunk(Coords))
- {
- return true;
- }
- }
-
- // Notify the chunk owner that the chunk failed to load (sets cChunk::m_HasLoadFailed to true):
- m_World->ChunkLoadFailed(a_ChunkX, a_ChunkY, a_ChunkZ);
-
- return false;
-}
-
-
-
-
-
+ +// WorldStorage.cpp + +// Implements the cWorldStorage class representing the chunk loading / saving thread + +// To add a new storage schema, implement a cWSSchema descendant and add it to cWorldStorage::InitSchemas() + +#include "Globals.h" +#include "WorldStorage.h" +#include "WSSCompact.h" +#include "WSSAnvil.h" +#include "cWorld.h" +#include "cChunkGenerator.h" +#include "cEntity.h" +#include "cBlockEntity.h" +#include "BlockID.h" + + + + + +/// Example storage schema - forgets all chunks ;) +class cWSSForgetful : + public cWSSchema +{ +public: + cWSSForgetful(cWorld * a_World) : cWSSchema(a_World) {} + +protected: + // cWSSchema overrides: + virtual bool LoadChunk(const cChunkCoords & a_Chunk) override {return false; } + virtual bool SaveChunk(const cChunkCoords & a_Chunk) override {return true; } + virtual const AString GetName(void) const override {return "forgetful"; } +} ; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWorldStorage: + +cWorldStorage::cWorldStorage(void) : + super("cWorldStorage"), + m_World(NULL), + m_SaveSchema(NULL) +{ +} + + + + + +cWorldStorage::~cWorldStorage() +{ + for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) + { + delete *itr; + } // for itr - m_Schemas[] + m_LoadQueue.clear(); + m_SaveQueue.clear(); +} + + + + + +bool cWorldStorage::Start(cWorld * a_World, const AString & a_StorageSchemaName) +{ + m_World = a_World; + m_StorageSchemaName = a_StorageSchemaName; + InitSchemas(); + + return super::Start(); +} + + + + + +void cWorldStorage::WaitForFinish(void) +{ + LOG("Waiting for the world storage to finish saving"); + + { + // Cancel all loading requests: + cCSLock Lock(m_CSQueues); + m_LoadQueue.clear(); + } + + // Wait for the saving to finish: + WaitForQueuesEmpty(); + + // Wait for the thread to finish: + m_ShouldTerminate = true; + m_Event.Set(); + m_evtRemoved.Set(); // Wake up anybody waiting in the WaitForQueuesEmpty() method + super::Wait(); + LOG("World storage thread finished"); +} + + + + + +void cWorldStorage::WaitForQueuesEmpty(void) +{ + cCSLock Lock(m_CSQueues); + while (!m_ShouldTerminate && (!m_LoadQueue.empty() || !m_SaveQueue.empty())) + { + cCSUnlock Unlock(Lock); + m_evtRemoved.Wait(); + } +} + + + + + +int cWorldStorage::GetLoadQueueLength(void) +{ + cCSLock Lock(m_CSQueues); + return (int)m_LoadQueue.size(); +} + + + + + +int cWorldStorage::GetSaveQueueLength(void) +{ + cCSLock Lock(m_CSQueues); + return (int)m_SaveQueue.size(); +} + + + + + +void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate) +{ + // Queues the chunk for loading; if not loaded, the chunk will be generated + { + cCSLock Lock(m_CSQueues); + + // Check if already in the queue: + for (sChunkLoadQueue::iterator itr = m_LoadQueue.begin(); itr != m_LoadQueue.end(); ++itr) + { + if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ) && (itr->m_Generate == a_Generate)) + { + return; + } + } + m_LoadQueue.push_back(sChunkLoad(a_ChunkX, a_ChunkY, a_ChunkZ, a_Generate)); + } + + m_Event.Set(); +} + + + + + +void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + { + cCSLock Lock(m_CSQueues); + m_SaveQueue.remove (cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); // Don't add twice + m_SaveQueue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + } + m_Event.Set(); +} + + + + + +void cWorldStorage::UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSQueues); + for (sChunkLoadQueue::iterator itr = m_LoadQueue.begin(); itr != m_LoadQueue.end(); ++itr) + { + if ((itr->m_ChunkX != a_ChunkX) || (itr->m_ChunkY != a_ChunkY) || (itr->m_ChunkZ != a_ChunkZ)) + { + continue; + } + m_LoadQueue.erase(itr); + Lock.Unlock(); + m_evtRemoved.Set(); + return; + } // for itr - m_LoadQueue[] +} + + + + + +void cWorldStorage::UnqueueSave(const cChunkCoords & a_Chunk) +{ + { + cCSLock Lock(m_CSQueues); + m_SaveQueue.remove(a_Chunk); + } + m_evtRemoved.Set(); +} + + + + + +void cWorldStorage::InitSchemas(void) +{ + // The first schema added is considered the default + m_Schemas.push_back(new cWSSCompact (m_World)); + m_Schemas.push_back(new cWSSAnvil (m_World)); + m_Schemas.push_back(new cWSSForgetful(m_World)); + // Add new schemas here + + if (NoCaseCompare(m_StorageSchemaName, "default") == 0) + { + m_SaveSchema = m_Schemas.front(); + return; + } + for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) + { + if (NoCaseCompare((*itr)->GetName(), m_StorageSchemaName) == 0) + { + m_SaveSchema = *itr; + return; + } + } // for itr - m_Schemas[] + + // Unknown schema selected, let the admin know: + LOGWARNING("Unknown storage schema name \"%s\". Using default (\"%s\"). Available schemas:", + m_StorageSchemaName.c_str(), m_SaveSchema->GetName().c_str() + ); + for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) + { + LOGWARNING("\t\"%s\"", (*itr)->GetName().c_str()); + } + m_SaveSchema = m_Schemas.front(); +} + + + + + +void cWorldStorage::Execute(void) +{ + while (!m_ShouldTerminate) + { + m_Event.Wait(); + + // Process both queues until they are empty again: + bool HasMore; + do + { + HasMore = false; + if (m_ShouldTerminate) + { + return; + } + + HasMore = LoadOneChunk(); + HasMore = HasMore | SaveOneChunk(); + m_evtRemoved.Set(); + } while (HasMore); + } +} + + + + + +bool cWorldStorage::LoadOneChunk(void) +{ + sChunkLoad ToLoad(0, 0, 0, false); + bool HasMore; + bool ShouldLoad = false; + { + cCSLock Lock(m_CSQueues); + if (!m_LoadQueue.empty()) + { + ToLoad = m_LoadQueue.front(); + m_LoadQueue.pop_front(); + ShouldLoad = true; + } + HasMore = !m_LoadQueue.empty(); + } + + if (ShouldLoad && !LoadChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ)) + { + if (ToLoad.m_Generate) + { + // The chunk couldn't be loaded, generate it: + m_World->GetGenerator().QueueGenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ); + } + else + { + // TODO: Notify the world that the load has failed: + // m_World->ChunkLoadFailed(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ); + } + } + return HasMore; +} + + + + + +bool cWorldStorage::SaveOneChunk(void) +{ + cChunkCoords Save(0, 0, 0); + bool HasMore; + bool ShouldSave = false; + { + cCSLock Lock(m_CSQueues); + if (!m_SaveQueue.empty()) + { + Save = m_SaveQueue.front(); + m_SaveQueue.pop_front(); + ShouldSave = true; + } + HasMore = !m_SaveQueue.empty(); + } + if (ShouldSave && m_World->IsChunkValid(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ)) + { + m_World->MarkChunkSaving(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ); + if (m_SaveSchema->SaveChunk(Save)) + { + m_World->MarkChunkSaved(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ); + } + else + { + LOGWARNING("Cannot save chunk [%d, %d, %d]", Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ); + } + } + return HasMore; +} + + + + + +bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + if (m_World->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ)) + { + // Already loaded (can happen, since the queue is async) + return true; + } + + cChunkCoords Coords(a_ChunkX, a_ChunkY, a_ChunkZ); + + // First try the schema that is used for saving + if (m_SaveSchema->LoadChunk(Coords)) + { + return true; + } + + // If it didn't have the chunk, try all the other schemas: + for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) + { + if (((*itr) != m_SaveSchema) && (*itr)->LoadChunk(Coords)) + { + return true; + } + } + + // Notify the chunk owner that the chunk failed to load (sets cChunk::m_HasLoadFailed to true): + m_World->ChunkLoadFailed(a_ChunkX, a_ChunkY, a_ChunkZ); + + return false; +} + + + + + diff --git a/source/WorldStorage.h b/source/WorldStorage.h index 0c725a460..b2daba059 100644 --- a/source/WorldStorage.h +++ b/source/WorldStorage.h @@ -1,131 +1,131 @@ -
-// WorldStorage.h
-
-// Interfaces to the cWorldStorage class representing the chunk loading / saving thread
-// This class decides which storage schema to use for saving; it queries all available schemas for loading
-// Also declares the base class for all storage schemas, cWSSchema
-// Helper serialization class cJsonChunkSerializer is declared as well
-
-
-
-
-
-#pragma once
-#ifndef WORLDSTORAGE_H_INCLUDED
-#define WORLDSTORAGE_H_INCLUDED
-
-#include "ChunkDef.h"
-#include "cIsThread.h"
-#include <json/json.h>
-
-
-
-
-
-// fwd:
-class cWorld;
-
-
-
-
-
-/// Interface that all the world storage schemas need to implement
-class cWSSchema abstract
-{
-public:
- cWSSchema(cWorld * a_World) : m_World(a_World) {}
- virtual ~cWSSchema() {} // Force the descendants' destructors to be virtual
-
- virtual bool LoadChunk(const cChunkCoords & a_Chunk) = 0;
- virtual bool SaveChunk(const cChunkCoords & a_Chunk) = 0;
- virtual const AString GetName(void) const = 0;
-
-protected:
-
- cWorld * m_World;
-} ;
-
-typedef std::list<cWSSchema *> cWSSchemaList;
-
-
-
-
-
-/// The actual world storage class
-class cWorldStorage :
- public cIsThread
-{
- typedef cIsThread super;
-
-public:
-
- cWorldStorage(void);
- ~cWorldStorage();
-
- void QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate); // Queues the chunk for loading; if not loaded, the chunk will be generated if a_Generate is true
- void QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- /// Loads the chunk specified; returns true on success, false on failure
- bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- void UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void UnqueueSave(const cChunkCoords & a_Chunk);
-
- bool Start(cWorld * a_World, const AString & a_StorageSchemaName); // Hide the cIsThread's Start() method, we need to provide args
- void WaitForFinish(void);
- void WaitForQueuesEmpty(void);
-
- int GetLoadQueueLength(void);
- int GetSaveQueueLength(void);
-
-protected:
-
- struct sChunkLoad
- {
- int m_ChunkX;
- int m_ChunkY;
- int m_ChunkZ;
- bool m_Generate; // If true, the chunk will be generated if it cannot be loaded
-
- sChunkLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ), m_Generate(a_Generate) {}
- } ;
-
- typedef std::list<sChunkLoad> sChunkLoadQueue;
-
- cWorld * m_World;
- AString m_StorageSchemaName;
-
- // Both queues are locked by the same CS
- cCriticalSection m_CSQueues;
- sChunkLoadQueue m_LoadQueue;
- cChunkCoordsList m_SaveQueue;
-
- cEvent m_Event; // Set when there's any addition to the queues
- cEvent m_evtRemoved; // Set when an item has been removed from the queue, either by the worker thread or the Unqueue methods
-
- /// All the storage schemas (all used for loading)
- cWSSchemaList m_Schemas;
-
- /// The one storage schema used for saving
- cWSSchema * m_SaveSchema;
-
- void InitSchemas(void);
-
- virtual void Execute(void) override;
-
- /// Loads one chunk from the queue (if any queued); returns true if there are more chunks in the load queue
- bool LoadOneChunk(void);
-
- /// Saves one chunk from the queue (if any queued); returns true if there are more chunks in the save queue
- bool SaveOneChunk(void);
-} ;
-
-
-
-
-
-#endif // WORLDSTORAGE_H_INCLUDED
-
-
-
-
+ +// WorldStorage.h + +// Interfaces to the cWorldStorage class representing the chunk loading / saving thread +// This class decides which storage schema to use for saving; it queries all available schemas for loading +// Also declares the base class for all storage schemas, cWSSchema +// Helper serialization class cJsonChunkSerializer is declared as well + + + + + +#pragma once +#ifndef WORLDSTORAGE_H_INCLUDED +#define WORLDSTORAGE_H_INCLUDED + +#include "ChunkDef.h" +#include "cIsThread.h" +#include <json/json.h> + + + + + +// fwd: +class cWorld; + + + + + +/// Interface that all the world storage schemas need to implement +class cWSSchema abstract +{ +public: + cWSSchema(cWorld * a_World) : m_World(a_World) {} + virtual ~cWSSchema() {} // Force the descendants' destructors to be virtual + + virtual bool LoadChunk(const cChunkCoords & a_Chunk) = 0; + virtual bool SaveChunk(const cChunkCoords & a_Chunk) = 0; + virtual const AString GetName(void) const = 0; + +protected: + + cWorld * m_World; +} ; + +typedef std::list<cWSSchema *> cWSSchemaList; + + + + + +/// The actual world storage class +class cWorldStorage : + public cIsThread +{ + typedef cIsThread super; + +public: + + cWorldStorage(void); + ~cWorldStorage(); + + void QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate); // Queues the chunk for loading; if not loaded, the chunk will be generated if a_Generate is true + void QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Loads the chunk specified; returns true on success, false on failure + bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + void UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void UnqueueSave(const cChunkCoords & a_Chunk); + + bool Start(cWorld * a_World, const AString & a_StorageSchemaName); // Hide the cIsThread's Start() method, we need to provide args + void WaitForFinish(void); + void WaitForQueuesEmpty(void); + + int GetLoadQueueLength(void); + int GetSaveQueueLength(void); + +protected: + + struct sChunkLoad + { + int m_ChunkX; + int m_ChunkY; + int m_ChunkZ; + bool m_Generate; // If true, the chunk will be generated if it cannot be loaded + + sChunkLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ), m_Generate(a_Generate) {} + } ; + + typedef std::list<sChunkLoad> sChunkLoadQueue; + + cWorld * m_World; + AString m_StorageSchemaName; + + // Both queues are locked by the same CS + cCriticalSection m_CSQueues; + sChunkLoadQueue m_LoadQueue; + cChunkCoordsList m_SaveQueue; + + cEvent m_Event; // Set when there's any addition to the queues + cEvent m_evtRemoved; // Set when an item has been removed from the queue, either by the worker thread or the Unqueue methods + + /// All the storage schemas (all used for loading) + cWSSchemaList m_Schemas; + + /// The one storage schema used for saving + cWSSchema * m_SaveSchema; + + void InitSchemas(void); + + virtual void Execute(void) override; + + /// Loads one chunk from the queue (if any queued); returns true if there are more chunks in the load queue + bool LoadOneChunk(void); + + /// Saves one chunk from the queue (if any queued); returns true if there are more chunks in the save queue + bool SaveOneChunk(void); +} ; + + + + + +#endif // WORLDSTORAGE_H_INCLUDED + + + + diff --git a/source/cAggressiveMonster.cpp b/source/cAggressiveMonster.cpp index e597bfed8..3fa61bb33 100644 --- a/source/cAggressiveMonster.cpp +++ b/source/cAggressiveMonster.cpp @@ -1,78 +1,78 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cAggressiveMonster.h"
-
-#include "Vector3f.h"
-#include "cPlayer.h"
-#include "MersenneTwister.h"
-
-
-cAggressiveMonster::cAggressiveMonster()
- : m_ChaseTime(999999)
-{
- m_EMPersonality = AGGRESSIVE;
-}
-
-cAggressiveMonster::~cAggressiveMonster()
-{
-}
-
-//What to do if in Chasing State
-void cAggressiveMonster::InStateChasing(float a_Dt) {
- cMonster::InStateChasing(a_Dt);
- m_ChaseTime += a_Dt;
- if( m_Target )
- {
- if(m_Target->GetEntityType() == cEntity::eEntityType_Player)
- {
- cPlayer * Player = (cPlayer *) m_Target;
- if(Player->GetGameMode() == 1)
- {
- m_EMState = IDLE;
- return;
- }
- }
-
- Vector3f Pos = Vector3f( m_Pos );
- Vector3f Their = Vector3f( m_Target->GetPosition() );
- if( (Their - Pos).Length() <= m_AttackRange) {
- cMonster::Attack(a_Dt);
- }
- MoveToPosition( Their + Vector3f(0, 0.65f, 0) );
- } else if( m_ChaseTime > 5.f ) {
- m_ChaseTime = 0;
- m_EMState = IDLE;
- }
-}
-
-
-
-void cAggressiveMonster::EventSeePlayer(cEntity *a_Entity)
-{
- cMonster::EventSeePlayer(a_Entity);
- m_EMState = CHASING;
-}
-
-void cAggressiveMonster::Tick(float a_Dt)
-{
- cMonster::Tick(a_Dt);
-
- m_SeePlayerInterval += a_Dt;
-
- if(m_SeePlayerInterval > 1)
- {
- MTRand r1;
- int rem = r1.randInt() % 3 + 1; //check most of the time but miss occasionally
-
- m_SeePlayerInterval = 0.0;
- if(rem >= 2)
- {
- if(m_EMState == CHASING){
- CheckEventLostPlayer();
- } else {
- CheckEventSeePlayer();
- }
- }
- }
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cAggressiveMonster.h" + +#include "Vector3f.h" +#include "cPlayer.h" +#include "MersenneTwister.h" + + +cAggressiveMonster::cAggressiveMonster() + : m_ChaseTime(999999) +{ + m_EMPersonality = AGGRESSIVE; +} + +cAggressiveMonster::~cAggressiveMonster() +{ +} + +//What to do if in Chasing State +void cAggressiveMonster::InStateChasing(float a_Dt) { + cMonster::InStateChasing(a_Dt); + m_ChaseTime += a_Dt; + if( m_Target ) + { + if(m_Target->GetEntityType() == cEntity::eEntityType_Player) + { + cPlayer * Player = (cPlayer *) m_Target; + if(Player->GetGameMode() == 1) + { + m_EMState = IDLE; + return; + } + } + + Vector3f Pos = Vector3f( m_Pos ); + Vector3f Their = Vector3f( m_Target->GetPosition() ); + if( (Their - Pos).Length() <= m_AttackRange) { + cMonster::Attack(a_Dt); + } + MoveToPosition( Their + Vector3f(0, 0.65f, 0) ); + } else if( m_ChaseTime > 5.f ) { + m_ChaseTime = 0; + m_EMState = IDLE; + } +} + + + +void cAggressiveMonster::EventSeePlayer(cEntity *a_Entity) +{ + cMonster::EventSeePlayer(a_Entity); + m_EMState = CHASING; +} + +void cAggressiveMonster::Tick(float a_Dt) +{ + cMonster::Tick(a_Dt); + + m_SeePlayerInterval += a_Dt; + + if(m_SeePlayerInterval > 1) + { + MTRand r1; + int rem = r1.randInt() % 3 + 1; //check most of the time but miss occasionally + + m_SeePlayerInterval = 0.0; + if(rem >= 2) + { + if(m_EMState == CHASING){ + CheckEventLostPlayer(); + } else { + CheckEventSeePlayer(); + } + } + } }
\ No newline at end of file diff --git a/source/cAuthenticator.cpp b/source/cAuthenticator.cpp index d45eaa043..f248f4698 100644 --- a/source/cAuthenticator.cpp +++ b/source/cAuthenticator.cpp @@ -1,274 +1,274 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cAuthenticator.h"
-#include "cBlockingTCPLink.h"
-#include "cRoot.h"
-#include "cServer.h"
-
-#include "../iniFile/iniFile.h"
-
-#include <sstream>
-
-
-
-
-
-#define DEFAULT_AUTH_SERVER "session.minecraft.net"
-#define DEFAULT_AUTH_ADDRESS "/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID%"
-#define MAX_REDIRECTS 10
-
-
-
-
-
-cAuthenticator::cAuthenticator(void) :
- super("cAuthenticator"),
- m_Server(DEFAULT_AUTH_SERVER),
- m_Address(DEFAULT_AUTH_ADDRESS),
- m_ShouldAuthenticate(true)
-{
- ReadINI();
-}
-
-
-
-
-
-cAuthenticator::~cAuthenticator()
-{
- Stop();
-}
-
-
-
-
-
-/// Read custom values from INI
-void cAuthenticator::ReadINI(void)
-{
- cIniFile IniFile("settings.ini");
- if (!IniFile.ReadFile())
- {
- return;
- }
-
- m_Server = IniFile.GetValue("Authentication", "Server");
- m_Address = IniFile.GetValue("Authentication", "Address");
- m_ShouldAuthenticate = IniFile.GetValueB("Authentication", "Authenticate", true);
- bool bSave = false;
-
- if (m_Server.length() == 0)
- {
- m_Server = DEFAULT_AUTH_SERVER;
- IniFile.SetValue("Authentication", "Server", m_Server);
- bSave = true;
- }
- if (m_Address.length() == 0)
- {
- m_Address = DEFAULT_AUTH_ADDRESS;
- IniFile.SetValue("Authentication", "Address", m_Address);
- bSave = true;
- }
-
- if (bSave)
- {
- IniFile.SetValueB("Authentication", "Authenticate", m_ShouldAuthenticate);
- IniFile.WriteFile();
- }
-}
-
-
-
-
-
-/// Queues a request for authenticating a user. If the auth fails, the user is kicked
-void cAuthenticator::Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash)
-{
- if (!m_ShouldAuthenticate)
- {
- cRoot::Get()->AuthenticateUser(a_ClientID);
- return;
- }
-
- cCSLock Lock(m_CS);
- m_Queue.push_back(cUser(a_ClientID, a_UserName, a_ServerHash));
- m_QueueNonempty.Set();
-}
-
-
-
-
-
-void cAuthenticator::Stop(void)
-{
- m_ShouldTerminate = true;
- m_QueueNonempty.Set();
- Wait();
-}
-
-
-
-
-
-void cAuthenticator::Execute(void)
-{
- for (;;)
- {
- cCSLock Lock(m_CS);
- while (!m_ShouldTerminate && (m_Queue.size() == 0))
- {
- cCSUnlock Unlock(Lock);
- m_QueueNonempty.Wait();
- }
- if (m_ShouldTerminate)
- {
- return;
- }
- ASSERT(!m_Queue.empty());
-
- int ClientID = m_Queue.front().mClientID;
- AString UserName = m_Queue.front().mName;
- AString ActualAddress = m_Address;
- ReplaceString(ActualAddress, "%USERNAME%", UserName);
- ReplaceString(ActualAddress, "%SERVERID%", cRoot::Get()->GetServer()->GetServerID());
- m_Queue.pop_front();
- Lock.Unlock();
-
- if (!AuthFromAddress(m_Server, ActualAddress, UserName))
- {
- cRoot::Get()->KickUser(ClientID, "Failed to authenticate account!");
- }
- else
- {
- cRoot::Get()->AuthenticateUser(ClientID);
- }
- } // for (-ever)
-}
-
-
-
-
-
-bool cAuthenticator::AuthFromAddress(const AString & a_Server, const AString & a_Address, const AString & a_UserName, int a_Level /* = 1 */)
-{
- // Returns true if the user authenticated okay, false on error; iLevel is the recursion deptht (bails out if too deep)
-
- cBlockingTCPLink Link;
- if (!Link.Connect(a_Server.c_str(), 80))
- {
- LOGERROR("cAuthenticator: cannot connect to auth server \"%s\", kicking user \"%s\"", a_Server.c_str(), a_Server.c_str());
- return false;
- }
-
- Link.SendMessage( AString( "GET " + a_Address + " HTTP/1.0\r\n\r\n" ).c_str());
- AString DataRecvd;
- Link.ReceiveData(DataRecvd);
- Link.CloseSocket();
-
- std::stringstream ss(DataRecvd);
-
- // Parse the data received:
- std::string temp;
- ss >> temp;
- bool bRedirect = false;
- bool bOK = false;
- if ((temp.compare("HTTP/1.1") == 0) || (temp.compare("HTTP/1.0") == 0))
- {
- int code;
- ss >> code;
- if (code == 302)
- {
- // redirect blabla
- LOGINFO("Need to redirect!");
- if (a_Level > MAX_REDIRECTS)
- {
- LOGERROR("cAuthenticator: received too many levels of redirection from auth server \"%s\" for user \"%s\", bailing out and kicking the user", a_Server.c_str(), a_UserName.c_str());
- return false;
- }
- bRedirect = true;
- }
- else if (code == 200)
- {
- LOGINFO("Got 200 OK :D");
- bOK = true;
- }
- }
- else
- {
- LOGERROR("cAuthenticator: cannot parse auth reply from server \"%s\" for user \"%s\", kicking the user.", a_Server.c_str(), a_UserName.c_str());
- return false;
- }
-
- if( bRedirect )
- {
- AString Location;
- // Search for "Location:"
- bool bFoundLocation = false;
- while( !bFoundLocation && ss.good() )
- {
- char c = 0;
- while( c != '\n' )
- {
- ss.get( c );
- }
- AString Name;
- ss >> Name;
- if (Name.compare("Location:") == 0)
- {
- bFoundLocation = true;
- ss >> Location;
- }
- }
- if (!bFoundLocation)
- {
- LOGERROR("cAuthenticator: received invalid redirection from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
- return false;
- }
-
- Location = Location.substr(strlen("http://"), std::string::npos); // Strip http://
- std::string Server = Location.substr( 0, Location.find( "/" ) ); // Only leave server address
- Location = Location.substr( Server.length(), std::string::npos);
- return AuthFromAddress(Server, Location, a_UserName, a_Level + 1);
- }
-
- if (!bOK)
- {
- LOGERROR("cAuthenticator: received an error from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
- return false;
- }
-
- // Header says OK, so receive the rest.
- // Go past header, double \n means end of headers
- char c = 0;
- while (ss.good())
- {
- while (c != '\n')
- {
- ss.get(c);
- }
- ss.get(c);
- if( c == '\n' || c == '\r' || ss.peek() == '\r' || ss.peek() == '\n' )
- break;
- }
- if (!ss.good())
- {
- LOGERROR("cAuthenticator: error while parsing response body from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
- return false;
- }
-
- std::string Result;
- ss >> Result;
- LOGINFO("Got result: %s", Result.c_str());
- if (Result.compare("YES") == 0)
- {
- LOGINFO("Result was \"YES\", so player is authenticated!");
- return true;
- }
- LOGINFO("Result was \"%s\", so player is NOT authenticated!", Result.c_str());
- return false;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cAuthenticator.h" +#include "cBlockingTCPLink.h" +#include "cRoot.h" +#include "cServer.h" + +#include "../iniFile/iniFile.h" + +#include <sstream> + + + + + +#define DEFAULT_AUTH_SERVER "session.minecraft.net" +#define DEFAULT_AUTH_ADDRESS "/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID%" +#define MAX_REDIRECTS 10 + + + + + +cAuthenticator::cAuthenticator(void) : + super("cAuthenticator"), + m_Server(DEFAULT_AUTH_SERVER), + m_Address(DEFAULT_AUTH_ADDRESS), + m_ShouldAuthenticate(true) +{ + ReadINI(); +} + + + + + +cAuthenticator::~cAuthenticator() +{ + Stop(); +} + + + + + +/// Read custom values from INI +void cAuthenticator::ReadINI(void) +{ + cIniFile IniFile("settings.ini"); + if (!IniFile.ReadFile()) + { + return; + } + + m_Server = IniFile.GetValue("Authentication", "Server"); + m_Address = IniFile.GetValue("Authentication", "Address"); + m_ShouldAuthenticate = IniFile.GetValueB("Authentication", "Authenticate", true); + bool bSave = false; + + if (m_Server.length() == 0) + { + m_Server = DEFAULT_AUTH_SERVER; + IniFile.SetValue("Authentication", "Server", m_Server); + bSave = true; + } + if (m_Address.length() == 0) + { + m_Address = DEFAULT_AUTH_ADDRESS; + IniFile.SetValue("Authentication", "Address", m_Address); + bSave = true; + } + + if (bSave) + { + IniFile.SetValueB("Authentication", "Authenticate", m_ShouldAuthenticate); + IniFile.WriteFile(); + } +} + + + + + +/// Queues a request for authenticating a user. If the auth fails, the user is kicked +void cAuthenticator::Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash) +{ + if (!m_ShouldAuthenticate) + { + cRoot::Get()->AuthenticateUser(a_ClientID); + return; + } + + cCSLock Lock(m_CS); + m_Queue.push_back(cUser(a_ClientID, a_UserName, a_ServerHash)); + m_QueueNonempty.Set(); +} + + + + + +void cAuthenticator::Stop(void) +{ + m_ShouldTerminate = true; + m_QueueNonempty.Set(); + Wait(); +} + + + + + +void cAuthenticator::Execute(void) +{ + for (;;) + { + cCSLock Lock(m_CS); + while (!m_ShouldTerminate && (m_Queue.size() == 0)) + { + cCSUnlock Unlock(Lock); + m_QueueNonempty.Wait(); + } + if (m_ShouldTerminate) + { + return; + } + ASSERT(!m_Queue.empty()); + + int ClientID = m_Queue.front().mClientID; + AString UserName = m_Queue.front().mName; + AString ActualAddress = m_Address; + ReplaceString(ActualAddress, "%USERNAME%", UserName); + ReplaceString(ActualAddress, "%SERVERID%", cRoot::Get()->GetServer()->GetServerID()); + m_Queue.pop_front(); + Lock.Unlock(); + + if (!AuthFromAddress(m_Server, ActualAddress, UserName)) + { + cRoot::Get()->KickUser(ClientID, "Failed to authenticate account!"); + } + else + { + cRoot::Get()->AuthenticateUser(ClientID); + } + } // for (-ever) +} + + + + + +bool cAuthenticator::AuthFromAddress(const AString & a_Server, const AString & a_Address, const AString & a_UserName, int a_Level /* = 1 */) +{ + // Returns true if the user authenticated okay, false on error; iLevel is the recursion deptht (bails out if too deep) + + cBlockingTCPLink Link; + if (!Link.Connect(a_Server.c_str(), 80)) + { + LOGERROR("cAuthenticator: cannot connect to auth server \"%s\", kicking user \"%s\"", a_Server.c_str(), a_Server.c_str()); + return false; + } + + Link.SendMessage( AString( "GET " + a_Address + " HTTP/1.0\r\n\r\n" ).c_str()); + AString DataRecvd; + Link.ReceiveData(DataRecvd); + Link.CloseSocket(); + + std::stringstream ss(DataRecvd); + + // Parse the data received: + std::string temp; + ss >> temp; + bool bRedirect = false; + bool bOK = false; + if ((temp.compare("HTTP/1.1") == 0) || (temp.compare("HTTP/1.0") == 0)) + { + int code; + ss >> code; + if (code == 302) + { + // redirect blabla + LOGINFO("Need to redirect!"); + if (a_Level > MAX_REDIRECTS) + { + LOGERROR("cAuthenticator: received too many levels of redirection from auth server \"%s\" for user \"%s\", bailing out and kicking the user", a_Server.c_str(), a_UserName.c_str()); + return false; + } + bRedirect = true; + } + else if (code == 200) + { + LOGINFO("Got 200 OK :D"); + bOK = true; + } + } + else + { + LOGERROR("cAuthenticator: cannot parse auth reply from server \"%s\" for user \"%s\", kicking the user.", a_Server.c_str(), a_UserName.c_str()); + return false; + } + + if( bRedirect ) + { + AString Location; + // Search for "Location:" + bool bFoundLocation = false; + while( !bFoundLocation && ss.good() ) + { + char c = 0; + while( c != '\n' ) + { + ss.get( c ); + } + AString Name; + ss >> Name; + if (Name.compare("Location:") == 0) + { + bFoundLocation = true; + ss >> Location; + } + } + if (!bFoundLocation) + { + LOGERROR("cAuthenticator: received invalid redirection from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str()); + return false; + } + + Location = Location.substr(strlen("http://"), std::string::npos); // Strip http:// + std::string Server = Location.substr( 0, Location.find( "/" ) ); // Only leave server address + Location = Location.substr( Server.length(), std::string::npos); + return AuthFromAddress(Server, Location, a_UserName, a_Level + 1); + } + + if (!bOK) + { + LOGERROR("cAuthenticator: received an error from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str()); + return false; + } + + // Header says OK, so receive the rest. + // Go past header, double \n means end of headers + char c = 0; + while (ss.good()) + { + while (c != '\n') + { + ss.get(c); + } + ss.get(c); + if( c == '\n' || c == '\r' || ss.peek() == '\r' || ss.peek() == '\n' ) + break; + } + if (!ss.good()) + { + LOGERROR("cAuthenticator: error while parsing response body from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str()); + return false; + } + + std::string Result; + ss >> Result; + LOGINFO("Got result: %s", Result.c_str()); + if (Result.compare("YES") == 0) + { + LOGINFO("Result was \"YES\", so player is authenticated!"); + return true; + } + LOGINFO("Result was \"%s\", so player is NOT authenticated!", Result.c_str()); + return false; +} + + + + diff --git a/source/cAuthenticator.h b/source/cAuthenticator.h index ba75e8eb3..0d69e930e 100644 --- a/source/cAuthenticator.h +++ b/source/cAuthenticator.h @@ -1,85 +1,85 @@ -
-// cAuthenticator.h
-
-// Interfaces to the cAuthenticator class representing the thread that authenticates users against the official MC server
-// Authentication prevents "hackers" from joining with an arbitrary username (possibly impersonating the server admins)
-// For more info, see http://wiki.vg/Session#Server_operation
-// In MCS, authentication is implemented as a single thread that receives queued auth requests and dispatches them one by one.
-
-
-
-
-
-#pragma once
-#ifndef CAUTHENTICATOR_H_INCLUDED
-#define CAUTHENTICATOR_H_INCLUDED
-
-#include "cIsThread.h"
-
-
-
-
-
-// fwd: "cRoot.h"
-class cRoot;
-
-
-
-
-
-class cAuthenticator :
- public cIsThread
-{
- typedef cIsThread super;
-
-public:
- cAuthenticator(void);
- ~cAuthenticator();
-
- /// (Re-)read server and address from INI:
- void ReadINI(void);
-
- /// Queues a request for authenticating a user. If the auth fails, the user is kicked
- void Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash);
-
- // Stops the authenticator thread
- void Stop(void);
-
-private:
-
- class cUser
- {
- public:
- int mClientID;
- AString mName;
- AString mServerHash;
-
- cUser(int a_ClientID, const AString & a_Name, const AString & a_ServerHash) : mClientID(a_ClientID), mName(a_Name), mServerHash(a_ServerHash) {}
- } ;
-
- typedef std::deque<cUser> cUserList;
-
- cCriticalSection m_CS;
- cUserList m_Queue;
- cEvent m_QueueNonempty;
-
- AString m_Server;
- AString m_Address;
- bool m_ShouldAuthenticate;
-
- // cIsThread override:
- virtual void Execute(void) override;
-
- // Returns true if the user authenticated okay, false on error; iLevel is the recursion deptht (bails out if too deep)
- bool AuthFromAddress(const AString & a_Server, const AString & a_Address, const AString & a_UserName, int a_Level = 1);
-};
-
-
-
-
-
-#endif // CAUTHENTICATOR_H_INCLUDED
-
-
-
-
+ +// cAuthenticator.h + +// Interfaces to the cAuthenticator class representing the thread that authenticates users against the official MC server +// Authentication prevents "hackers" from joining with an arbitrary username (possibly impersonating the server admins) +// For more info, see http://wiki.vg/Session#Server_operation +// In MCS, authentication is implemented as a single thread that receives queued auth requests and dispatches them one by one. + + + + + +#pragma once +#ifndef CAUTHENTICATOR_H_INCLUDED +#define CAUTHENTICATOR_H_INCLUDED + +#include "cIsThread.h" + + + + + +// fwd: "cRoot.h" +class cRoot; + + + + + +class cAuthenticator : + public cIsThread +{ + typedef cIsThread super; + +public: + cAuthenticator(void); + ~cAuthenticator(); + + /// (Re-)read server and address from INI: + void ReadINI(void); + + /// Queues a request for authenticating a user. If the auth fails, the user is kicked + void Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash); + + // Stops the authenticator thread + void Stop(void); + +private: + + class cUser + { + public: + int mClientID; + AString mName; + AString mServerHash; + + cUser(int a_ClientID, const AString & a_Name, const AString & a_ServerHash) : mClientID(a_ClientID), mName(a_Name), mServerHash(a_ServerHash) {} + } ; + + typedef std::deque<cUser> cUserList; + + cCriticalSection m_CS; + cUserList m_Queue; + cEvent m_QueueNonempty; + + AString m_Server; + AString m_Address; + bool m_ShouldAuthenticate; + + // cIsThread override: + virtual void Execute(void) override; + + // Returns true if the user authenticated okay, false on error; iLevel is the recursion deptht (bails out if too deep) + bool AuthFromAddress(const AString & a_Server, const AString & a_Address, const AString & a_UserName, int a_Level = 1); +}; + + + + + +#endif // CAUTHENTICATOR_H_INCLUDED + + + + diff --git a/source/cBlockEntity.h b/source/cBlockEntity.h index 8a9e51f56..0a6494ec6 100644 --- a/source/cBlockEntity.h +++ b/source/cBlockEntity.h @@ -1,93 +1,93 @@ -
-#pragma once
-
-#include "cClientHandle.h"
-#include "cWorld.h"
-
-
-
-
-
-#ifndef _WIN32
-#include "BlockID.h"
-#else
-enum ENUM_BLOCK_ID;
-#endif
-
-
-
-
-
-namespace Json
-{
- class Value;
-};
-
-class cPlayer;
-class cWorld;
-class cPacket;
-
-
-
-
-
-class cBlockEntity
-{
-protected:
- cBlockEntity(ENUM_BLOCK_ID a_BlockType, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World)
- : m_PosX( a_BlockX )
- , m_PosY( a_BlockY )
- , m_PosZ( a_BlockZ )
- , m_BlockType( a_BlockType )
- , m_World( a_World )
- {}
-public:
- virtual ~cBlockEntity() {};
- virtual void Destroy() {};
-
- // Position, in absolute block coordinates:
- int GetPosX() { return m_PosX; }
- int GetPosY() { return m_PosY; }
- int GetPosZ() { return m_PosZ; }
-
- ENUM_BLOCK_ID GetBlockType() { return m_BlockType; }
-
- cWorld * GetWorld(void) const {return m_World; }
-
- virtual void SaveToJson (Json::Value & a_Value ) = 0;
-
- virtual void UsedBy( cPlayer * a_Player ) = 0;
-
- void SendTo( cClientHandle* a_Client )
- {
- std::auto_ptr<cPacket> Packet(GetPacket());
- if (Packet.get() == NULL)
- {
- return;
- }
- if ( a_Client != NULL )
- {
- a_Client->Send(*(Packet.get()));
- }
- else // broadcast to all chunk clients
- {
- m_World->BroadcastToChunkOfBlock(m_PosX, m_PosY, m_PosZ, Packet.get());
- }
- }
-
- /// Returns the packet to send to clients to represent this entity; NULL if no packet needed; caller is supposed to delete the packet
- virtual cPacket * GetPacket(void) {return NULL; }
-
-protected:
- int m_PosX; // Position in absolute block coordinates
- int m_PosY;
- int m_PosZ;
-
- ENUM_BLOCK_ID m_BlockType;
-
- cWorld * m_World;
-};
-
-
-
-
+ +#pragma once + +#include "cClientHandle.h" +#include "cWorld.h" + + + + + +#ifndef _WIN32 +#include "BlockID.h" +#else +enum ENUM_BLOCK_ID; +#endif + + + + + +namespace Json +{ + class Value; +}; + +class cPlayer; +class cWorld; +class cPacket; + + + + + +class cBlockEntity +{ +protected: + cBlockEntity(ENUM_BLOCK_ID a_BlockType, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) + : m_PosX( a_BlockX ) + , m_PosY( a_BlockY ) + , m_PosZ( a_BlockZ ) + , m_BlockType( a_BlockType ) + , m_World( a_World ) + {} +public: + virtual ~cBlockEntity() {}; + virtual void Destroy() {}; + + // Position, in absolute block coordinates: + int GetPosX() { return m_PosX; } + int GetPosY() { return m_PosY; } + int GetPosZ() { return m_PosZ; } + + ENUM_BLOCK_ID GetBlockType() { return m_BlockType; } + + cWorld * GetWorld(void) const {return m_World; } + + virtual void SaveToJson (Json::Value & a_Value ) = 0; + + virtual void UsedBy( cPlayer * a_Player ) = 0; + + void SendTo( cClientHandle* a_Client ) + { + std::auto_ptr<cPacket> Packet(GetPacket()); + if (Packet.get() == NULL) + { + return; + } + if ( a_Client != NULL ) + { + a_Client->Send(*(Packet.get())); + } + else // broadcast to all chunk clients + { + m_World->BroadcastToChunkOfBlock(m_PosX, m_PosY, m_PosZ, Packet.get()); + } + } + + /// Returns the packet to send to clients to represent this entity; NULL if no packet needed; caller is supposed to delete the packet + virtual cPacket * GetPacket(void) {return NULL; } + +protected: + int m_PosX; // Position in absolute block coordinates + int m_PosY; + int m_PosZ; + + ENUM_BLOCK_ID m_BlockType; + + cWorld * m_World; +}; + + + + diff --git a/source/cBlockToPickup.cpp b/source/cBlockToPickup.cpp index ceda2b115..8089320e7 100644 --- a/source/cBlockToPickup.cpp +++ b/source/cBlockToPickup.cpp @@ -1,323 +1,323 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cBlockToPickup.h"
-#include "Defines.h"
-#include "BlockID.h"
-#include "MersenneTwister.h"
-
-
-
-
-
-static void AddRandomDrop(cItems & a_Drops, MTRand & r1, int a_OneInNChance, ENUM_ITEM_ID a_ItemID)
-{
- if ((r1.randInt(16 * a_OneInNChance - 1) / 16) != 0)
- {
- return;
- }
- a_Drops.push_back(cItem(a_ItemID, 1));
-}
-
-
-
-
-
-void cBlockToPickup::ToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cItem & a_UsedItem, cItems & a_Drops)
-{
- MTRand r1;
-
- switch (a_BlockType)
- {
- // Blocks that always drop themselves as the only item, no matter what tool; copy damage from meta:
- case E_BLOCK_LOG:
- case E_BLOCK_PLANKS:
- case E_BLOCK_WOOL:
- {
- a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1, a_BlockMeta));
- return;
- }
-
-
- // Blocks that always drop themselves as the only item, no matter what tool, set damage value zero:
- case E_BLOCK_DIRT:
- case E_BLOCK_SAPLING:
- case E_BLOCK_SAND:
- case E_BLOCK_TORCH:
- case E_BLOCK_YELLOW_FLOWER:
- case E_BLOCK_RED_ROSE:
- case E_BLOCK_BROWN_MUSHROOM:
- case E_BLOCK_RED_MUSHROOM:
- case E_BLOCK_TNT:
- case E_BLOCK_CRAFTING_TABLE:
- case E_BLOCK_FURNACE:
- case E_BLOCK_CACTUS:
- case E_BLOCK_REDSTONE_TORCH_OFF:
- case E_BLOCK_POWERED_RAIL:
- case E_BLOCK_DETECTOR_RAIL:
- case E_BLOCK_RAIL:
- case E_BLOCK_LADDER:
- case E_BLOCK_LEVER:
- case E_BLOCK_WOODEN_PRESSURE_PLATE:
- case E_BLOCK_STONE_BUTTON:
- case E_BLOCK_JUKEBOX:
- case E_BLOCK_FENCE:
- case E_BLOCK_FENCE_GATE:
- case E_BLOCK_PUMPKIN:
- case E_BLOCK_NETHERRACK:
- case E_BLOCK_SOULSAND:
- case E_BLOCK_JACK_O_LANTERN:
- case E_BLOCK_TRAPDOOR:
- {
- a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1, 0));
- return;
- }
-
-
- // Blocks that always drop a single item, no matter what tool:
- case E_BLOCK_SIGN_POST:
- case E_BLOCK_WALLSIGN: a_Drops.push_back(cItem(E_ITEM_SIGN, 1)); return;
- case E_BLOCK_REDSTONE_WIRE: a_Drops.push_back(cItem(E_ITEM_REDSTONE_DUST, 1)); return;
- case E_BLOCK_GLOWSTONE: a_Drops.push_back(cItem(E_ITEM_GLOWSTONE_DUST, 1)); return;
- case E_BLOCK_REDSTONE_REPEATER_OFF:
- case E_BLOCK_REDSTONE_REPEATER_ON: a_Drops.push_back(cItem(E_ITEM_REDSTONE_REPEATER, 1)); return;
- case E_BLOCK_COBWEB: a_Drops.push_back(cItem(E_ITEM_STRING, 1)); return;
- case E_BLOCK_FARMLAND:
- case E_BLOCK_GRASS: a_Drops.push_back(cItem(E_ITEM_DIRT, 1)); return;
- case E_BLOCK_LIT_FURNACE: a_Drops.push_back(cItem(E_ITEM_FURNACE, 1)); return;
- case E_BLOCK_SUGARCANE: a_Drops.push_back(cItem(E_ITEM_SUGARCANE, 1)); return;
- case E_BLOCK_PUMPKIN_STEM: a_Drops.push_back(cItem(E_ITEM_PUMPKIN_SEEDS, 1)); return;
- case E_BLOCK_MELON_STEM: a_Drops.push_back(cItem(E_ITEM_MELON_SEEDS, 1)); return;
-
-
- // Doors seem to need their meta set to 1
- case E_BLOCK_WOODEN_DOOR: a_Drops.push_back(cItem(E_ITEM_WOODEN_DOOR, 1, 1)); return;
- case E_BLOCK_IRON_DOOR: a_Drops.push_back(cItem(E_ITEM_IRON_DOOR, 1, 1)); return;
-
-
- ////////////////////////
- // Ores:
-
- // Coal ore requires a pickaxe:
- case E_BLOCK_COAL_ORE:
- {
- if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID))
- {
- a_Drops.push_back(cItem(E_ITEM_COAL, 1));
- }
- return;
- }
-
- // Iron ore requires a stone or better pickaxe:
- case E_BLOCK_IRON_ORE:
- {
- if (
- (a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) ||
- (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) ||
- (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE)
- )
- {
- a_Drops.push_back(cItem(E_ITEM_IRON_ORE, 1));
- }
- return;
- }
-
- // Gold and diamond ores require an iron or better pickaxe:
- case E_BLOCK_GOLD_ORE:
- case E_BLOCK_DIAMOND_ORE:
- {
- if (
- (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) ||
- (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE)
- )
- {
- a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1));
- }
- return;
- }
-
- // Obsidian require a diamond pickaxe:
- case E_BLOCK_OBSIDIAN:
- {
- if (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE)
- {
- a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1));
- }
- return;
- }
-
- // Redstone requires an iron or better pickaxe:
- case E_BLOCK_REDSTONE_ORE_GLOWING:
- case E_BLOCK_REDSTONE_ORE:
- {
- if (
- (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) ||
- (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE)
- )
- {
- a_Drops.push_back(cItem(E_ITEM_REDSTONE_DUST, 4 + (short)r1.randInt(1)));
- }
- return;
- }
-
- // Lapis ore requires a stone or better pickaxe:
- case E_BLOCK_LAPIS_ORE:
- {
- if (
- (a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) ||
- (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) ||
- (a_UsedItem.m_ItemID == E_ITEM_GOLD_PICKAXE) ||
- (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE)
- )
- {
- a_Drops.push_back(cItem(E_ITEM_DYE, 4 + (short)r1.randInt(4), E_META_DYE_BLUE));
- }
- return;
- }
-
-
- ////////////////////////
- // Resource blocks:
-
- // Iron and lapis blocks require a stone or better pickaxe:
- case E_BLOCK_IRON_BLOCK:
- case E_BLOCK_LAPIS_BLOCK:
- {
- if (
- (a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) ||
- (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) ||
- (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE)
- )
- {
- a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1));
- }
- return;
- }
-
- // Diamond and gold blocks require an iron or better pickaxe:
- case E_BLOCK_DIAMOND_BLOCK:
- {
- if (
- (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) ||
- (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE)
- )
- {
- a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1));
- }
- }
-
-
- // These blocks require a pickaxe to drop themselves:
- case E_BLOCK_COBBLESTONE:
- case E_BLOCK_BRICK:
- case E_BLOCK_NETHER_BRICK:
- case E_BLOCK_MOSSY_COBBLESTONE:
- case E_BLOCK_STONE_SLAB:
- case E_BLOCK_COBBLESTONE_STAIRS:
- case E_BLOCK_STONE_BRICK_STAIRS:
- case E_BLOCK_NETHER_BRICK_STAIRS:
- case E_BLOCK_SANDSTONE_STAIRS:
- case E_BLOCK_SANDSTONE:
- case E_BLOCK_STONE_PRESSURE_PLATE:
- {
- if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID))
- {
- a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1));
- }
- return;
- }
-
-
- // Stone requires a pickaxe to drop cobblestone:
- case E_BLOCK_STONE:
- {
- if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID))
- {
- a_Drops.push_back(cItem(E_ITEM_COBBLESTONE, 1));
- }
- return;
- }
-
-
- // Snow requires a shovel to harvest:
- case E_BLOCK_SNOW:
- {
- if (ItemCategory::IsShovel(a_UsedItem.m_ItemID))
- {
- a_Drops.push_back(cItem(E_ITEM_SNOWBALL, 1));
- }
- return;
- }
-
-
- // Leaves require shears for harvesting and have a chance of dropping a sapling and a red apple:
- case E_BLOCK_LEAVES:
- {
- if (a_UsedItem.m_ItemID == E_ITEM_SHEARS)
- {
- a_Drops.push_back(cItem(E_ITEM_LEAVES, 1));
- }
- else
- {
- AddRandomDrop(a_Drops, r1, 5, E_ITEM_SAPLING);
- AddRandomDrop(a_Drops, r1, 200, E_ITEM_APPLE);
- }
- return;
- }
-
-
- // Crops drop a wheat and possibly another seeds when ripe; always drop at least a single seed
- case E_BLOCK_CROPS:
- {
- if (a_BlockMeta == 7)
- {
- AddRandomDrop(a_Drops, r1, 3, E_ITEM_SEEDS);
- a_Drops.push_back(cItem(E_ITEM_WHEAT, 1));
- }
- a_Drops.push_back(cItem(E_ITEM_SEEDS, 1));
- return;
- }
-
-
- // Vines drop only with shears, otherwise they are destroyed
- case E_BLOCK_VINES:
- {
- if (a_UsedItem.m_ItemID == E_ITEM_SHEARS)
- {
- a_Drops.push_back(cItem(E_ITEM_VINES, 1));
- }
- return;
- }
-
-
- // Snow drops only when using a shovel
- case E_BLOCK_SNOW_BLOCK:
- {
- if (ItemCategory::IsShovel(a_UsedItem.m_ItemID))
- {
- a_Drops.push_back(cItem(E_ITEM_SNOWBALL, 4, 0)); return;
- }
- return;
- }
-
-
- // Random multi-drop blocks:
- case E_BLOCK_TALL_GRASS: a_Drops.push_back(cItem(E_ITEM_SEEDS, (short)r1.randInt(3) / 2, 1)); return;
- case E_BLOCK_MELON: a_Drops.push_back(cItem(E_ITEM_MELON_SLICE, 3 + (short)r1.randInt(2), 1)); return;
-
-
- // Fixed multi-drop blocks:
- case E_BLOCK_DOUBLE_STONE_SLAB: a_Drops.push_back(cItem(E_ITEM_STONE_SLAB, 2, 0)); return;
- case E_BLOCK_DOUBLE_WOODEN_SLAB: a_Drops.push_back(cItem(E_ITEM_STEP, 2, 0)); return;
-
- default:
- {
- return;
- }
- } // switch (a_BlockType)
-}
-
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cBlockToPickup.h" +#include "Defines.h" +#include "BlockID.h" +#include "MersenneTwister.h" + + + + + +static void AddRandomDrop(cItems & a_Drops, MTRand & r1, int a_OneInNChance, ENUM_ITEM_ID a_ItemID) +{ + if ((r1.randInt(16 * a_OneInNChance - 1) / 16) != 0) + { + return; + } + a_Drops.push_back(cItem(a_ItemID, 1)); +} + + + + + +void cBlockToPickup::ToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cItem & a_UsedItem, cItems & a_Drops) +{ + MTRand r1; + + switch (a_BlockType) + { + // Blocks that always drop themselves as the only item, no matter what tool; copy damage from meta: + case E_BLOCK_LOG: + case E_BLOCK_PLANKS: + case E_BLOCK_WOOL: + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1, a_BlockMeta)); + return; + } + + + // Blocks that always drop themselves as the only item, no matter what tool, set damage value zero: + case E_BLOCK_DIRT: + case E_BLOCK_SAPLING: + case E_BLOCK_SAND: + case E_BLOCK_TORCH: + case E_BLOCK_YELLOW_FLOWER: + case E_BLOCK_RED_ROSE: + case E_BLOCK_BROWN_MUSHROOM: + case E_BLOCK_RED_MUSHROOM: + case E_BLOCK_TNT: + case E_BLOCK_CRAFTING_TABLE: + case E_BLOCK_FURNACE: + case E_BLOCK_CACTUS: + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_POWERED_RAIL: + case E_BLOCK_DETECTOR_RAIL: + case E_BLOCK_RAIL: + case E_BLOCK_LADDER: + case E_BLOCK_LEVER: + case E_BLOCK_WOODEN_PRESSURE_PLATE: + case E_BLOCK_STONE_BUTTON: + case E_BLOCK_JUKEBOX: + case E_BLOCK_FENCE: + case E_BLOCK_FENCE_GATE: + case E_BLOCK_PUMPKIN: + case E_BLOCK_NETHERRACK: + case E_BLOCK_SOULSAND: + case E_BLOCK_JACK_O_LANTERN: + case E_BLOCK_TRAPDOOR: + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1, 0)); + return; + } + + + // Blocks that always drop a single item, no matter what tool: + case E_BLOCK_SIGN_POST: + case E_BLOCK_WALLSIGN: a_Drops.push_back(cItem(E_ITEM_SIGN, 1)); return; + case E_BLOCK_REDSTONE_WIRE: a_Drops.push_back(cItem(E_ITEM_REDSTONE_DUST, 1)); return; + case E_BLOCK_GLOWSTONE: a_Drops.push_back(cItem(E_ITEM_GLOWSTONE_DUST, 1)); return; + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_REDSTONE_REPEATER_ON: a_Drops.push_back(cItem(E_ITEM_REDSTONE_REPEATER, 1)); return; + case E_BLOCK_COBWEB: a_Drops.push_back(cItem(E_ITEM_STRING, 1)); return; + case E_BLOCK_FARMLAND: + case E_BLOCK_GRASS: a_Drops.push_back(cItem(E_ITEM_DIRT, 1)); return; + case E_BLOCK_LIT_FURNACE: a_Drops.push_back(cItem(E_ITEM_FURNACE, 1)); return; + case E_BLOCK_SUGARCANE: a_Drops.push_back(cItem(E_ITEM_SUGARCANE, 1)); return; + case E_BLOCK_PUMPKIN_STEM: a_Drops.push_back(cItem(E_ITEM_PUMPKIN_SEEDS, 1)); return; + case E_BLOCK_MELON_STEM: a_Drops.push_back(cItem(E_ITEM_MELON_SEEDS, 1)); return; + + + // Doors seem to need their meta set to 1 + case E_BLOCK_WOODEN_DOOR: a_Drops.push_back(cItem(E_ITEM_WOODEN_DOOR, 1, 1)); return; + case E_BLOCK_IRON_DOOR: a_Drops.push_back(cItem(E_ITEM_IRON_DOOR, 1, 1)); return; + + + //////////////////////// + // Ores: + + // Coal ore requires a pickaxe: + case E_BLOCK_COAL_ORE: + { + if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID)) + { + a_Drops.push_back(cItem(E_ITEM_COAL, 1)); + } + return; + } + + // Iron ore requires a stone or better pickaxe: + case E_BLOCK_IRON_ORE: + { + if ( + (a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem(E_ITEM_IRON_ORE, 1)); + } + return; + } + + // Gold and diamond ores require an iron or better pickaxe: + case E_BLOCK_GOLD_ORE: + case E_BLOCK_DIAMOND_ORE: + { + if ( + (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + return; + } + + // Obsidian require a diamond pickaxe: + case E_BLOCK_OBSIDIAN: + { + if (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + return; + } + + // Redstone requires an iron or better pickaxe: + case E_BLOCK_REDSTONE_ORE_GLOWING: + case E_BLOCK_REDSTONE_ORE: + { + if ( + (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem(E_ITEM_REDSTONE_DUST, 4 + (short)r1.randInt(1))); + } + return; + } + + // Lapis ore requires a stone or better pickaxe: + case E_BLOCK_LAPIS_ORE: + { + if ( + (a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_GOLD_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem(E_ITEM_DYE, 4 + (short)r1.randInt(4), E_META_DYE_BLUE)); + } + return; + } + + + //////////////////////// + // Resource blocks: + + // Iron and lapis blocks require a stone or better pickaxe: + case E_BLOCK_IRON_BLOCK: + case E_BLOCK_LAPIS_BLOCK: + { + if ( + (a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + return; + } + + // Diamond and gold blocks require an iron or better pickaxe: + case E_BLOCK_DIAMOND_BLOCK: + { + if ( + (a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + } + + + // These blocks require a pickaxe to drop themselves: + case E_BLOCK_COBBLESTONE: + case E_BLOCK_BRICK: + case E_BLOCK_NETHER_BRICK: + case E_BLOCK_MOSSY_COBBLESTONE: + case E_BLOCK_STONE_SLAB: + case E_BLOCK_COBBLESTONE_STAIRS: + case E_BLOCK_STONE_BRICK_STAIRS: + case E_BLOCK_NETHER_BRICK_STAIRS: + case E_BLOCK_SANDSTONE_STAIRS: + case E_BLOCK_SANDSTONE: + case E_BLOCK_STONE_PRESSURE_PLATE: + { + if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID)) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + return; + } + + + // Stone requires a pickaxe to drop cobblestone: + case E_BLOCK_STONE: + { + if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID)) + { + a_Drops.push_back(cItem(E_ITEM_COBBLESTONE, 1)); + } + return; + } + + + // Snow requires a shovel to harvest: + case E_BLOCK_SNOW: + { + if (ItemCategory::IsShovel(a_UsedItem.m_ItemID)) + { + a_Drops.push_back(cItem(E_ITEM_SNOWBALL, 1)); + } + return; + } + + + // Leaves require shears for harvesting and have a chance of dropping a sapling and a red apple: + case E_BLOCK_LEAVES: + { + if (a_UsedItem.m_ItemID == E_ITEM_SHEARS) + { + a_Drops.push_back(cItem(E_ITEM_LEAVES, 1)); + } + else + { + AddRandomDrop(a_Drops, r1, 5, E_ITEM_SAPLING); + AddRandomDrop(a_Drops, r1, 200, E_ITEM_APPLE); + } + return; + } + + + // Crops drop a wheat and possibly another seeds when ripe; always drop at least a single seed + case E_BLOCK_CROPS: + { + if (a_BlockMeta == 7) + { + AddRandomDrop(a_Drops, r1, 3, E_ITEM_SEEDS); + a_Drops.push_back(cItem(E_ITEM_WHEAT, 1)); + } + a_Drops.push_back(cItem(E_ITEM_SEEDS, 1)); + return; + } + + + // Vines drop only with shears, otherwise they are destroyed + case E_BLOCK_VINES: + { + if (a_UsedItem.m_ItemID == E_ITEM_SHEARS) + { + a_Drops.push_back(cItem(E_ITEM_VINES, 1)); + } + return; + } + + + // Snow drops only when using a shovel + case E_BLOCK_SNOW_BLOCK: + { + if (ItemCategory::IsShovel(a_UsedItem.m_ItemID)) + { + a_Drops.push_back(cItem(E_ITEM_SNOWBALL, 4, 0)); return; + } + return; + } + + + // Random multi-drop blocks: + case E_BLOCK_TALL_GRASS: a_Drops.push_back(cItem(E_ITEM_SEEDS, (short)r1.randInt(3) / 2, 1)); return; + case E_BLOCK_MELON: a_Drops.push_back(cItem(E_ITEM_MELON_SLICE, 3 + (short)r1.randInt(2), 1)); return; + + + // Fixed multi-drop blocks: + case E_BLOCK_DOUBLE_STONE_SLAB: a_Drops.push_back(cItem(E_ITEM_STONE_SLAB, 2, 0)); return; + case E_BLOCK_DOUBLE_WOODEN_SLAB: a_Drops.push_back(cItem(E_ITEM_STEP, 2, 0)); return; + + default: + { + return; + } + } // switch (a_BlockType) +} + + + + + diff --git a/source/cBlockToPickup.h b/source/cBlockToPickup.h index 195f96bf6..559e0a052 100644 --- a/source/cBlockToPickup.h +++ b/source/cBlockToPickup.h @@ -1,28 +1,28 @@ -#pragma once
-
-#ifndef _WIN32
- #include "BlockID.h"
-#else
- enum ENUM_ITEM_ID;
-#endif
-
-#include "cItem.h"
-
-
-
-
-
-class cBlockToPickup // tolua_export
-{ // tolua_export
-public:
- /// For a given block and tool, returns the list of drops generated
- static void ToPickup(BLOCKTYPE a_BlockID, NIBBLETYPE a_BlockMeta, const cItem & a_UsedItem, cItems & a_Drops); // tolua_export
-
- /// Returns true if the tool used for the block is the right one for the job. cClientHandle uses this to determine whether to decrease tool durability twice as much
- static bool IsRightTool(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, ENUM_ITEM_ID a_UsedTool); // tolua_export
-
-}; // tolua_export
-
-
-
-
+#pragma once + +#ifndef _WIN32 + #include "BlockID.h" +#else + enum ENUM_ITEM_ID; +#endif + +#include "cItem.h" + + + + + +class cBlockToPickup // tolua_export +{ // tolua_export +public: + /// For a given block and tool, returns the list of drops generated + static void ToPickup(BLOCKTYPE a_BlockID, NIBBLETYPE a_BlockMeta, const cItem & a_UsedItem, cItems & a_Drops); // tolua_export + + /// Returns true if the tool used for the block is the right one for the job. cClientHandle uses this to determine whether to decrease tool durability twice as much + static bool IsRightTool(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, ENUM_ITEM_ID a_UsedTool); // tolua_export + +}; // tolua_export + + + + diff --git a/source/cBlockingTCPLink.cpp b/source/cBlockingTCPLink.cpp index da82f3801..741eb328c 100644 --- a/source/cBlockingTCPLink.cpp +++ b/source/cBlockingTCPLink.cpp @@ -1,150 +1,150 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cBlockingTCPLink.h"
-#include "packets/cPacket.h"
-
-
-
-
-
-#ifdef _WIN32
- #define MSG_NOSIGNAL (0)
-#endif
-#ifdef __MACH__
- #define MSG_NOSIGNAL (0)
-#endif
-
-
-
-
-
-cBlockingTCPLink::cBlockingTCPLink(void)
-{
-}
-
-
-
-
-
-cBlockingTCPLink::~cBlockingTCPLink()
-{
- CloseSocket();
-}
-
-
-
-
-
-void cBlockingTCPLink::CloseSocket()
-{
- if (!m_Socket.IsValid())
- {
- m_Socket.CloseSocket();
- }
-}
-
-
-
-
-
-bool cBlockingTCPLink::Connect(const char * iAddress, unsigned int iPort)
-{
- ASSERT(!m_Socket.IsValid());
- if (m_Socket.IsValid())
- {
- LOGWARN("WARNING: cTCPLink Connect() called while still connected.");
- m_Socket.CloseSocket();
- }
-
- struct hostent *hp;
- unsigned int addr;
- struct sockaddr_in server;
-
- m_Socket = socket(AF_INET, SOCK_STREAM, 0);
- if (!m_Socket.IsValid())
- {
- LOGERROR("cTCPLink: Cannot create a socket");
- return false;
- }
-
- addr = inet_addr(iAddress);
- hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
- if (hp == NULL)
- {
- //LOGWARN("cTCPLink: gethostbyaddr returned NULL");
- hp = gethostbyname(iAddress);
- if (hp == NULL)
- {
- LOGWARN("cTCPLink: Could not resolve %s", iAddress);
- CloseSocket();
- return false;
- }
- }
-
- server.sin_addr.s_addr = *((unsigned long *)hp->h_addr);
- server.sin_family = AF_INET;
- server.sin_port = htons( (unsigned short)iPort);
- if (connect(m_Socket, (struct sockaddr *)&server, sizeof(server)))
- {
- LOGWARN("cTCPLink: Connection to \"%s:%d\" failed (%s)", iAddress, iPort, cSocket::GetErrorString( cSocket::GetLastError() ).c_str() );
- CloseSocket();
- return false;
- }
-
- return true;
-}
-
-
-
-
-
-int cBlockingTCPLink::Send(char * a_Data, unsigned int a_Size, int a_Flags /* = 0 */ )
-{
- ASSERT(m_Socket.IsValid());
- if (!m_Socket.IsValid())
- {
- LOGERROR("cBlockingTCPLink: Trying to send data without a valid connection!");
- return -1;
- }
- return m_Socket.Send(a_Data, a_Size);
-}
-
-
-
-
-
-int cBlockingTCPLink::SendMessage( const char* a_Message, int a_Flags /* = 0 */ )
-{
- ASSERT(m_Socket.IsValid());
- if (!m_Socket.IsValid())
- {
- LOGWARN("cBlockingTCPLink: Trying to send message without a valid connection!");
- return -1;
- }
- return m_Socket.Send(a_Message, strlen(a_Message));
-}
-
-
-
-
-
-void cBlockingTCPLink::ReceiveData(AString & oData)
-{
- ASSERT(m_Socket.IsValid());
- if (!m_Socket.IsValid())
- {
- return;
- }
-
- int Received = 0;
- char Buffer[256];
- while ((Received = recv(m_Socket, Buffer, sizeof(Buffer), 0)) > 0)
- {
- oData.append(Buffer, Received);
- }
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cBlockingTCPLink.h" +#include "packets/cPacket.h" + + + + + +#ifdef _WIN32 + #define MSG_NOSIGNAL (0) +#endif +#ifdef __MACH__ + #define MSG_NOSIGNAL (0) +#endif + + + + + +cBlockingTCPLink::cBlockingTCPLink(void) +{ +} + + + + + +cBlockingTCPLink::~cBlockingTCPLink() +{ + CloseSocket(); +} + + + + + +void cBlockingTCPLink::CloseSocket() +{ + if (!m_Socket.IsValid()) + { + m_Socket.CloseSocket(); + } +} + + + + + +bool cBlockingTCPLink::Connect(const char * iAddress, unsigned int iPort) +{ + ASSERT(!m_Socket.IsValid()); + if (m_Socket.IsValid()) + { + LOGWARN("WARNING: cTCPLink Connect() called while still connected."); + m_Socket.CloseSocket(); + } + + struct hostent *hp; + unsigned int addr; + struct sockaddr_in server; + + m_Socket = socket(AF_INET, SOCK_STREAM, 0); + if (!m_Socket.IsValid()) + { + LOGERROR("cTCPLink: Cannot create a socket"); + return false; + } + + addr = inet_addr(iAddress); + hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET); + if (hp == NULL) + { + //LOGWARN("cTCPLink: gethostbyaddr returned NULL"); + hp = gethostbyname(iAddress); + if (hp == NULL) + { + LOGWARN("cTCPLink: Could not resolve %s", iAddress); + CloseSocket(); + return false; + } + } + + server.sin_addr.s_addr = *((unsigned long *)hp->h_addr); + server.sin_family = AF_INET; + server.sin_port = htons( (unsigned short)iPort); + if (connect(m_Socket, (struct sockaddr *)&server, sizeof(server))) + { + LOGWARN("cTCPLink: Connection to \"%s:%d\" failed (%s)", iAddress, iPort, cSocket::GetErrorString( cSocket::GetLastError() ).c_str() ); + CloseSocket(); + return false; + } + + return true; +} + + + + + +int cBlockingTCPLink::Send(char * a_Data, unsigned int a_Size, int a_Flags /* = 0 */ ) +{ + ASSERT(m_Socket.IsValid()); + if (!m_Socket.IsValid()) + { + LOGERROR("cBlockingTCPLink: Trying to send data without a valid connection!"); + return -1; + } + return m_Socket.Send(a_Data, a_Size); +} + + + + + +int cBlockingTCPLink::SendMessage( const char* a_Message, int a_Flags /* = 0 */ ) +{ + ASSERT(m_Socket.IsValid()); + if (!m_Socket.IsValid()) + { + LOGWARN("cBlockingTCPLink: Trying to send message without a valid connection!"); + return -1; + } + return m_Socket.Send(a_Message, strlen(a_Message)); +} + + + + + +void cBlockingTCPLink::ReceiveData(AString & oData) +{ + ASSERT(m_Socket.IsValid()); + if (!m_Socket.IsValid()) + { + return; + } + + int Received = 0; + char Buffer[256]; + while ((Received = recv(m_Socket, Buffer, sizeof(Buffer), 0)) > 0) + { + oData.append(Buffer, Received); + } +} + + + + diff --git a/source/cBlockingTCPLink.h b/source/cBlockingTCPLink.h index ff89f7db3..feba52970 100644 --- a/source/cBlockingTCPLink.h +++ b/source/cBlockingTCPLink.h @@ -1,28 +1,28 @@ -
-#pragma once
-
-#include "cSocket.h"
-
-
-
-
-
-class cBlockingTCPLink //tolua_export
-{ //tolua_export
-public: //tolua_export
- cBlockingTCPLink(void); //tolua_export
- ~cBlockingTCPLink(); //tolua_export
-
- bool Connect( const char* a_Address, unsigned int a_Port ); //tolua_export
- int Send( char* a_Data, unsigned int a_Size, int a_Flags = 0 ); //tolua_export
- int SendMessage( const char* a_Message, int a_Flags = 0 ); //tolua_export
- void CloseSocket(); //tolua_export
- void ReceiveData(AString & oData); //tolua_export
-protected:
-
- cSocket m_Socket;
-}; //tolua_export
-
-
-
-
+ +#pragma once + +#include "cSocket.h" + + + + + +class cBlockingTCPLink //tolua_export +{ //tolua_export +public: //tolua_export + cBlockingTCPLink(void); //tolua_export + ~cBlockingTCPLink(); //tolua_export + + bool Connect( const char* a_Address, unsigned int a_Port ); //tolua_export + int Send( char* a_Data, unsigned int a_Size, int a_Flags = 0 ); //tolua_export + int SendMessage( const char* a_Message, int a_Flags = 0 ); //tolua_export + void CloseSocket(); //tolua_export + void ReceiveData(AString & oData); //tolua_export +protected: + + cSocket m_Socket; +}; //tolua_export + + + + diff --git a/source/cCavespider.cpp b/source/cCavespider.cpp index 8c2a1ca2c..8d0285674 100644 --- a/source/cCavespider.cpp +++ b/source/cCavespider.cpp @@ -1,59 +1,59 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cCavespider.h"
-
-
-
-
-
-cCavespider::cCavespider()
-{
- m_MobType = 59;
- GetMonsterConfig("Cavespider");
-}
-
-
-
-
-
-cCavespider::~cCavespider()
-{
-}
-
-
-
-
-
-bool cCavespider::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cCavespider" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
-
-
-
-
-
-void cCavespider::Tick(float a_Dt)
-{
- cMonster::Tick(a_Dt);
- m_EMPersonality = (GetWorld()->GetWorldTime() < (12000 + 1000) ) ? PASSIVE : AGGRESSIVE;
-}
-
-
-
-
-
-void cCavespider::KilledBy( cEntity* a_Killer )
-{
- cItems Drops;
- AddRandomDropItem(Drops, 0, 2, E_ITEM_STRING);
- AddRandomDropItem(Drops, 0, 1, E_ITEM_SPIDER_EYE);
-
- cMonster::KilledBy( a_Killer );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cCavespider.h" + + + + + +cCavespider::cCavespider() +{ + m_MobType = 59; + GetMonsterConfig("Cavespider"); +} + + + + + +cCavespider::~cCavespider() +{ +} + + + + + +bool cCavespider::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cCavespider" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cCavespider::Tick(float a_Dt) +{ + cMonster::Tick(a_Dt); + m_EMPersonality = (GetWorld()->GetWorldTime() < (12000 + 1000) ) ? PASSIVE : AGGRESSIVE; +} + + + + + +void cCavespider::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_STRING); + AddRandomDropItem(Drops, 0, 1, E_ITEM_SPIDER_EYE); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cChatColor.cpp b/source/cChatColor.cpp index 50d9bbc63..228dc7a38 100644 --- a/source/cChatColor.cpp +++ b/source/cChatColor.cpp @@ -1,39 +1,39 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cChatColor.h"
-
-const std::string cChatColor::Color = "\xa7"; // Old color was "\xc2\xa7" or in other words: "§"
-const std::string cChatColor::Delimiter = "\xa7";
-const std::string cChatColor::Black = cChatColor::Color + "0";
-const std::string cChatColor::Navy = cChatColor::Color + "1";
-const std::string cChatColor::Green = cChatColor::Color + "2";
-const std::string cChatColor::Blue = cChatColor::Color + "3";
-const std::string cChatColor::Red = cChatColor::Color + "4";
-const std::string cChatColor::Purple = cChatColor::Color + "5";
-const std::string cChatColor::Gold = cChatColor::Color + "6";
-const std::string cChatColor::LightGray = cChatColor::Color + "7";
-const std::string cChatColor::Gray = cChatColor::Color + "8";
-const std::string cChatColor::DarkPurple = cChatColor::Color + "9";
-const std::string cChatColor::LightGreen = cChatColor::Color + "a";
-const std::string cChatColor::LightBlue = cChatColor::Color + "b";
-const std::string cChatColor::Rose = cChatColor::Color + "c";
-const std::string cChatColor::LightPurple = cChatColor::Color + "d";
-const std::string cChatColor::Yellow = cChatColor::Color + "e";
-const std::string cChatColor::White = cChatColor::Color + "f";
-
-const std::string cChatColor::Random = cChatColor::Color + "k";
-const std::string cChatColor::Bold = cChatColor::Color + "l";
-const std::string cChatColor::Strikethrough = cChatColor::Color + "m";
-const std::string cChatColor::Underlined = cChatColor::Color + "n";
-const std::string cChatColor::Italic = cChatColor::Color + "o";
-const std::string cChatColor::Plain = cChatColor::Color + "r";
-
-const std::string cChatColor::MakeColor( char a_Color )
-{
- return cChatColor::Color + a_Color;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cChatColor.h" + +const std::string cChatColor::Color = "\xa7"; // Old color was "\xc2\xa7" or in other words: "§" +const std::string cChatColor::Delimiter = "\xa7"; +const std::string cChatColor::Black = cChatColor::Color + "0"; +const std::string cChatColor::Navy = cChatColor::Color + "1"; +const std::string cChatColor::Green = cChatColor::Color + "2"; +const std::string cChatColor::Blue = cChatColor::Color + "3"; +const std::string cChatColor::Red = cChatColor::Color + "4"; +const std::string cChatColor::Purple = cChatColor::Color + "5"; +const std::string cChatColor::Gold = cChatColor::Color + "6"; +const std::string cChatColor::LightGray = cChatColor::Color + "7"; +const std::string cChatColor::Gray = cChatColor::Color + "8"; +const std::string cChatColor::DarkPurple = cChatColor::Color + "9"; +const std::string cChatColor::LightGreen = cChatColor::Color + "a"; +const std::string cChatColor::LightBlue = cChatColor::Color + "b"; +const std::string cChatColor::Rose = cChatColor::Color + "c"; +const std::string cChatColor::LightPurple = cChatColor::Color + "d"; +const std::string cChatColor::Yellow = cChatColor::Color + "e"; +const std::string cChatColor::White = cChatColor::Color + "f"; + +const std::string cChatColor::Random = cChatColor::Color + "k"; +const std::string cChatColor::Bold = cChatColor::Color + "l"; +const std::string cChatColor::Strikethrough = cChatColor::Color + "m"; +const std::string cChatColor::Underlined = cChatColor::Color + "n"; +const std::string cChatColor::Italic = cChatColor::Color + "o"; +const std::string cChatColor::Plain = cChatColor::Color + "r"; + +const std::string cChatColor::MakeColor( char a_Color ) +{ + return cChatColor::Color + a_Color; +} + + + + diff --git a/source/cChatColor.h b/source/cChatColor.h index 8c12c7e29..85b10f400 100644 --- a/source/cChatColor.h +++ b/source/cChatColor.h @@ -1,43 +1,43 @@ -
-#pragma once
-
-
-
-
-
-// tolua_begin
-class cChatColor
-{
-public:
- static const std::string Color;
- static const std::string Delimiter;
-
- static const std::string Black;
- static const std::string Navy;
- static const std::string Green;
- static const std::string Blue;
- static const std::string Red;
- static const std::string Purple;
- static const std::string Gold;
- static const std::string LightGray;
- static const std::string Gray;
- static const std::string DarkPurple;
- static const std::string LightGreen;
- static const std::string LightBlue;
- static const std::string Rose;
- static const std::string LightPurple;
- static const std::string Yellow;
- static const std::string White;
-
- // Styles ( source: http://wiki.vg/Chat )
- static const std::string Random;
- static const std::string Bold;
- static const std::string Strikethrough;
- static const std::string Underlined;
- static const std::string Italic;
- static const std::string Plain;
-
- static const std::string MakeColor( char a_Color );
-};
-
-// tolua_end
+ +#pragma once + + + + + +// tolua_begin +class cChatColor +{ +public: + static const std::string Color; + static const std::string Delimiter; + + static const std::string Black; + static const std::string Navy; + static const std::string Green; + static const std::string Blue; + static const std::string Red; + static const std::string Purple; + static const std::string Gold; + static const std::string LightGray; + static const std::string Gray; + static const std::string DarkPurple; + static const std::string LightGreen; + static const std::string LightBlue; + static const std::string Rose; + static const std::string LightPurple; + static const std::string Yellow; + static const std::string White; + + // Styles ( source: http://wiki.vg/Chat ) + static const std::string Random; + static const std::string Bold; + static const std::string Strikethrough; + static const std::string Underlined; + static const std::string Italic; + static const std::string Plain; + + static const std::string MakeColor( char a_Color ); +}; + +// tolua_end diff --git a/source/cChestEntity.cpp b/source/cChestEntity.cpp index 35fb2894e..d2cc168b0 100644 --- a/source/cChestEntity.cpp +++ b/source/cChestEntity.cpp @@ -1,234 +1,234 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cChestEntity.h"
-#include "cItem.h"
-#include "cClientHandle.h"
-#include "cPlayer.h"
-#include "cWindow.h"
-#include "cWorld.h"
-#include "cRoot.h"
-#include "cPickup.h"
-#include <json/json.h>
-
-
-
-
-
-class cWorld;
-class cRoot;
-
-
-
-
-
-cChestEntity::cChestEntity(int a_X, int a_Y, int a_Z, cWorld * a_World)
- : cBlockEntity( E_BLOCK_CHEST, a_X, a_Y, a_Z, a_World)
- , m_TopChest( false )
- , m_JoinedChest( NULL )
-{
- m_Content = new cItem[ c_ChestHeight * c_ChestWidth ];
-}
-
-
-
-
-
-cChestEntity::~cChestEntity()
-{
- if( GetWindow() )
- {
- GetWindow()->OwnerDestroyed();
- }
-
- if( m_Content )
- {
- delete [] m_Content;
- }
-}
-
-
-
-
-
-void cChestEntity::Destroy()
-{
- // Drop items
- cItems Pickups;
- for( int i = 0; i < c_ChestHeight * c_ChestWidth; ++i )
- {
- if( !m_Content[i].IsEmpty() )
- {
- Pickups.push_back(m_Content[i]);
- m_Content[i].Empty();
- }
- }
- m_World->SpawnItemPickups(Pickups, m_PosX, m_PosY, m_PosZ);
- if (m_JoinedChest)
- {
- m_JoinedChest->RemoveJoinedChest(this);
- }
-}
-
-
-
-
-
-const cItem * cChestEntity::GetSlot( int a_Slot ) const
-{
- if( a_Slot > -1 && a_Slot < c_ChestHeight*c_ChestWidth )
- {
- return &m_Content[ a_Slot ];
- }
- return 0;
-}
-
-
-
-
-
-void cChestEntity::SetSlot( int a_Slot, cItem & a_Item )
-{
- if( a_Slot > -1 && a_Slot < c_ChestHeight*c_ChestWidth )
- {
- m_Content[a_Slot] = a_Item;
- }
-}
-
-
-
-
-
-#define READ(File, Var) \
- if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \
- { \
- LOGERROR("ERROR READING cChestEntity %s FROM FILE (line %d)", #Var, __LINE__); \
- return false; \
- }
-
-
-
-
-
-
-bool cChestEntity::LoadFromJson( const Json::Value& a_Value )
-{
- m_PosX = a_Value.get("x", 0).asInt();
- m_PosY = a_Value.get("y", 0).asInt();
- m_PosZ = a_Value.get("z", 0).asInt();
-
- Json::Value AllSlots = a_Value.get("Slots", 0);
- int SlotIdx = 0;
- for( Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr )
- {
- cItem Item;
- Item.FromJson( *itr );
- SetSlot( SlotIdx, Item );
- SlotIdx++;
- }
- return true;
-}
-
-
-
-
-
-void cChestEntity::SaveToJson( Json::Value& a_Value )
-{
- a_Value["x"] = m_PosX;
- a_Value["y"] = m_PosY;
- a_Value["z"] = m_PosZ;
-
- unsigned int NumSlots = c_ChestHeight*c_ChestWidth;
- Json::Value AllSlots;
- for(unsigned int i = 0; i < NumSlots; i++)
- {
- Json::Value Slot;
- const cItem * Item = GetSlot( i );
- if( Item ) Item->GetJson( Slot );
- AllSlots.append( Slot );
- }
- a_Value["Slots"] = AllSlots;
-}
-
-
-
-
-
-void cChestEntity::SendTo( cClientHandle* a_Client, cServer* a_Server )
-{
- (void)a_Client;
- (void)a_Server;
- return;
-}
-
-
-
-
-
-void cChestEntity::UsedBy( cPlayer * a_Player )
-{
- if( !GetWindow() )
- {
- cWindow* Window = new cWindow( this, true );
- Window->SetSlots( GetContents(), GetChestHeight()*c_ChestWidth );
- Window->SetWindowID( 1 );
- Window->SetWindowType( cWindow::Chest );
- Window->SetWindowTitle("UberChest");
- Window->GetOwner()->SetEntity(this);
- OpenWindow( Window );
- }
- if ( GetWindow() )
- {
- if( a_Player->GetWindow() != GetWindow() )
- {
- a_Player->OpenWindow( GetWindow() );
- GetWindow()->SendWholeWindow( a_Player->GetClientHandle() );
- }
- }
- cPacket_BlockAction ChestOpen;
- ChestOpen.m_PosX = GetPosX();
- ChestOpen.m_PosY = (short)GetPosY();
- ChestOpen.m_PosZ = GetPosZ();
- ChestOpen.m_Byte1 = (char)1;
- ChestOpen.m_Byte2 = (char)1;
- m_World->BroadcastToChunkOfBlock(m_PosX, m_PosY, m_PosZ, &ChestOpen);
-
- // This is rather a hack
- // Instead of marking the chunk as dirty upon chest contents change, we mark it dirty now
- // We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first.
- // The few false positives aren't much to worry about
- int ChunkX, ChunkY = 0, ChunkZ;
- cChunkDef::BlockToChunk(m_PosX, m_PosY, m_PosZ, ChunkX, ChunkZ);
- m_World->MarkChunkDirty(ChunkX, ChunkY, ChunkZ);
-}
-
-
-
-
-
-cItem *cChestEntity::GetContents(bool a_OnlyThis)
-{
- if (m_JoinedChest && !a_OnlyThis)
- {
- cItem *Combined = new cItem[GetChestHeight()*c_ChestWidth];
- int i;
- cItem *first = (m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true);
- cItem *second = (!m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true);
- for (i=0; i < GetChestHeight()*c_ChestWidth; i++)
- {
- int index = i % c_ChestHeight*c_ChestWidth;
- if (i < c_ChestHeight*c_ChestWidth)
- Combined[index] = first[index];
- else
- Combined[index] = second[index];
- }
- return Combined;
- }
- else
- return m_Content;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cChestEntity.h" +#include "cItem.h" +#include "cClientHandle.h" +#include "cPlayer.h" +#include "cWindow.h" +#include "cWorld.h" +#include "cRoot.h" +#include "cPickup.h" +#include <json/json.h> + + + + + +class cWorld; +class cRoot; + + + + + +cChestEntity::cChestEntity(int a_X, int a_Y, int a_Z, cWorld * a_World) + : cBlockEntity( E_BLOCK_CHEST, a_X, a_Y, a_Z, a_World) + , m_TopChest( false ) + , m_JoinedChest( NULL ) +{ + m_Content = new cItem[ c_ChestHeight * c_ChestWidth ]; +} + + + + + +cChestEntity::~cChestEntity() +{ + if( GetWindow() ) + { + GetWindow()->OwnerDestroyed(); + } + + if( m_Content ) + { + delete [] m_Content; + } +} + + + + + +void cChestEntity::Destroy() +{ + // Drop items + cItems Pickups; + for( int i = 0; i < c_ChestHeight * c_ChestWidth; ++i ) + { + if( !m_Content[i].IsEmpty() ) + { + Pickups.push_back(m_Content[i]); + m_Content[i].Empty(); + } + } + m_World->SpawnItemPickups(Pickups, m_PosX, m_PosY, m_PosZ); + if (m_JoinedChest) + { + m_JoinedChest->RemoveJoinedChest(this); + } +} + + + + + +const cItem * cChestEntity::GetSlot( int a_Slot ) const +{ + if( a_Slot > -1 && a_Slot < c_ChestHeight*c_ChestWidth ) + { + return &m_Content[ a_Slot ]; + } + return 0; +} + + + + + +void cChestEntity::SetSlot( int a_Slot, cItem & a_Item ) +{ + if( a_Slot > -1 && a_Slot < c_ChestHeight*c_ChestWidth ) + { + m_Content[a_Slot] = a_Item; + } +} + + + + + +#define READ(File, Var) \ + if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("ERROR READING cChestEntity %s FROM FILE (line %d)", #Var, __LINE__); \ + return false; \ + } + + + + + + +bool cChestEntity::LoadFromJson( const Json::Value& a_Value ) +{ + m_PosX = a_Value.get("x", 0).asInt(); + m_PosY = a_Value.get("y", 0).asInt(); + m_PosZ = a_Value.get("z", 0).asInt(); + + Json::Value AllSlots = a_Value.get("Slots", 0); + int SlotIdx = 0; + for( Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr ) + { + cItem Item; + Item.FromJson( *itr ); + SetSlot( SlotIdx, Item ); + SlotIdx++; + } + return true; +} + + + + + +void cChestEntity::SaveToJson( Json::Value& a_Value ) +{ + a_Value["x"] = m_PosX; + a_Value["y"] = m_PosY; + a_Value["z"] = m_PosZ; + + unsigned int NumSlots = c_ChestHeight*c_ChestWidth; + Json::Value AllSlots; + for(unsigned int i = 0; i < NumSlots; i++) + { + Json::Value Slot; + const cItem * Item = GetSlot( i ); + if( Item ) Item->GetJson( Slot ); + AllSlots.append( Slot ); + } + a_Value["Slots"] = AllSlots; +} + + + + + +void cChestEntity::SendTo( cClientHandle* a_Client, cServer* a_Server ) +{ + (void)a_Client; + (void)a_Server; + return; +} + + + + + +void cChestEntity::UsedBy( cPlayer * a_Player ) +{ + if( !GetWindow() ) + { + cWindow* Window = new cWindow( this, true ); + Window->SetSlots( GetContents(), GetChestHeight()*c_ChestWidth ); + Window->SetWindowID( 1 ); + Window->SetWindowType( cWindow::Chest ); + Window->SetWindowTitle("UberChest"); + Window->GetOwner()->SetEntity(this); + OpenWindow( Window ); + } + if ( GetWindow() ) + { + if( a_Player->GetWindow() != GetWindow() ) + { + a_Player->OpenWindow( GetWindow() ); + GetWindow()->SendWholeWindow( a_Player->GetClientHandle() ); + } + } + cPacket_BlockAction ChestOpen; + ChestOpen.m_PosX = GetPosX(); + ChestOpen.m_PosY = (short)GetPosY(); + ChestOpen.m_PosZ = GetPosZ(); + ChestOpen.m_Byte1 = (char)1; + ChestOpen.m_Byte2 = (char)1; + m_World->BroadcastToChunkOfBlock(m_PosX, m_PosY, m_PosZ, &ChestOpen); + + // This is rather a hack + // Instead of marking the chunk as dirty upon chest contents change, we mark it dirty now + // We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first. + // The few false positives aren't much to worry about + int ChunkX, ChunkY = 0, ChunkZ; + cChunkDef::BlockToChunk(m_PosX, m_PosY, m_PosZ, ChunkX, ChunkZ); + m_World->MarkChunkDirty(ChunkX, ChunkY, ChunkZ); +} + + + + + +cItem *cChestEntity::GetContents(bool a_OnlyThis) +{ + if (m_JoinedChest && !a_OnlyThis) + { + cItem *Combined = new cItem[GetChestHeight()*c_ChestWidth]; + int i; + cItem *first = (m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true); + cItem *second = (!m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true); + for (i=0; i < GetChestHeight()*c_ChestWidth; i++) + { + int index = i % c_ChestHeight*c_ChestWidth; + if (i < c_ChestHeight*c_ChestWidth) + Combined[index] = first[index]; + else + Combined[index] = second[index]; + } + return Combined; + } + else + return m_Content; +} + + + + diff --git a/source/cChestEntity.h b/source/cChestEntity.h index 6e625f8f5..b24533d76 100644 --- a/source/cChestEntity.h +++ b/source/cChestEntity.h @@ -1,66 +1,66 @@ -
-#pragma once
-
-#include "cBlockEntity.h"
-#include "cWindowOwner.h"
-#include "packets/cPacket_BlockAction.h"
-
-
-
-
-
-namespace Json
-{
- class Value;
-};
-
-class cClientHandle;
-class cServer;
-class cItem;
-class cNBTData;
-
-
-
-
-
-class cChestEntity :
- public cBlockEntity,
- public cWindowOwner
-{
-public:
- cChestEntity(int a_X, int a_Y, int a_Z, cWorld * a_World);
- virtual ~cChestEntity();
- virtual void Destroy();
-
- void HandleData( cNBTData* a_NBTData );
-
- const cItem * GetSlot( int a_Slot ) const;
- void SetSlot( int a_Slot, cItem & a_Item );
-
- bool LoadFromJson( const Json::Value& a_Value );
- virtual void SaveToJson(Json::Value& a_Value ) override;
-
- void SendTo( cClientHandle* a_Client, cServer* a_Server );
-
- virtual void UsedBy( cPlayer * a_Player ) override;
-
- cChestEntity *GetJoinedChest() { return m_JoinedChest; }
- void SetJoinedChest(cChestEntity *a_Chest) { m_JoinedChest = a_Chest; }
- void RemoveJoinedChest(cChestEntity *a_Chest) { if (m_JoinedChest && m_JoinedChest == a_Chest) { m_JoinedChest = NULL; m_TopChest = false; } }
-
- int GetChestHeight() { return ((m_JoinedChest) ? c_ChestHeight * 2 : c_ChestHeight); }
- cItem * GetContents(bool a_OnlyThis = false);
-
- static const int c_ChestWidth = 9;
- static const int c_ChestHeight = 3;
-
-private:
-
- cItem * m_Content;
- bool m_TopChest;
- cChestEntity * m_JoinedChest;
-};
-
-
-
-
+ +#pragma once + +#include "cBlockEntity.h" +#include "cWindowOwner.h" +#include "packets/cPacket_BlockAction.h" + + + + + +namespace Json +{ + class Value; +}; + +class cClientHandle; +class cServer; +class cItem; +class cNBTData; + + + + + +class cChestEntity : + public cBlockEntity, + public cWindowOwner +{ +public: + cChestEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); + virtual ~cChestEntity(); + virtual void Destroy(); + + void HandleData( cNBTData* a_NBTData ); + + const cItem * GetSlot( int a_Slot ) const; + void SetSlot( int a_Slot, cItem & a_Item ); + + bool LoadFromJson( const Json::Value& a_Value ); + virtual void SaveToJson(Json::Value& a_Value ) override; + + void SendTo( cClientHandle* a_Client, cServer* a_Server ); + + virtual void UsedBy( cPlayer * a_Player ) override; + + cChestEntity *GetJoinedChest() { return m_JoinedChest; } + void SetJoinedChest(cChestEntity *a_Chest) { m_JoinedChest = a_Chest; } + void RemoveJoinedChest(cChestEntity *a_Chest) { if (m_JoinedChest && m_JoinedChest == a_Chest) { m_JoinedChest = NULL; m_TopChest = false; } } + + int GetChestHeight() { return ((m_JoinedChest) ? c_ChestHeight * 2 : c_ChestHeight); } + cItem * GetContents(bool a_OnlyThis = false); + + static const int c_ChestWidth = 9; + static const int c_ChestHeight = 3; + +private: + + cItem * m_Content; + bool m_TopChest; + cChestEntity * m_JoinedChest; +}; + + + + diff --git a/source/cChicken.cpp b/source/cChicken.cpp index 2073393d6..ddc6400e4 100644 --- a/source/cChicken.cpp +++ b/source/cChicken.cpp @@ -1,56 +1,56 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cChicken.h"
-
-
-
-
-
-// TODO Drop egg every 5-10 minutes
-
-
-
-
-
-cChicken::cChicken()
-{
- m_MobType = 93;
- GetMonsterConfig("Chicken");
-}
-
-
-
-
-
-cChicken::~cChicken()
-{
-}
-
-
-
-
-
-bool cChicken::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cChicken" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
-
-
-
-
-
-void cChicken::KilledBy( cEntity* a_Killer )
-{
- cItems Drops;
- AddRandomDropItem(Drops, 0, 2, E_ITEM_FEATHER);
- Drops.push_back(cItem((GetMetaData() == BURNING) ? E_ITEM_COOKED_CHICKEN : E_ITEM_RAW_CHICKEN, 1));
- m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
-
- cMonster::KilledBy( a_Killer );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cChicken.h" + + + + + +// TODO Drop egg every 5-10 minutes + + + + + +cChicken::cChicken() +{ + m_MobType = 93; + GetMonsterConfig("Chicken"); +} + + + + + +cChicken::~cChicken() +{ +} + + + + + +bool cChicken::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cChicken" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cChicken::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_FEATHER); + Drops.push_back(cItem((GetMetaData() == BURNING) ? E_ITEM_COOKED_CHICKEN : E_ITEM_RAW_CHICKEN, 1)); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cChicken.h b/source/cChicken.h index 1ad545828..b04197414 100644 --- a/source/cChicken.h +++ b/source/cChicken.h @@ -1,14 +1,14 @@ -#pragma once
-
-#include "cPassiveMonster.h"
-
-class cChicken : public cPassiveMonster
-{
-public:
- cChicken();
- ~cChicken();
-
- virtual bool IsA( const char* a_EntityType );
-
- virtual void KilledBy( cEntity* a_Killer );
-};
+#pragma once + +#include "cPassiveMonster.h" + +class cChicken : public cPassiveMonster +{ +public: + cChicken(); + ~cChicken(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/cChunk.cpp b/source/cChunk.cpp index 5d5a1d972..98415b572 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -1,1643 +1,1643 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#ifndef _WIN32
- #include <cstdlib>
-#endif
-
-
-#include "cChunk.h"
-#include "cWorld.h"
-#include "cWaterSimulator.h"
-#include "cLavaSimulator.h"
-#include "cClientHandle.h"
-#include "cServer.h"
-#include "zlib.h"
-#include "Defines.h"
-#include "cChestEntity.h"
-#include "cFurnaceEntity.h"
-#include "cSignEntity.h"
-#include "cTorch.h"
-#include "cLadder.h"
-#include "cPickup.h"
-#include "cRedstone.h"
-#include "cItem.h"
-#include "cNoise.h"
-#include "cRoot.h"
-#include "cBlockToPickup.h"
-#include "MersenneTwister.h"
-#include "cPlayer.h"
-
-#include "packets/cPacket_DestroyEntity.h"
-#include "packets/cPacket_PreChunk.h"
-#include "packets/cPacket_BlockChange.h"
-#include "packets/cPacket_MultiBlock.h"
-
-#include <json/json.h>
-
-
-
-
-
-extern bool g_bWaterPhysics;
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// sSetBlock:
-
-sSetBlock::sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) // absolute block position
- : x( a_BlockX )
- , y( a_BlockY )
- , z( a_BlockZ )
- , BlockType( a_BlockType )
- , BlockMeta( a_BlockMeta )
-{
- cChunkDef::AbsoluteToRelative(x, y, z, ChunkX, ChunkZ);
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cChunk:
-
-cChunk::cChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkMap * a_ChunkMap, cWorld * a_World)
- : m_PosX( a_ChunkX )
- , m_PosY( a_ChunkY )
- , m_PosZ( a_ChunkZ )
- , m_BlockTickX( 0 )
- , m_BlockTickY( 0 )
- , m_BlockTickZ( 0 )
- , m_World( a_World )
- , m_ChunkMap(a_ChunkMap)
- , m_IsValid(false)
- , m_IsLightValid(false)
- , m_IsDirty(false)
- , m_IsSaving(false)
- , m_StayCount(0)
-{
- // LOGINFO("### new cChunk (%i, %i) at %p, thread 0x%x ###", a_X, a_Z, this, GetCurrentThreadId());
-}
-
-
-
-
-
-cChunk::~cChunk()
-{
- // LOGINFO("### delete cChunk() (%i, %i) from %p, thread 0x%x ###", m_PosX, m_PosZ, this, GetCurrentThreadId() );
-
- for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
- {
- delete *itr;
- }
- m_BlockEntities.clear();
-
- // Remove and destroy all entities that are not players:
- cEntityList Entities;
- for (cEntityList::const_iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
- {
- if ((*itr)->GetEntityType() != cEntity::eEntityType_Player)
- {
- Entities.push_back(*itr);
- }
- }
- for (cEntityList::iterator itr = Entities.begin(); itr != Entities.end(); ++itr)
- {
- (*itr)->RemoveFromChunk();
- (*itr)->Destroy();
- }
- m_Entities.clear();
-}
-
-
-
-
-
-void cChunk::SetValid(void)
-{
- m_IsValid = true;
-
- m_World->GetChunkMap()->ChunkValidated();
-}
-
-
-
-
-
-void cChunk::MarkRegenerating(void)
-{
- // Tell all clients attached to this chunk that they want this chunk:
- for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
- {
- (*itr)->AddWantedChunk(m_PosX, m_PosZ);
- } // for itr - m_LoadedByClient[]
-}
-
-
-
-
-
-bool cChunk::CanUnload(void)
-{
- return m_LoadedByClient.empty() && !m_IsDirty && (m_StayCount == 0);
-}
-
-
-
-
-
-void cChunk::MarkSaving(void)
-{
- m_IsSaving = true;
-}
-
-
-
-
-
-void cChunk::MarkSaved(void)
-{
- if (!m_IsSaving)
- {
- return;
- }
- m_IsDirty = false;
-}
-
-
-
-
-
-void cChunk::MarkLoaded(void)
-{
- m_IsDirty = false;
- SetValid();
-}
-
-
-
-
-
-void cChunk::MarkLoadFailed(void)
-{
- if (m_IsValid)
- {
- return;
- }
-
- m_HasLoadFailed = true;
-}
-
-
-
-
-
-void cChunk::GetAllData(cChunkDataCallback & a_Callback)
-{
- a_Callback.HeightMap (&m_HeightMap);
- a_Callback.BiomeData (&m_BiomeMap);
- a_Callback.BlockTypes (m_BlockTypes);
- a_Callback.BlockMeta (m_BlockMeta);
- a_Callback.LightIsValid (m_IsLightValid);
- a_Callback.BlockLight (m_BlockLight);
- a_Callback.BlockSkyLight(m_BlockSkyLight);
-
- for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
- {
- a_Callback.Entity(*itr);
- }
-
- for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
- {
- a_Callback.BlockEntity(*itr);
- }
-}
-
-
-
-
-
-void cChunk::SetAllData(
- const BLOCKTYPE * a_BlockTypes,
- const NIBBLETYPE * a_BlockMeta,
- const NIBBLETYPE * a_BlockLight,
- const NIBBLETYPE * a_BlockSkyLight,
- const HeightMap * a_HeightMap,
- const BiomeMap & a_BiomeMap,
- cEntityList & a_Entities,
- cBlockEntityList & a_BlockEntities
-)
-{
- memcpy(m_BiomeMap, a_BiomeMap, sizeof(m_BiomeMap));
-
- if (a_HeightMap != NULL)
- {
- memcpy(m_HeightMap, a_HeightMap, sizeof(m_HeightMap));
- }
-
- memcpy(m_BlockTypes, a_BlockTypes, sizeof(m_BlockTypes));
- memcpy(m_BlockMeta, a_BlockMeta, sizeof(m_BlockMeta));
- if (a_BlockLight != NULL)
- {
- memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight));
- }
- if (a_BlockSkyLight != NULL)
- {
- memcpy(m_BlockSkyLight, a_BlockSkyLight, sizeof(m_BlockSkyLight));
- }
-
- m_IsLightValid = (a_BlockLight != NULL) && (a_BlockSkyLight != NULL);
-
- if (a_HeightMap == NULL)
- {
- CalculateHeightmap();
- }
-
- // Append entities to current entity list:
- m_Entities.splice(m_Entities.end(), a_Entities);
-
- // Clear the block entities present - either the loader / saver has better, or we'll create empty ones:
- for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
- {
- delete *itr;
- }
- std::swap(a_BlockEntities, m_BlockEntities);
-
- // Create block entities that the loader didn't load; fill them with defaults
- CreateBlockEntities();
-
- m_HasLoadFailed = false;
-}
-
-
-
-
-
-void cChunk::SetLight(
- const cChunkDef::BlockNibbles & a_BlockLight,
- const cChunkDef::BlockNibbles & a_SkyLight
-)
-{
- // TODO: We might get cases of wrong lighting when a chunk changes in the middle of a lighting calculation.
- // Postponing until we see how bad it is :)
- memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight));
- memcpy(m_BlockSkyLight, a_SkyLight, sizeof(m_BlockSkyLight));
- m_IsLightValid = true;
-}
-
-
-
-
-
-void cChunk::GetBlockTypes(BLOCKTYPE * a_BlockTypes)
-{
- memcpy(a_BlockTypes, m_BlockTypes, NumBlocks);
-}
-
-
-
-
-
-void cChunk::GetBlockData(BLOCKTYPE * a_BlockData)
-{
- memcpy(a_BlockData, m_BlockTypes, NumBlocks);
- memcpy(a_BlockData + MetaOffset, m_BlockMeta, NumBlocks / 2);
- memcpy(a_BlockData + LightOffset, m_BlockLight, NumBlocks / 2);
- memcpy(a_BlockData + SkyLightOffset, m_BlockSkyLight, NumBlocks / 2);
-}
-
-
-
-
-
-/// Returns true if there is a block entity at the coords specified
-bool cChunk::HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ)
-{
- for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
- {
- if (
- ((*itr)->GetPosX() == a_BlockX) &&
- ((*itr)->GetPosY() == a_BlockY) &&
- ((*itr)->GetPosZ() == a_BlockZ)
- )
- {
- return true;
- }
- } // for itr - m_BlockEntities[]
- return false;
-}
-
-
-
-
-
-/// Sets or resets the internal flag that prevents chunk from being unloaded
-void cChunk::Stay(bool a_Stay)
-{
- m_StayCount += (a_Stay ? 1 : -1);
- ASSERT(m_StayCount >= 0);
-}
-
-
-
-
-
-void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
-{
- cCSLock Lock(m_CSBlockLists);
- unsigned int PendingSendBlocks = m_PendingSendBlocks.size();
- if( PendingSendBlocks > 1 )
- {
- cPacket_MultiBlock MultiBlock;
- MultiBlock.m_ChunkX = m_PosX;
- MultiBlock.m_ChunkZ = m_PosZ;
- MultiBlock.m_NumBlocks = (short)PendingSendBlocks;
- MultiBlock.m_Data = new cPacket_MultiBlock::sBlockChange[ PendingSendBlocks ];
- MultiBlock.m_DataSize = PendingSendBlocks * sizeof( cPacket_MultiBlock::sBlockChange );
- //LOG("Sending multiblock packet for %i blocks", PendingSendBlocks );
- for( unsigned int i = 0; i < PendingSendBlocks; i++)
- {
- unsigned int index = m_PendingSendBlocks[i];
- Vector3i BlockPos = IndexToCoordinate( index );
-
- unsigned int Coords = BlockPos.y | (BlockPos.z << 8) | (BlockPos.x << 12);
- unsigned int Blocks = GetNibble( m_BlockMeta, index ) | (m_BlockTypes[index] << 4);
- MultiBlock.m_Data[i].Data = Coords << 16 | Blocks;
- }
- m_PendingSendBlocks.clear();
- PendingSendBlocks = m_PendingSendBlocks.size();
- Broadcast( MultiBlock );
- }
- if( PendingSendBlocks > 0 )
- {
- for( unsigned int i = 0; i < PendingSendBlocks; i++)
- {
- unsigned int index = m_PendingSendBlocks[i];
- Vector3i WorldPos = PositionToWorldPosition( IndexToCoordinate( index ) );
-
- cPacket_BlockChange BlockChange;
- BlockChange.m_PosX = WorldPos.x;
- BlockChange.m_PosY = (unsigned char)WorldPos.y;
- BlockChange.m_PosZ = WorldPos.z;
- BlockChange.m_BlockType = m_BlockTypes[index];
- BlockChange.m_BlockMeta = GetNibble( m_BlockMeta, index );
- Broadcast( BlockChange );
- }
- m_PendingSendBlocks.clear();
- }
- Lock.Unlock();
-
- while ( !m_UnloadQuery.empty() )
- {
- cPacket_PreChunk UnloadPacket;
- UnloadPacket.m_PosX = GetPosX();
- UnloadPacket.m_PosZ = GetPosZ();
- UnloadPacket.m_bLoad = false; // Unload
- (*m_UnloadQuery.begin())->Send( UnloadPacket );
- m_UnloadQuery.remove( *m_UnloadQuery.begin() );
- }
-
- CheckBlocks();
-
- TickBlocks(a_TickRandom);
-
- // Tick block entities (furnaces)
- for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
- {
- if ((*itr)->GetBlockType() == E_BLOCK_FURNACE)
- {
- m_IsDirty = ((cFurnaceEntity *)(*itr))->Tick( a_Dt ) | m_IsDirty;
- }
- }
-}
-
-
-
-
-
-void cChunk::CheckBlocks(void)
-{
- cCSLock Lock2(m_CSBlockLists);
- unsigned int NumTickBlocks = m_ToTickBlocks.size();
- Lock2.Unlock();
-
- if (NumTickBlocks == 0)
- {
- return;
- }
-
- Lock2.Lock();
- std::deque< unsigned int > ToTickBlocks = m_ToTickBlocks;
- m_ToTickBlocks.clear();
- Lock2.Unlock();
-
- for (std::deque< unsigned int >::const_iterator itr = ToTickBlocks.begin(); itr != ToTickBlocks.end(); ++itr)
- {
- unsigned int index = (*itr);
- Vector3i BlockPos = IndexToCoordinate(index);
-
- BLOCKTYPE BlockType = GetBlock(index);
- NIBBLETYPE BlockMeta = GetMeta (index);
- switch (BlockType)
- {
- // Stuff that drops when block below is destroyed:
- case E_BLOCK_REDSTONE_REPEATER_OFF:
- case E_BLOCK_REDSTONE_REPEATER_ON:
- case E_BLOCK_REDSTONE_WIRE:
- case E_BLOCK_CACTUS:
- case E_BLOCK_REEDS:
- case E_BLOCK_WOODEN_PRESSURE_PLATE:
- case E_BLOCK_STONE_PRESSURE_PLATE:
- case E_BLOCK_MINECART_TRACKS:
- case E_BLOCK_SIGN_POST:
- case E_BLOCK_CROPS:
- case E_BLOCK_SAPLING:
- case E_BLOCK_YELLOW_FLOWER:
- case E_BLOCK_RED_ROSE:
- case E_BLOCK_RED_MUSHROOM:
- case E_BLOCK_BROWN_MUSHROOM:
- case E_BLOCK_SNOW:
- {
- if (GetBlock(BlockPos.x, BlockPos.y - 1, BlockPos.z) == E_BLOCK_AIR)
- {
- SetBlock( BlockPos, E_BLOCK_AIR, 0 );
-
- Vector3i WorldPos = PositionToWorldPosition( BlockPos );
-
- m_World->GetSimulatorManager()->WakeUp(WorldPos.x, WorldPos.y, WorldPos.z);
-
- cItems Pickups;
- cBlockToPickup::ToPickup(BlockType, BlockMeta, E_ITEM_EMPTY, Pickups);
- m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z);
- }
- break;
- }
-
- case E_BLOCK_REDSTONE_TORCH_OFF:
- case E_BLOCK_REDSTONE_TORCH_ON:
- case E_BLOCK_TORCH:
- {
- char Dir = cTorch::MetaDataToDirection( GetNibble( m_BlockMeta, BlockPos ) );
- Vector3i WorldPos = PositionToWorldPosition( BlockPos );
-
- Vector3i AttachedTo = WorldPos;
- AddDirection( AttachedTo.x, AttachedTo.y, AttachedTo.z, Dir, true );
- if( m_World->GetBlock( AttachedTo ) == E_BLOCK_AIR )
- {
- SetBlock( BlockPos, E_BLOCK_AIR, 0 );
-
- m_World->GetSimulatorManager()->WakeUp(WorldPos.x, WorldPos.y, WorldPos.z);
-
- cItems Pickups;
- cBlockToPickup::ToPickup(BlockType, BlockMeta, E_ITEM_EMPTY, Pickups);
- m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z);
- }
- break;
- }
-
- case E_BLOCK_LADDER:
- {
- char Dir = cLadder::MetaDataToDirection( GetNibble( m_BlockMeta, BlockPos ) );
- Vector3i WorldPos = PositionToWorldPosition( BlockPos );
- Vector3i AttachedTo = WorldPos;
- AddDirection( AttachedTo.x, AttachedTo.y, AttachedTo.z, Dir, true );
- if( m_World->GetBlock( AttachedTo ) == E_BLOCK_AIR )
- {
- SetBlock( BlockPos, E_BLOCK_AIR, 0 );
- cItems Pickups;
- cBlockToPickup::ToPickup(BlockType, BlockMeta, E_ITEM_EMPTY, Pickups);
- m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z);
- }
- break;
- }
- } // switch (BlockType)
- } // for itr - ToTickBlocks[]
-}
-
-
-
-
-
-void cChunk::TickBlocks(MTRand & a_TickRandom)
-{
- // Tick dem blocks
- // _X: We must limit the random number or else we get a nasty int overflow bug ( http://forum.mc-server.org/showthread.php?tid=457 )
- int RandomX = a_TickRandom.randInt(0x00ffffff);
- int RandomY = a_TickRandom.randInt(0x00ffffff);
- int RandomZ = a_TickRandom.randInt(0x00ffffff);
- int TickX = m_BlockTickX;
- int TickY = m_BlockTickY;
- int TickZ = m_BlockTickZ;
-
- // This for loop looks disgusting, but it actually does a simple thing - first processes m_BlockTick, then adds random to it
- // This is so that SetNextBlockTick() works
- for (int i = 0; i < 50; i++,
-
- // This weird construct (*2, then /2) is needed,
- // otherwise the blocktick distribution is too biased towards even coords!
-
- TickX = (TickX + RandomX) % (Width * 2),
- TickY = (TickY + RandomY) % (Height * 2),
- TickZ = (TickZ + RandomZ) % (Width * 2),
- m_BlockTickX = TickX / 2,
- m_BlockTickY = TickY / 2,
- m_BlockTickZ = TickZ / 2
- )
- {
-
- if (m_BlockTickY > cChunkDef::GetHeight(m_HeightMap, m_BlockTickX, m_BlockTickZ))
- {
- continue; // It's all air up here
- }
-
- unsigned int Index = MakeIndexNoCheck( m_BlockTickX, m_BlockTickY, m_BlockTickZ );
- BLOCKTYPE ID = m_BlockTypes[Index];
- switch( ID )
- {
- case E_BLOCK_CROPS:
- {
- NIBBLETYPE Meta = GetMeta(Index);
- if (Meta < 7)
- {
- FastSetBlock(m_BlockTickX, m_BlockTickY, m_BlockTickZ, E_BLOCK_CROPS, ++Meta);
- }
- break;
- }
-
- case E_BLOCK_GRASS: TickGrass (m_BlockTickX, m_BlockTickY, m_BlockTickZ, a_TickRandom); break;
- case E_BLOCK_PUMPKIN_STEM:
- case E_BLOCK_MELON_STEM: TickMelonPumpkin(m_BlockTickX, m_BlockTickY, m_BlockTickZ, Index, ID, a_TickRandom); break;
- case E_BLOCK_FARMLAND: TickFarmland (m_BlockTickX, m_BlockTickY, m_BlockTickZ); break;
- case E_BLOCK_SUGARCANE: GrowSugarcane (m_BlockTickX, m_BlockTickY, m_BlockTickZ, 1); break;
- case E_BLOCK_CACTUS: GrowCactus (m_BlockTickX, m_BlockTickY, m_BlockTickZ, 1); break;
-
- case E_BLOCK_SAPLING:
- {
- // Check the highest bit, if set, grow the tree, if not, set it (1-bit delay):
- NIBBLETYPE Meta = GetMeta(m_BlockTickX, m_BlockTickY, m_BlockTickZ);
- if ((Meta & 0x08) != 0)
- {
- m_World->GrowTree( m_BlockTickX + m_PosX*Width, m_BlockTickY, m_BlockTickZ + m_PosZ*Width );
- }
- else
- {
- SetMeta(m_BlockTickX, m_BlockTickY, m_BlockTickZ, Meta | 0x08);
- }
- break;
- }
-
- case E_BLOCK_LEAVES: //todo, http://www.minecraftwiki.net/wiki/Data_values#Leaves
- {
- break;
- }
-
- default:
- {
- break;
- }
- }
- }
-}
-
-
-
-
-
-void cChunk::TickGrass(int a_RelX, int a_RelY, int a_RelZ, MTRand & a_TickRandom)
-{
- // Grass turns into dirt if there's another block on top of it:
- {
- BLOCKTYPE AboveBlock = cChunkDef::GetBlock(m_BlockTypes, a_RelX, a_RelY + 1, a_RelZ);
- if (!((g_BlockOneHitDig[AboveBlock]) || (g_BlockTransparent[AboveBlock])))
- {
- FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0);
- return;
- }
- }
-
- // Grass spreads to nearby blocks if there's enough light (TODO) and free space above that block
- // Ref.: http://www.minecraftwiki.net/wiki/Grass_Block#Growth
- for (int i = 0; i < 2; i++) // Pick two blocks to grow to
- {
- int OfsX = a_TickRandom.randInt(2) - 1; // [-1 .. 1]
- int OfsY = a_TickRandom.randInt(4) - 3; // [-3 .. 1]
- int OfsZ = a_TickRandom.randInt(2) - 1; // [-1 .. 1]
-
- BLOCKTYPE DestBlock;
- NIBBLETYPE DestMeta;
- if (
- !UnboundedRelGetBlock(a_RelX + OfsX, a_RelY + OfsY, a_RelZ + OfsZ, DestBlock, DestMeta) ||
- (DestBlock != E_BLOCK_DIRT)
- )
- {
- continue;
- }
-
- BLOCKTYPE AboveDest;
- NIBBLETYPE AboveMeta;
- if (
- UnboundedRelGetBlock(a_RelX + OfsX, a_RelY + OfsY + 1, a_RelZ + OfsZ, AboveDest, AboveMeta) &&
- ((g_BlockOneHitDig[AboveDest]) || (g_BlockTransparent[AboveDest]))
- // TODO: Query dest light, if it's enough
- )
- {
- UnboundedRelFastSetBlock(a_RelX + OfsX, a_RelY + OfsY, a_RelZ + OfsZ, E_BLOCK_GRASS, 0);
- }
- } // for i - repeat twice
-}
-
-
-
-
-
-void cChunk::TickMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, int a_BlockIdx, BLOCKTYPE a_BlockType, MTRand & a_TickRandom)
-{
- NIBBLETYPE Meta = GetMeta(a_BlockIdx);
- if (Meta < 7)
- {
- FastSetBlock(m_BlockTickX, m_BlockTickY, m_BlockTickZ, a_BlockType, ++Meta);
- return;
- }
- GrowMelonPumpkin(a_RelX, a_RelY, a_RelZ, a_BlockType, a_TickRandom);
-}
-
-
-
-
-
-void cChunk::TickFarmland(int a_RelX, int a_RelY, int a_RelZ)
-{
- // TODO: Rain hydrates blocks, too. Check world weather, don't search for water if raining.
-
- // Search for water in a close proximity:
- // Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles
- bool Found = false;
- for (int y = a_RelY; y <= a_RelY + 1; y++)
- {
- for (int z = a_RelZ - 4; z <= a_RelZ + 4; z++)
- {
- for (int x = a_RelX - 4; x <= a_RelX + 4; x++)
- {
- BLOCKTYPE BlockType;
- NIBBLETYPE Meta; // unused
-
- if (!UnboundedRelGetBlock(x, y, z, BlockType, Meta))
- {
- // Too close to an unloaded chunk, we might miss a water block there, so don't tick at all
- return;
- }
- if (
- (BlockType == E_BLOCK_WATER) ||
- (BlockType == E_BLOCK_STATIONARY_WATER)
- )
- {
- Found = true;
- break;
- }
- } // for x
- if (Found)
- {
- break;
- }
- } // for z
- if (Found)
- {
- break;
- }
- } // for y
-
- NIBBLETYPE BlockMeta = GetMeta(a_RelX, a_RelY, a_RelZ);
-
- if (Found)
- {
- // Water was found, hydrate the block until hydration reaches 7:
- if (BlockMeta < 7)
- {
- FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, ++BlockMeta);
- }
- return;
- }
-
- // Water wasn't found, de-hydrate block:
- if (BlockMeta > 0)
- {
- FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, --BlockMeta);
- return;
- }
-
- // Farmland too dry. Turn back to dirt:
- FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0);
-
- // TODO: Uproot whatever was growing on top:
-}
-
-
-
-
-
-void cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_TickRandom)
-{
- // Convert the stem BlockType into produce BlockType
- BLOCKTYPE ProduceType;
- switch (a_BlockType)
- {
- case E_BLOCK_MELON_STEM: ProduceType = E_BLOCK_MELON; break;
- case E_BLOCK_PUMPKIN_STEM: ProduceType = E_BLOCK_PUMPKIN; break;
- default:
- {
- ASSERT(!"Unhandled blocktype in TickMelonPumpkin()");
- return;
- }
- }
-
- // Check if there's another melon / pumpkin around that stem, if so, abort:
- bool IsValid;
- BLOCKTYPE BlockType[4];
- NIBBLETYPE BlockMeta; // unused
- IsValid = UnboundedRelGetBlock(a_RelX + 1, a_RelY, a_RelZ, BlockType[0], BlockMeta);
- IsValid = IsValid && UnboundedRelGetBlock(a_RelX - 1, a_RelY, a_RelZ, BlockType[1], BlockMeta);
- IsValid = IsValid && UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ + 1, BlockType[2], BlockMeta);
- IsValid = IsValid && UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ - 1, BlockType[3], BlockMeta);
- if (
- !IsValid ||
- (BlockType[0] == ProduceType) ||
- (BlockType[1] == ProduceType) ||
- (BlockType[2] == ProduceType) ||
- (BlockType[3] == ProduceType)
- )
- {
- // Neighbors not valid or already taken by the same produce
- return;
- }
-
- // Pick a direction in which to place the produce:
- int x = 0, z = 0;
- int CheckType = a_TickRandom.randInt(3); // The index to the neighbors array which should be checked for emptiness
- switch (CheckType)
- {
- case 0: x = 1; break;
- case 1: x = -1; break;
- case 2: z = 1; break;
- case 3: z = -1; break;
- }
-
- // Check that the block in that direction is empty:
- switch (BlockType[CheckType])
- {
- case E_BLOCK_AIR:
- case E_BLOCK_SNOW:
- case E_BLOCK_TALL_GRASS:
- case E_BLOCK_DEAD_BUSH:
- {
- break;
- }
- default: return;
- }
-
- // Check if there's soil under the neighbor. We already know the neighbors are valid. Place produce if ok
- BLOCKTYPE Soil;
- UnboundedRelGetBlock(a_RelX + x, a_RelY - 1, a_RelZ + z, Soil, BlockMeta);
- switch (Soil)
- {
- case E_BLOCK_DIRT:
- case E_BLOCK_GRASS:
- case E_BLOCK_FARMLAND:
- {
- // Place a randomly-facing produce:
- UnboundedRelFastSetBlock(a_RelX + x, a_RelY, a_RelZ + z, ProduceType, (NIBBLETYPE)(a_TickRandom.randInt(4) % 4));
- break;
- }
- }
-}
-
-
-
-
-
-void cChunk::GrowSugarcane(int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks)
-{
- // Check the total height of the sugarcane blocks here:
- int Top = a_RelY + 1;
- while (
- (Top < cChunkDef::Height) &&
- (GetBlock(a_RelX, Top, a_RelZ) == E_BLOCK_SUGARCANE)
- )
- {
- ++Top;
- }
- int Bottom = a_RelY - 1;
- while (
- (Bottom > 0) &&
- (GetBlock(a_RelX, Bottom, a_RelZ) == E_BLOCK_SUGARCANE)
- )
- {
- --Bottom;
- }
-
- // Grow by at most a_NumBlocks, but no more than max height:
- int ToGrow = std::min(a_NumBlocks, m_World->GetMaxSugarcaneHeight() + 1 - (Top - Bottom));
- for (int i = 0; i < ToGrow; i++)
- {
- BLOCKTYPE BlockType;
- NIBBLETYPE BlockMeta;
- if (UnboundedRelGetBlock(a_RelX, Top + i, a_RelZ, BlockType, BlockMeta) && (BlockType == E_BLOCK_AIR))
- {
- UnboundedRelFastSetBlock(a_RelX, Top + i, a_RelZ, E_BLOCK_SUGARCANE, 0);
- }
- else
- {
- break;
- }
- } // for i
-}
-
-
-
-
-
-void cChunk::GrowCactus(int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks)
-{
- // Check the total height of the sugarcane blocks here:
- int Top = a_RelY + 1;
- while (
- (Top < cChunkDef::Height) &&
- (GetBlock(a_RelX, Top, a_RelZ) == E_BLOCK_CACTUS)
- )
- {
- ++Top;
- }
- int Bottom = a_RelY - 1;
- while (
- (Bottom > 0) &&
- (GetBlock(a_RelX, Bottom, a_RelZ) == E_BLOCK_CACTUS)
- )
- {
- --Bottom;
- }
-
- // Grow by at most a_NumBlocks, but no more than max height:
- int ToGrow = std::min(a_NumBlocks, m_World->GetMaxCactusHeight() + 1 - (Top - Bottom));
- for (int i = 0; i < ToGrow; i++)
- {
- BLOCKTYPE BlockType;
- NIBBLETYPE BlockMeta;
- if (UnboundedRelGetBlock(a_RelX, Top + i, a_RelZ, BlockType, BlockMeta) && (BlockType == E_BLOCK_AIR))
- {
- // TODO: Check the surrounding blocks, if they aren't air, break the cactus block into pickups (and continue breaking blocks above in the next loop iterations)
- UnboundedRelFastSetBlock(a_RelX, Top + i, a_RelZ, E_BLOCK_CACTUS, 0);
- }
- else
- {
- break;
- }
- } // for i
-}
-
-
-
-
-
-bool cChunk::UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta)
-{
- if ((a_RelY < 0) || (a_RelY > cChunkDef::Height))
- {
- return false;
- }
-
- if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width))
- {
- int BlockIdx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ);
- a_BlockType = GetBlock(BlockIdx);
- a_BlockMeta = GetMeta(BlockIdx);
- return true;
- }
- return m_ChunkMap->LockedGetBlock(
- m_PosX * cChunkDef::Width + a_RelX,
- ZERO_CHUNK_Y * cChunkDef::Height + a_RelY,
- m_PosZ * cChunkDef::Width + a_RelZ,
- a_BlockType, a_BlockMeta
- );
-}
-
-
-
-
-
-bool cChunk::UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
-{
- if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width))
- {
- SetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta);
- return true;
- }
- return m_ChunkMap->LockedSetBlock(
- m_PosX * cChunkDef::Width + a_RelX,
- ZERO_CHUNK_Y * cChunkDef::Height + a_RelY,
- m_PosZ * cChunkDef::Width + a_RelZ,
- a_BlockType, a_BlockMeta
- );
-}
-
-
-
-
-
-bool cChunk::UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
-{
- if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width))
- {
- FastSetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta);
- return true;
- }
- return m_ChunkMap->LockedFastSetBlock(
- m_PosX * cChunkDef::Width + a_RelX,
- ZERO_CHUNK_Y * cChunkDef::Height + a_RelY,
- m_PosZ * cChunkDef::Width + a_RelZ,
- a_BlockType, a_BlockMeta
- );
-}
-
-
-
-
-
-int cChunk::GetHeight( int a_X, int a_Z )
-{
- ASSERT((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width));
-
- if ((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width))
- {
- return m_HeightMap[a_X + a_Z * Width];
- }
- return 0;
-}
-
-
-
-
-
-void cChunk::CreateBlockEntities(void)
-{
- for (int x = 0; x < Width; x++)
- {
- for (int z = 0; z < Width; z++)
- {
- for (int y = 0; y < Height; y++)
- {
- ENUM_BLOCK_ID BlockType = (ENUM_BLOCK_ID)m_BlockTypes[ MakeIndex( x, y, z ) ];
- switch ( BlockType )
- {
- case E_BLOCK_CHEST:
- {
- if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
- {
- m_BlockEntities.push_back( new cChestEntity( x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) );
- }
- break;
- }
-
- case E_BLOCK_FURNACE:
- {
- if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
- {
- m_BlockEntities.push_back( new cFurnaceEntity( x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) );
- }
- break;
- }
-
- case E_BLOCK_SIGN_POST:
- case E_BLOCK_WALLSIGN:
- {
- if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
- {
- m_BlockEntities.push_back( new cSignEntity( BlockType, x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) );
- }
- break;
- }
- } // switch (BlockType)
- } // for y
- } // for z
- } // for x
-}
-
-
-
-
-
-void cChunk::CalculateHeightmap()
-{
- for (int x = 0; x < Width; x++)
- {
- for (int z = 0; z < Width; z++)
- {
- for (int y = Height - 1; y > -1; y--)
- {
- int index = MakeIndex( x, y, z );
- if (m_BlockTypes[index] != E_BLOCK_AIR)
- {
- m_HeightMap[x + z * Width] = (unsigned char)y;
- break;
- }
- } // for y
- } // for z
- } // for x
-}
-
-
-
-
-
-void cChunk::SetBlock( int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta )
-{
- if (a_RelX < 0 || a_RelX >= Width || a_RelY < 0 || a_RelY >= Height || a_RelZ < 0 || a_RelZ >= Width)
- {
- return; // Clip
- }
-
- ASSERT(IsValid()); // Is this chunk loaded / generated?
-
- int index = MakeIndexNoCheck( a_RelX, a_RelY, a_RelZ );
- BLOCKTYPE OldBlockMeta = GetNibble( m_BlockMeta, index );
- BLOCKTYPE OldBlockType = m_BlockTypes[index];
- m_BlockTypes[index] = a_BlockType;
-
- SetNibble( m_BlockMeta, index, a_BlockMeta );
-
- if ((OldBlockType == a_BlockType) && (OldBlockMeta == a_BlockMeta))
- {
- return;
- }
-
- MarkDirty();
-
- {
- cCSLock Lock(m_CSBlockLists);
- m_PendingSendBlocks.push_back( index );
- }
-
- // ONLY recalculate lighting if it's necessary!
- if(
- (g_BlockLightValue[ OldBlockType ] != g_BlockLightValue[ a_BlockType ]) ||
- (g_BlockSpreadLightFalloff[ OldBlockType ] != g_BlockSpreadLightFalloff[ a_BlockType ]) ||
- (g_BlockTransparent[ OldBlockType ] != g_BlockTransparent[ a_BlockType ] )
- )
- {
- m_IsLightValid = false;
- }
-
- // Update heightmap, if needed:
- if (a_RelY >= m_HeightMap[a_RelX + a_RelZ * Width])
- {
- if (a_BlockType != E_BLOCK_AIR)
- {
- SetHeight(m_HeightMap, a_RelX, a_RelZ, a_RelY);
- }
- else
- {
- for (int y = a_RelY - 1; y > 0; --y)
- {
- if (cChunkDef::GetBlock(m_BlockTypes, a_RelX, y, a_RelZ) != E_BLOCK_AIR)
- {
- SetHeight(m_HeightMap, a_RelX, a_RelZ, y);
- break;
- }
- } // for y - column in m_BlockData
- }
- }
-
- m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY, a_RelZ ) );
- m_ToTickBlocks.push_back( MakeIndex( a_RelX + 1, a_RelY, a_RelZ ) );
- m_ToTickBlocks.push_back( MakeIndex( a_RelX - 1, a_RelY, a_RelZ ) );
- m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY + 1, a_RelZ ) );
- m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY - 1, a_RelZ ) );
- m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY, a_RelZ + 1 ) );
- m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY, a_RelZ - 1 ) );
-
- Vector3i WorldPos = PositionToWorldPosition( a_RelX, a_RelY, a_RelZ );
- cBlockEntity* BlockEntity = GetBlockEntity( WorldPos );
- if( BlockEntity )
- {
- BlockEntity->Destroy();
- RemoveBlockEntity( BlockEntity );
- delete BlockEntity;
- }
- switch( a_BlockType )
- {
- case E_BLOCK_CHEST:
- {
- AddBlockEntity( new cChestEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World) );
- break;
- }
- case E_BLOCK_FURNACE:
- {
- AddBlockEntity( new cFurnaceEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World) );
- break;
- }
- case E_BLOCK_SIGN_POST:
- case E_BLOCK_WALLSIGN:
- {
- AddBlockEntity( new cSignEntity( (ENUM_BLOCK_ID)a_BlockType, WorldPos.x, WorldPos.y, WorldPos.z, m_World) );
- break;
- }
- } // switch (a_BlockType)
-}
-
-
-
-
-
-void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta)
-{
- ASSERT(!((a_X < 0 || a_X >= Width || a_Y < 0 || a_Y >= Height || a_Z < 0 || a_Z >= Width)));
-
- ASSERT(IsValid());
-
- const int index = MakeIndexNoCheck( a_X, a_Y, a_Z );
- const BLOCKTYPE OldBlock = m_BlockTypes[index];
- const BLOCKTYPE OldBlockMeta = GetNibble( m_BlockMeta, index );
- if ((OldBlock == a_BlockType) && (OldBlockMeta == a_BlockMeta))
- {
- return;
- }
-
- MarkDirty();
-
- m_BlockTypes[index] = a_BlockType;
-
- {
- cCSLock Lock(m_CSBlockLists);
- m_PendingSendBlocks.push_back( index );
- }
-
- SetNibble( m_BlockMeta, index, a_BlockMeta );
-
- // ONLY recalculate lighting if it's necessary!
- if(
- (g_BlockLightValue[ OldBlock ] != g_BlockLightValue[ a_BlockType ]) ||
- (g_BlockSpreadLightFalloff[ OldBlock ] != g_BlockSpreadLightFalloff[ a_BlockType ]) ||
- (g_BlockTransparent[ OldBlock ] != g_BlockTransparent[ a_BlockType ] )
- )
- {
- m_IsLightValid = false;
- }
-
- // Update heightmap, if needed:
- if (a_Y >= m_HeightMap[a_X + a_Z * Width])
- {
- if (a_BlockType != E_BLOCK_AIR)
- {
- m_HeightMap[a_X + a_Z * Width] = (unsigned char)a_Y;
- }
- else
- {
- for (int y = a_Y - 1; y > 0; --y)
- {
- if (m_BlockTypes[MakeIndexNoCheck(a_X, y, a_Z)] != E_BLOCK_AIR)
- {
- m_HeightMap[a_X + a_Z * Width] = (unsigned char)y;
- break;
- }
- } // for y - column in m_BlockData
- }
- }
-}
-
-
-
-
-
-void cChunk::SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client )
-{
- if( a_Client == 0 )
- {
- cCSLock Lock(m_CSBlockLists);
- unsigned int index = MakeIndex( a_X, a_Y, a_Z );
- if( index != INDEX_OUT_OF_RANGE )
- {
- m_PendingSendBlocks.push_back( index );
- }
- else
- {
- LOGWARN("cChunk::SendBlockTo Index out of range!");
- }
- return;
- }
-
- for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr )
- {
- if ( *itr == a_Client )
- {
- unsigned int index = MakeIndex( a_X, a_Y, a_Z );
- Vector3i WorldPos = PositionToWorldPosition( a_X, a_Y, a_Z );
- cPacket_BlockChange BlockChange;
- BlockChange.m_PosX = WorldPos.x;
- BlockChange.m_PosY = (unsigned char)WorldPos.y;
- BlockChange.m_PosZ = WorldPos.z;
- if( index != INDEX_OUT_OF_RANGE )
- {
- BlockChange.m_BlockType = m_BlockTypes[ index ];
- BlockChange.m_BlockMeta = GetNibble( m_BlockMeta, index );
- } // else it's both 0
- a_Client->Send( BlockChange );
- break;
- }
- }
-}
-
-
-
-
-
-void cChunk::AddBlockEntity( cBlockEntity* a_BlockEntity )
-{
- cCSLock Lock(m_CSBlockLists);
- m_BlockEntities.push_back( a_BlockEntity );
-}
-
-
-
-
-
-cBlockEntity * cChunk::GetBlockEntity(int a_X, int a_Y, int a_Z)
-{
- // Assumes that the m_CSBlockList is already locked, we're being called from SetBlock()
- for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
- {
- if (
- ((*itr)->GetPosX() == a_X) &&
- ((*itr)->GetPosY() == a_Y) &&
- ((*itr)->GetPosZ() == a_Z)
- )
- {
- return *itr;
- }
- } // for itr - m_BlockEntities[]
-
- return NULL;
-}
-
-
-
-
-
-void cChunk::UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z)
-{
- cBlockEntity * be = GetBlockEntity(a_X, a_Y, a_Z);
- if (be != NULL)
- {
- be->UsedBy(a_Player);
- }
-}
-
-
-
-
-
-void cChunk::CollectPickupsByPlayer(cPlayer * a_Player)
-{
- double PosX = a_Player->GetPosX();
- double PosY = a_Player->GetPosY();
- double PosZ = a_Player->GetPosZ();
-
- for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
- {
- if ( (*itr)->GetEntityType() != cEntity::eEntityType_Pickup )
- {
- continue; // Only pickups
- }
- float DiffX = (float)((*itr)->GetPosX() - PosX );
- float DiffY = (float)((*itr)->GetPosY() - PosY );
- float DiffZ = (float)((*itr)->GetPosZ() - PosZ );
- float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ;
- if (SqrDist < 1.5f * 1.5f) // 1.5 block
- {
- MarkDirty();
- (reinterpret_cast<cPickup *>(*itr))->CollectedBy( a_Player );
- }
- }
-}
-
-
-
-
-
-void cChunk::UpdateSign(int a_PosX, int a_PosY, int a_PosZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4)
-{
- // Also sends update packets to all clients in the chunk
- for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
- {
- if (
- ((*itr)->GetPosX() == a_PosX) &&
- ((*itr)->GetPosY() == a_PosY) &&
- ((*itr)->GetPosZ() == a_PosZ) &&
- (
- ((*itr)->GetBlockType() == E_BLOCK_WALLSIGN) ||
- ((*itr)->GetBlockType() == E_BLOCK_SIGN_POST)
- )
- )
- {
- MarkDirty();
- (reinterpret_cast<cSignEntity *>(*itr))->SetLines(a_Line1, a_Line2, a_Line3, a_Line4);
- (*itr)->SendTo(NULL);
- }
- } // for itr - m_BlockEntities[]
-}
-
-
-
-
-
-void cChunk::RemoveBlockEntity( cBlockEntity* a_BlockEntity )
-{
- cCSLock Lock(m_CSBlockLists);
- MarkDirty();
- m_BlockEntities.remove( a_BlockEntity );
-}
-
-
-
-
-
-bool cChunk::AddClient(cClientHandle* a_Client)
-{
- for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
- {
- if (a_Client == *itr)
- {
- // Already there, nothing needed
- return false;
- }
- }
- m_LoadedByClient.push_back( a_Client );
-
- for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr )
- {
- LOGD("cChunk: Entity #%d (%s) at [%i, %i, %i] spawning for player \"%s\"", (*itr)->GetUniqueID(), (*itr)->GetClass(), m_PosX, m_PosY, m_PosZ, a_Client->GetUsername().c_str() );
- (*itr)->SpawnOn( a_Client );
- }
- return true;
-}
-
-
-
-
-
-void cChunk::RemoveClient( cClientHandle* a_Client )
-{
- for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
- {
- if (*itr != a_Client)
- {
- continue;
- }
-
- m_LoadedByClient.erase(itr);
-
- if ( !a_Client->IsDestroyed() )
- {
- for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr )
- {
- LOGD("chunk [%i, %i] destroying entity #%i for player \"%s\"", m_PosX, m_PosZ, (*itr)->GetUniqueID(), a_Client->GetUsername().c_str() );
- cPacket_DestroyEntity DestroyEntity( *itr );
- a_Client->Send( DestroyEntity );
- }
- }
- return;
- } // for itr - m_LoadedByClient[]
-}
-
-
-
-
-
-bool cChunk::HasClient( cClientHandle* a_Client )
-{
- for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
- {
- if ((*itr) == a_Client)
- {
- return true;
- }
- }
- return false;
-}
-
-
-
-
-
-bool cChunk::HasAnyClients(void)
-{
- return !m_LoadedByClient.empty();
-}
-
-
-
-
-
-void cChunk::AddEntity( cEntity * a_Entity)
-{
- if (a_Entity->GetEntityType() != cEntity::eEntityType_Player)
- {
- MarkDirty();
- }
- m_Entities.push_back( a_Entity );
-}
-
-
-
-
-
-void cChunk::RemoveEntity(cEntity * a_Entity)
-{
- size_t SizeBefore = m_Entities.size();
- m_Entities.remove(a_Entity);
- size_t SizeAfter = m_Entities.size();
-
- if (SizeBefore != SizeAfter)
- {
- // Mark as dirty if it was a server-generated entity:
- if (a_Entity->GetEntityType() != cEntity::eEntityType_Player)
- {
- MarkDirty();
- }
- }
-}
-
-
-
-
-
-BLOCKTYPE cChunk::GetBlock( int a_X, int a_Y, int a_Z )
-{
- if ((a_X < 0) || (a_X >= Width) || (a_Y < 0) || (a_Y >= Height) || (a_Z < 0) || (a_Z >= Width)) return 0; // Clip
-
- return m_BlockTypes[ MakeIndexNoCheck( a_X, a_Y, a_Z ) ];
-}
-
-
-
-
-
-BLOCKTYPE cChunk::GetBlock( int a_BlockIdx )
-{
- if( a_BlockIdx < 0 || a_BlockIdx >= NumBlocks ) return 0;
- return m_BlockTypes[ a_BlockIdx ];
-}
-
-
-
-
-
-void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta)
-{
- int Idx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ);
- a_BlockType = cChunkDef::GetBlock (m_BlockTypes, a_RelX, a_RelY, a_RelZ);
- a_BlockMeta = cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ);
-}
-
-
-
-
-
-/*
-// _X 2012_02_23: Loading in old format not supported anymore
-/// Loads the chunk from the old-format disk file, erases the file afterwards. Returns true if successful
-bool cChunk::LoadFromDisk()
-{
- AString SourceFile;
- Printf(SourceFile, "world/X%i_Y%i_Z%i.bin", m_PosX, m_PosY, m_PosZ );
-
- cFile f;
- if (!f.Open(SourceFile, cFile::fmRead))
- {
- return false;
- }
-
- if (f.Read(m_BlockData, sizeof(m_BlockData)) != sizeof(m_BlockData))
- {
- LOGERROR("ERROR READING FROM FILE %s", SourceFile.c_str());
- return false;
- }
-
- // Now load Block Entities:
- ENUM_BLOCK_ID BlockType;
- while (f.Read(&BlockType, sizeof(ENUM_BLOCK_ID)) == sizeof(ENUM_BLOCK_ID))
- {
- switch (BlockType)
- {
- case E_BLOCK_CHEST:
- {
- cChestEntity * ChestEntity = new cChestEntity( 0, 0, 0, m_World );
- if (!ChestEntity->LoadFromFile(f))
- {
- LOGERROR("ERROR READING CHEST FROM FILE %s", SourceFile.c_str());
- delete ChestEntity;
- return false;
- }
- m_BlockEntities.push_back( ChestEntity );
- break;
- }
-
- case E_BLOCK_FURNACE:
- {
- cFurnaceEntity* FurnaceEntity = new cFurnaceEntity( 0, 0, 0, m_World );
- if (!FurnaceEntity->LoadFromFile(f))
- {
- LOGERROR("ERROR READING FURNACE FROM FILE %s", SourceFile.c_str());
- delete FurnaceEntity;
- return false;
- }
- m_BlockEntities.push_back( FurnaceEntity );
- break;
- }
-
- case E_BLOCK_SIGN_POST:
- case E_BLOCK_WALLSIGN:
- {
- cSignEntity * SignEntity = new cSignEntity(BlockType, 0, 0, 0, m_World );
- if (!SignEntity->LoadFromFile( f ) )
- {
- LOGERROR("ERROR READING SIGN FROM FILE %s", SourceFile.c_str());
- delete SignEntity;
- return false;
- }
- m_BlockEntities.push_back( SignEntity );
- break;
- }
-
- default:
- {
- ASSERT(!"Unhandled block entity in file");
- break;
- }
- }
- }
- f.Close();
-
- // Delete old format file
- if (std::remove(SourceFile.c_str()) != 0)
- {
- LOGERROR("Could not delete file %s", SourceFile.c_str());
- }
- else
- {
- LOGINFO("Successfully deleted old format file \"%s\"", SourceFile.c_str());
- }
- m_IsDirty = false;
- return true;
-}
-*/
-
-
-
-
-
-void cChunk::Broadcast( const cPacket * a_Packet, cClientHandle* a_Exclude)
-{
- for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr )
- {
- if (*itr == a_Exclude)
- {
- continue;
- }
- (*itr)->Send(*a_Packet);
- } // for itr - LoadedByClient[]
-}
-
-
-
-
-
-void cChunk::PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z)
-{
- a_Y = a_ChunkY;
- a_X = m_PosX * Width + a_ChunkX;
- a_Z = m_PosZ * Width + a_ChunkZ;
-}
-
-
-
-
-
-Vector3i cChunk::PositionToWorldPosition( int a_ChunkX, int a_ChunkY, int a_ChunkZ )
-{
- return Vector3i( m_PosX * Width + a_ChunkX, m_PosY * Height + a_ChunkY, m_PosZ * Width + a_ChunkZ );
-}
-
-
-
-
-
-#if !C_CHUNK_USE_INLINE
-# include "cChunk.inl.h"
-#endif
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#ifndef _WIN32 + #include <cstdlib> +#endif + + +#include "cChunk.h" +#include "cWorld.h" +#include "cWaterSimulator.h" +#include "cLavaSimulator.h" +#include "cClientHandle.h" +#include "cServer.h" +#include "zlib.h" +#include "Defines.h" +#include "cChestEntity.h" +#include "cFurnaceEntity.h" +#include "cSignEntity.h" +#include "cTorch.h" +#include "cLadder.h" +#include "cPickup.h" +#include "cRedstone.h" +#include "cItem.h" +#include "cNoise.h" +#include "cRoot.h" +#include "cBlockToPickup.h" +#include "MersenneTwister.h" +#include "cPlayer.h" + +#include "packets/cPacket_DestroyEntity.h" +#include "packets/cPacket_PreChunk.h" +#include "packets/cPacket_BlockChange.h" +#include "packets/cPacket_MultiBlock.h" + +#include <json/json.h> + + + + + +extern bool g_bWaterPhysics; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// sSetBlock: + +sSetBlock::sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) // absolute block position + : x( a_BlockX ) + , y( a_BlockY ) + , z( a_BlockZ ) + , BlockType( a_BlockType ) + , BlockMeta( a_BlockMeta ) +{ + cChunkDef::AbsoluteToRelative(x, y, z, ChunkX, ChunkZ); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cChunk: + +cChunk::cChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkMap * a_ChunkMap, cWorld * a_World) + : m_PosX( a_ChunkX ) + , m_PosY( a_ChunkY ) + , m_PosZ( a_ChunkZ ) + , m_BlockTickX( 0 ) + , m_BlockTickY( 0 ) + , m_BlockTickZ( 0 ) + , m_World( a_World ) + , m_ChunkMap(a_ChunkMap) + , m_IsValid(false) + , m_IsLightValid(false) + , m_IsDirty(false) + , m_IsSaving(false) + , m_StayCount(0) +{ + // LOGINFO("### new cChunk (%i, %i) at %p, thread 0x%x ###", a_X, a_Z, this, GetCurrentThreadId()); +} + + + + + +cChunk::~cChunk() +{ + // LOGINFO("### delete cChunk() (%i, %i) from %p, thread 0x%x ###", m_PosX, m_PosZ, this, GetCurrentThreadId() ); + + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + delete *itr; + } + m_BlockEntities.clear(); + + // Remove and destroy all entities that are not players: + cEntityList Entities; + for (cEntityList::const_iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) + { + if ((*itr)->GetEntityType() != cEntity::eEntityType_Player) + { + Entities.push_back(*itr); + } + } + for (cEntityList::iterator itr = Entities.begin(); itr != Entities.end(); ++itr) + { + (*itr)->RemoveFromChunk(); + (*itr)->Destroy(); + } + m_Entities.clear(); +} + + + + + +void cChunk::SetValid(void) +{ + m_IsValid = true; + + m_World->GetChunkMap()->ChunkValidated(); +} + + + + + +void cChunk::MarkRegenerating(void) +{ + // Tell all clients attached to this chunk that they want this chunk: + for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) + { + (*itr)->AddWantedChunk(m_PosX, m_PosZ); + } // for itr - m_LoadedByClient[] +} + + + + + +bool cChunk::CanUnload(void) +{ + return m_LoadedByClient.empty() && !m_IsDirty && (m_StayCount == 0); +} + + + + + +void cChunk::MarkSaving(void) +{ + m_IsSaving = true; +} + + + + + +void cChunk::MarkSaved(void) +{ + if (!m_IsSaving) + { + return; + } + m_IsDirty = false; +} + + + + + +void cChunk::MarkLoaded(void) +{ + m_IsDirty = false; + SetValid(); +} + + + + + +void cChunk::MarkLoadFailed(void) +{ + if (m_IsValid) + { + return; + } + + m_HasLoadFailed = true; +} + + + + + +void cChunk::GetAllData(cChunkDataCallback & a_Callback) +{ + a_Callback.HeightMap (&m_HeightMap); + a_Callback.BiomeData (&m_BiomeMap); + a_Callback.BlockTypes (m_BlockTypes); + a_Callback.BlockMeta (m_BlockMeta); + a_Callback.LightIsValid (m_IsLightValid); + a_Callback.BlockLight (m_BlockLight); + a_Callback.BlockSkyLight(m_BlockSkyLight); + + for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) + { + a_Callback.Entity(*itr); + } + + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + a_Callback.BlockEntity(*itr); + } +} + + + + + +void cChunk::SetAllData( + const BLOCKTYPE * a_BlockTypes, + const NIBBLETYPE * a_BlockMeta, + const NIBBLETYPE * a_BlockLight, + const NIBBLETYPE * a_BlockSkyLight, + const HeightMap * a_HeightMap, + const BiomeMap & a_BiomeMap, + cEntityList & a_Entities, + cBlockEntityList & a_BlockEntities +) +{ + memcpy(m_BiomeMap, a_BiomeMap, sizeof(m_BiomeMap)); + + if (a_HeightMap != NULL) + { + memcpy(m_HeightMap, a_HeightMap, sizeof(m_HeightMap)); + } + + memcpy(m_BlockTypes, a_BlockTypes, sizeof(m_BlockTypes)); + memcpy(m_BlockMeta, a_BlockMeta, sizeof(m_BlockMeta)); + if (a_BlockLight != NULL) + { + memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight)); + } + if (a_BlockSkyLight != NULL) + { + memcpy(m_BlockSkyLight, a_BlockSkyLight, sizeof(m_BlockSkyLight)); + } + + m_IsLightValid = (a_BlockLight != NULL) && (a_BlockSkyLight != NULL); + + if (a_HeightMap == NULL) + { + CalculateHeightmap(); + } + + // Append entities to current entity list: + m_Entities.splice(m_Entities.end(), a_Entities); + + // Clear the block entities present - either the loader / saver has better, or we'll create empty ones: + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + delete *itr; + } + std::swap(a_BlockEntities, m_BlockEntities); + + // Create block entities that the loader didn't load; fill them with defaults + CreateBlockEntities(); + + m_HasLoadFailed = false; +} + + + + + +void cChunk::SetLight( + const cChunkDef::BlockNibbles & a_BlockLight, + const cChunkDef::BlockNibbles & a_SkyLight +) +{ + // TODO: We might get cases of wrong lighting when a chunk changes in the middle of a lighting calculation. + // Postponing until we see how bad it is :) + memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight)); + memcpy(m_BlockSkyLight, a_SkyLight, sizeof(m_BlockSkyLight)); + m_IsLightValid = true; +} + + + + + +void cChunk::GetBlockTypes(BLOCKTYPE * a_BlockTypes) +{ + memcpy(a_BlockTypes, m_BlockTypes, NumBlocks); +} + + + + + +void cChunk::GetBlockData(BLOCKTYPE * a_BlockData) +{ + memcpy(a_BlockData, m_BlockTypes, NumBlocks); + memcpy(a_BlockData + MetaOffset, m_BlockMeta, NumBlocks / 2); + memcpy(a_BlockData + LightOffset, m_BlockLight, NumBlocks / 2); + memcpy(a_BlockData + SkyLightOffset, m_BlockSkyLight, NumBlocks / 2); +} + + + + + +/// Returns true if there is a block entity at the coords specified +bool cChunk::HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + if ( + ((*itr)->GetPosX() == a_BlockX) && + ((*itr)->GetPosY() == a_BlockY) && + ((*itr)->GetPosZ() == a_BlockZ) + ) + { + return true; + } + } // for itr - m_BlockEntities[] + return false; +} + + + + + +/// Sets or resets the internal flag that prevents chunk from being unloaded +void cChunk::Stay(bool a_Stay) +{ + m_StayCount += (a_Stay ? 1 : -1); + ASSERT(m_StayCount >= 0); +} + + + + + +void cChunk::Tick(float a_Dt, MTRand & a_TickRandom) +{ + cCSLock Lock(m_CSBlockLists); + unsigned int PendingSendBlocks = m_PendingSendBlocks.size(); + if( PendingSendBlocks > 1 ) + { + cPacket_MultiBlock MultiBlock; + MultiBlock.m_ChunkX = m_PosX; + MultiBlock.m_ChunkZ = m_PosZ; + MultiBlock.m_NumBlocks = (short)PendingSendBlocks; + MultiBlock.m_Data = new cPacket_MultiBlock::sBlockChange[ PendingSendBlocks ]; + MultiBlock.m_DataSize = PendingSendBlocks * sizeof( cPacket_MultiBlock::sBlockChange ); + //LOG("Sending multiblock packet for %i blocks", PendingSendBlocks ); + for( unsigned int i = 0; i < PendingSendBlocks; i++) + { + unsigned int index = m_PendingSendBlocks[i]; + Vector3i BlockPos = IndexToCoordinate( index ); + + unsigned int Coords = BlockPos.y | (BlockPos.z << 8) | (BlockPos.x << 12); + unsigned int Blocks = GetNibble( m_BlockMeta, index ) | (m_BlockTypes[index] << 4); + MultiBlock.m_Data[i].Data = Coords << 16 | Blocks; + } + m_PendingSendBlocks.clear(); + PendingSendBlocks = m_PendingSendBlocks.size(); + Broadcast( MultiBlock ); + } + if( PendingSendBlocks > 0 ) + { + for( unsigned int i = 0; i < PendingSendBlocks; i++) + { + unsigned int index = m_PendingSendBlocks[i]; + Vector3i WorldPos = PositionToWorldPosition( IndexToCoordinate( index ) ); + + cPacket_BlockChange BlockChange; + BlockChange.m_PosX = WorldPos.x; + BlockChange.m_PosY = (unsigned char)WorldPos.y; + BlockChange.m_PosZ = WorldPos.z; + BlockChange.m_BlockType = m_BlockTypes[index]; + BlockChange.m_BlockMeta = GetNibble( m_BlockMeta, index ); + Broadcast( BlockChange ); + } + m_PendingSendBlocks.clear(); + } + Lock.Unlock(); + + while ( !m_UnloadQuery.empty() ) + { + cPacket_PreChunk UnloadPacket; + UnloadPacket.m_PosX = GetPosX(); + UnloadPacket.m_PosZ = GetPosZ(); + UnloadPacket.m_bLoad = false; // Unload + (*m_UnloadQuery.begin())->Send( UnloadPacket ); + m_UnloadQuery.remove( *m_UnloadQuery.begin() ); + } + + CheckBlocks(); + + TickBlocks(a_TickRandom); + + // Tick block entities (furnaces) + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + if ((*itr)->GetBlockType() == E_BLOCK_FURNACE) + { + m_IsDirty = ((cFurnaceEntity *)(*itr))->Tick( a_Dt ) | m_IsDirty; + } + } +} + + + + + +void cChunk::CheckBlocks(void) +{ + cCSLock Lock2(m_CSBlockLists); + unsigned int NumTickBlocks = m_ToTickBlocks.size(); + Lock2.Unlock(); + + if (NumTickBlocks == 0) + { + return; + } + + Lock2.Lock(); + std::deque< unsigned int > ToTickBlocks = m_ToTickBlocks; + m_ToTickBlocks.clear(); + Lock2.Unlock(); + + for (std::deque< unsigned int >::const_iterator itr = ToTickBlocks.begin(); itr != ToTickBlocks.end(); ++itr) + { + unsigned int index = (*itr); + Vector3i BlockPos = IndexToCoordinate(index); + + BLOCKTYPE BlockType = GetBlock(index); + NIBBLETYPE BlockMeta = GetMeta (index); + switch (BlockType) + { + // Stuff that drops when block below is destroyed: + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_REDSTONE_WIRE: + case E_BLOCK_CACTUS: + case E_BLOCK_REEDS: + case E_BLOCK_WOODEN_PRESSURE_PLATE: + case E_BLOCK_STONE_PRESSURE_PLATE: + case E_BLOCK_MINECART_TRACKS: + case E_BLOCK_SIGN_POST: + case E_BLOCK_CROPS: + case E_BLOCK_SAPLING: + case E_BLOCK_YELLOW_FLOWER: + case E_BLOCK_RED_ROSE: + case E_BLOCK_RED_MUSHROOM: + case E_BLOCK_BROWN_MUSHROOM: + case E_BLOCK_SNOW: + { + if (GetBlock(BlockPos.x, BlockPos.y - 1, BlockPos.z) == E_BLOCK_AIR) + { + SetBlock( BlockPos, E_BLOCK_AIR, 0 ); + + Vector3i WorldPos = PositionToWorldPosition( BlockPos ); + + m_World->GetSimulatorManager()->WakeUp(WorldPos.x, WorldPos.y, WorldPos.z); + + cItems Pickups; + cBlockToPickup::ToPickup(BlockType, BlockMeta, E_ITEM_EMPTY, Pickups); + m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z); + } + break; + } + + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_TORCH: + { + char Dir = cTorch::MetaDataToDirection( GetNibble( m_BlockMeta, BlockPos ) ); + Vector3i WorldPos = PositionToWorldPosition( BlockPos ); + + Vector3i AttachedTo = WorldPos; + AddDirection( AttachedTo.x, AttachedTo.y, AttachedTo.z, Dir, true ); + if( m_World->GetBlock( AttachedTo ) == E_BLOCK_AIR ) + { + SetBlock( BlockPos, E_BLOCK_AIR, 0 ); + + m_World->GetSimulatorManager()->WakeUp(WorldPos.x, WorldPos.y, WorldPos.z); + + cItems Pickups; + cBlockToPickup::ToPickup(BlockType, BlockMeta, E_ITEM_EMPTY, Pickups); + m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z); + } + break; + } + + case E_BLOCK_LADDER: + { + char Dir = cLadder::MetaDataToDirection( GetNibble( m_BlockMeta, BlockPos ) ); + Vector3i WorldPos = PositionToWorldPosition( BlockPos ); + Vector3i AttachedTo = WorldPos; + AddDirection( AttachedTo.x, AttachedTo.y, AttachedTo.z, Dir, true ); + if( m_World->GetBlock( AttachedTo ) == E_BLOCK_AIR ) + { + SetBlock( BlockPos, E_BLOCK_AIR, 0 ); + cItems Pickups; + cBlockToPickup::ToPickup(BlockType, BlockMeta, E_ITEM_EMPTY, Pickups); + m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z); + } + break; + } + } // switch (BlockType) + } // for itr - ToTickBlocks[] +} + + + + + +void cChunk::TickBlocks(MTRand & a_TickRandom) +{ + // Tick dem blocks + // _X: We must limit the random number or else we get a nasty int overflow bug ( http://forum.mc-server.org/showthread.php?tid=457 ) + int RandomX = a_TickRandom.randInt(0x00ffffff); + int RandomY = a_TickRandom.randInt(0x00ffffff); + int RandomZ = a_TickRandom.randInt(0x00ffffff); + int TickX = m_BlockTickX; + int TickY = m_BlockTickY; + int TickZ = m_BlockTickZ; + + // This for loop looks disgusting, but it actually does a simple thing - first processes m_BlockTick, then adds random to it + // This is so that SetNextBlockTick() works + for (int i = 0; i < 50; i++, + + // This weird construct (*2, then /2) is needed, + // otherwise the blocktick distribution is too biased towards even coords! + + TickX = (TickX + RandomX) % (Width * 2), + TickY = (TickY + RandomY) % (Height * 2), + TickZ = (TickZ + RandomZ) % (Width * 2), + m_BlockTickX = TickX / 2, + m_BlockTickY = TickY / 2, + m_BlockTickZ = TickZ / 2 + ) + { + + if (m_BlockTickY > cChunkDef::GetHeight(m_HeightMap, m_BlockTickX, m_BlockTickZ)) + { + continue; // It's all air up here + } + + unsigned int Index = MakeIndexNoCheck( m_BlockTickX, m_BlockTickY, m_BlockTickZ ); + BLOCKTYPE ID = m_BlockTypes[Index]; + switch( ID ) + { + case E_BLOCK_CROPS: + { + NIBBLETYPE Meta = GetMeta(Index); + if (Meta < 7) + { + FastSetBlock(m_BlockTickX, m_BlockTickY, m_BlockTickZ, E_BLOCK_CROPS, ++Meta); + } + break; + } + + case E_BLOCK_GRASS: TickGrass (m_BlockTickX, m_BlockTickY, m_BlockTickZ, a_TickRandom); break; + case E_BLOCK_PUMPKIN_STEM: + case E_BLOCK_MELON_STEM: TickMelonPumpkin(m_BlockTickX, m_BlockTickY, m_BlockTickZ, Index, ID, a_TickRandom); break; + case E_BLOCK_FARMLAND: TickFarmland (m_BlockTickX, m_BlockTickY, m_BlockTickZ); break; + case E_BLOCK_SUGARCANE: GrowSugarcane (m_BlockTickX, m_BlockTickY, m_BlockTickZ, 1); break; + case E_BLOCK_CACTUS: GrowCactus (m_BlockTickX, m_BlockTickY, m_BlockTickZ, 1); break; + + case E_BLOCK_SAPLING: + { + // Check the highest bit, if set, grow the tree, if not, set it (1-bit delay): + NIBBLETYPE Meta = GetMeta(m_BlockTickX, m_BlockTickY, m_BlockTickZ); + if ((Meta & 0x08) != 0) + { + m_World->GrowTree( m_BlockTickX + m_PosX*Width, m_BlockTickY, m_BlockTickZ + m_PosZ*Width ); + } + else + { + SetMeta(m_BlockTickX, m_BlockTickY, m_BlockTickZ, Meta | 0x08); + } + break; + } + + case E_BLOCK_LEAVES: //todo, http://www.minecraftwiki.net/wiki/Data_values#Leaves + { + break; + } + + default: + { + break; + } + } + } +} + + + + + +void cChunk::TickGrass(int a_RelX, int a_RelY, int a_RelZ, MTRand & a_TickRandom) +{ + // Grass turns into dirt if there's another block on top of it: + { + BLOCKTYPE AboveBlock = cChunkDef::GetBlock(m_BlockTypes, a_RelX, a_RelY + 1, a_RelZ); + if (!((g_BlockOneHitDig[AboveBlock]) || (g_BlockTransparent[AboveBlock]))) + { + FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0); + return; + } + } + + // Grass spreads to nearby blocks if there's enough light (TODO) and free space above that block + // Ref.: http://www.minecraftwiki.net/wiki/Grass_Block#Growth + for (int i = 0; i < 2; i++) // Pick two blocks to grow to + { + int OfsX = a_TickRandom.randInt(2) - 1; // [-1 .. 1] + int OfsY = a_TickRandom.randInt(4) - 3; // [-3 .. 1] + int OfsZ = a_TickRandom.randInt(2) - 1; // [-1 .. 1] + + BLOCKTYPE DestBlock; + NIBBLETYPE DestMeta; + if ( + !UnboundedRelGetBlock(a_RelX + OfsX, a_RelY + OfsY, a_RelZ + OfsZ, DestBlock, DestMeta) || + (DestBlock != E_BLOCK_DIRT) + ) + { + continue; + } + + BLOCKTYPE AboveDest; + NIBBLETYPE AboveMeta; + if ( + UnboundedRelGetBlock(a_RelX + OfsX, a_RelY + OfsY + 1, a_RelZ + OfsZ, AboveDest, AboveMeta) && + ((g_BlockOneHitDig[AboveDest]) || (g_BlockTransparent[AboveDest])) + // TODO: Query dest light, if it's enough + ) + { + UnboundedRelFastSetBlock(a_RelX + OfsX, a_RelY + OfsY, a_RelZ + OfsZ, E_BLOCK_GRASS, 0); + } + } // for i - repeat twice +} + + + + + +void cChunk::TickMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, int a_BlockIdx, BLOCKTYPE a_BlockType, MTRand & a_TickRandom) +{ + NIBBLETYPE Meta = GetMeta(a_BlockIdx); + if (Meta < 7) + { + FastSetBlock(m_BlockTickX, m_BlockTickY, m_BlockTickZ, a_BlockType, ++Meta); + return; + } + GrowMelonPumpkin(a_RelX, a_RelY, a_RelZ, a_BlockType, a_TickRandom); +} + + + + + +void cChunk::TickFarmland(int a_RelX, int a_RelY, int a_RelZ) +{ + // TODO: Rain hydrates blocks, too. Check world weather, don't search for water if raining. + + // Search for water in a close proximity: + // Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles + bool Found = false; + for (int y = a_RelY; y <= a_RelY + 1; y++) + { + for (int z = a_RelZ - 4; z <= a_RelZ + 4; z++) + { + for (int x = a_RelX - 4; x <= a_RelX + 4; x++) + { + BLOCKTYPE BlockType; + NIBBLETYPE Meta; // unused + + if (!UnboundedRelGetBlock(x, y, z, BlockType, Meta)) + { + // Too close to an unloaded chunk, we might miss a water block there, so don't tick at all + return; + } + if ( + (BlockType == E_BLOCK_WATER) || + (BlockType == E_BLOCK_STATIONARY_WATER) + ) + { + Found = true; + break; + } + } // for x + if (Found) + { + break; + } + } // for z + if (Found) + { + break; + } + } // for y + + NIBBLETYPE BlockMeta = GetMeta(a_RelX, a_RelY, a_RelZ); + + if (Found) + { + // Water was found, hydrate the block until hydration reaches 7: + if (BlockMeta < 7) + { + FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, ++BlockMeta); + } + return; + } + + // Water wasn't found, de-hydrate block: + if (BlockMeta > 0) + { + FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, --BlockMeta); + return; + } + + // Farmland too dry. Turn back to dirt: + FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0); + + // TODO: Uproot whatever was growing on top: +} + + + + + +void cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_TickRandom) +{ + // Convert the stem BlockType into produce BlockType + BLOCKTYPE ProduceType; + switch (a_BlockType) + { + case E_BLOCK_MELON_STEM: ProduceType = E_BLOCK_MELON; break; + case E_BLOCK_PUMPKIN_STEM: ProduceType = E_BLOCK_PUMPKIN; break; + default: + { + ASSERT(!"Unhandled blocktype in TickMelonPumpkin()"); + return; + } + } + + // Check if there's another melon / pumpkin around that stem, if so, abort: + bool IsValid; + BLOCKTYPE BlockType[4]; + NIBBLETYPE BlockMeta; // unused + IsValid = UnboundedRelGetBlock(a_RelX + 1, a_RelY, a_RelZ, BlockType[0], BlockMeta); + IsValid = IsValid && UnboundedRelGetBlock(a_RelX - 1, a_RelY, a_RelZ, BlockType[1], BlockMeta); + IsValid = IsValid && UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ + 1, BlockType[2], BlockMeta); + IsValid = IsValid && UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ - 1, BlockType[3], BlockMeta); + if ( + !IsValid || + (BlockType[0] == ProduceType) || + (BlockType[1] == ProduceType) || + (BlockType[2] == ProduceType) || + (BlockType[3] == ProduceType) + ) + { + // Neighbors not valid or already taken by the same produce + return; + } + + // Pick a direction in which to place the produce: + int x = 0, z = 0; + int CheckType = a_TickRandom.randInt(3); // The index to the neighbors array which should be checked for emptiness + switch (CheckType) + { + case 0: x = 1; break; + case 1: x = -1; break; + case 2: z = 1; break; + case 3: z = -1; break; + } + + // Check that the block in that direction is empty: + switch (BlockType[CheckType]) + { + case E_BLOCK_AIR: + case E_BLOCK_SNOW: + case E_BLOCK_TALL_GRASS: + case E_BLOCK_DEAD_BUSH: + { + break; + } + default: return; + } + + // Check if there's soil under the neighbor. We already know the neighbors are valid. Place produce if ok + BLOCKTYPE Soil; + UnboundedRelGetBlock(a_RelX + x, a_RelY - 1, a_RelZ + z, Soil, BlockMeta); + switch (Soil) + { + case E_BLOCK_DIRT: + case E_BLOCK_GRASS: + case E_BLOCK_FARMLAND: + { + // Place a randomly-facing produce: + UnboundedRelFastSetBlock(a_RelX + x, a_RelY, a_RelZ + z, ProduceType, (NIBBLETYPE)(a_TickRandom.randInt(4) % 4)); + break; + } + } +} + + + + + +void cChunk::GrowSugarcane(int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks) +{ + // Check the total height of the sugarcane blocks here: + int Top = a_RelY + 1; + while ( + (Top < cChunkDef::Height) && + (GetBlock(a_RelX, Top, a_RelZ) == E_BLOCK_SUGARCANE) + ) + { + ++Top; + } + int Bottom = a_RelY - 1; + while ( + (Bottom > 0) && + (GetBlock(a_RelX, Bottom, a_RelZ) == E_BLOCK_SUGARCANE) + ) + { + --Bottom; + } + + // Grow by at most a_NumBlocks, but no more than max height: + int ToGrow = std::min(a_NumBlocks, m_World->GetMaxSugarcaneHeight() + 1 - (Top - Bottom)); + for (int i = 0; i < ToGrow; i++) + { + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + if (UnboundedRelGetBlock(a_RelX, Top + i, a_RelZ, BlockType, BlockMeta) && (BlockType == E_BLOCK_AIR)) + { + UnboundedRelFastSetBlock(a_RelX, Top + i, a_RelZ, E_BLOCK_SUGARCANE, 0); + } + else + { + break; + } + } // for i +} + + + + + +void cChunk::GrowCactus(int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks) +{ + // Check the total height of the sugarcane blocks here: + int Top = a_RelY + 1; + while ( + (Top < cChunkDef::Height) && + (GetBlock(a_RelX, Top, a_RelZ) == E_BLOCK_CACTUS) + ) + { + ++Top; + } + int Bottom = a_RelY - 1; + while ( + (Bottom > 0) && + (GetBlock(a_RelX, Bottom, a_RelZ) == E_BLOCK_CACTUS) + ) + { + --Bottom; + } + + // Grow by at most a_NumBlocks, but no more than max height: + int ToGrow = std::min(a_NumBlocks, m_World->GetMaxCactusHeight() + 1 - (Top - Bottom)); + for (int i = 0; i < ToGrow; i++) + { + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + if (UnboundedRelGetBlock(a_RelX, Top + i, a_RelZ, BlockType, BlockMeta) && (BlockType == E_BLOCK_AIR)) + { + // TODO: Check the surrounding blocks, if they aren't air, break the cactus block into pickups (and continue breaking blocks above in the next loop iterations) + UnboundedRelFastSetBlock(a_RelX, Top + i, a_RelZ, E_BLOCK_CACTUS, 0); + } + else + { + break; + } + } // for i +} + + + + + +bool cChunk::UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) +{ + if ((a_RelY < 0) || (a_RelY > cChunkDef::Height)) + { + return false; + } + + if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) + { + int BlockIdx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); + a_BlockType = GetBlock(BlockIdx); + a_BlockMeta = GetMeta(BlockIdx); + return true; + } + return m_ChunkMap->LockedGetBlock( + m_PosX * cChunkDef::Width + a_RelX, + ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, + m_PosZ * cChunkDef::Width + a_RelZ, + a_BlockType, a_BlockMeta + ); +} + + + + + +bool cChunk::UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) + { + SetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); + return true; + } + return m_ChunkMap->LockedSetBlock( + m_PosX * cChunkDef::Width + a_RelX, + ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, + m_PosZ * cChunkDef::Width + a_RelZ, + a_BlockType, a_BlockMeta + ); +} + + + + + +bool cChunk::UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) + { + FastSetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); + return true; + } + return m_ChunkMap->LockedFastSetBlock( + m_PosX * cChunkDef::Width + a_RelX, + ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, + m_PosZ * cChunkDef::Width + a_RelZ, + a_BlockType, a_BlockMeta + ); +} + + + + + +int cChunk::GetHeight( int a_X, int a_Z ) +{ + ASSERT((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width)); + + if ((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width)) + { + return m_HeightMap[a_X + a_Z * Width]; + } + return 0; +} + + + + + +void cChunk::CreateBlockEntities(void) +{ + for (int x = 0; x < Width; x++) + { + for (int z = 0; z < Width; z++) + { + for (int y = 0; y < Height; y++) + { + ENUM_BLOCK_ID BlockType = (ENUM_BLOCK_ID)m_BlockTypes[ MakeIndex( x, y, z ) ]; + switch ( BlockType ) + { + case E_BLOCK_CHEST: + { + if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width)) + { + m_BlockEntities.push_back( new cChestEntity( x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) ); + } + break; + } + + case E_BLOCK_FURNACE: + { + if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width)) + { + m_BlockEntities.push_back( new cFurnaceEntity( x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) ); + } + break; + } + + case E_BLOCK_SIGN_POST: + case E_BLOCK_WALLSIGN: + { + if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width)) + { + m_BlockEntities.push_back( new cSignEntity( BlockType, x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World) ); + } + break; + } + } // switch (BlockType) + } // for y + } // for z + } // for x +} + + + + + +void cChunk::CalculateHeightmap() +{ + for (int x = 0; x < Width; x++) + { + for (int z = 0; z < Width; z++) + { + for (int y = Height - 1; y > -1; y--) + { + int index = MakeIndex( x, y, z ); + if (m_BlockTypes[index] != E_BLOCK_AIR) + { + m_HeightMap[x + z * Width] = (unsigned char)y; + break; + } + } // for y + } // for z + } // for x +} + + + + + +void cChunk::SetBlock( int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) +{ + if (a_RelX < 0 || a_RelX >= Width || a_RelY < 0 || a_RelY >= Height || a_RelZ < 0 || a_RelZ >= Width) + { + return; // Clip + } + + ASSERT(IsValid()); // Is this chunk loaded / generated? + + int index = MakeIndexNoCheck( a_RelX, a_RelY, a_RelZ ); + BLOCKTYPE OldBlockMeta = GetNibble( m_BlockMeta, index ); + BLOCKTYPE OldBlockType = m_BlockTypes[index]; + m_BlockTypes[index] = a_BlockType; + + SetNibble( m_BlockMeta, index, a_BlockMeta ); + + if ((OldBlockType == a_BlockType) && (OldBlockMeta == a_BlockMeta)) + { + return; + } + + MarkDirty(); + + { + cCSLock Lock(m_CSBlockLists); + m_PendingSendBlocks.push_back( index ); + } + + // ONLY recalculate lighting if it's necessary! + if( + (g_BlockLightValue[ OldBlockType ] != g_BlockLightValue[ a_BlockType ]) || + (g_BlockSpreadLightFalloff[ OldBlockType ] != g_BlockSpreadLightFalloff[ a_BlockType ]) || + (g_BlockTransparent[ OldBlockType ] != g_BlockTransparent[ a_BlockType ] ) + ) + { + m_IsLightValid = false; + } + + // Update heightmap, if needed: + if (a_RelY >= m_HeightMap[a_RelX + a_RelZ * Width]) + { + if (a_BlockType != E_BLOCK_AIR) + { + SetHeight(m_HeightMap, a_RelX, a_RelZ, a_RelY); + } + else + { + for (int y = a_RelY - 1; y > 0; --y) + { + if (cChunkDef::GetBlock(m_BlockTypes, a_RelX, y, a_RelZ) != E_BLOCK_AIR) + { + SetHeight(m_HeightMap, a_RelX, a_RelZ, y); + break; + } + } // for y - column in m_BlockData + } + } + + m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY, a_RelZ ) ); + m_ToTickBlocks.push_back( MakeIndex( a_RelX + 1, a_RelY, a_RelZ ) ); + m_ToTickBlocks.push_back( MakeIndex( a_RelX - 1, a_RelY, a_RelZ ) ); + m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY + 1, a_RelZ ) ); + m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY - 1, a_RelZ ) ); + m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY, a_RelZ + 1 ) ); + m_ToTickBlocks.push_back( MakeIndex( a_RelX, a_RelY, a_RelZ - 1 ) ); + + Vector3i WorldPos = PositionToWorldPosition( a_RelX, a_RelY, a_RelZ ); + cBlockEntity* BlockEntity = GetBlockEntity( WorldPos ); + if( BlockEntity ) + { + BlockEntity->Destroy(); + RemoveBlockEntity( BlockEntity ); + delete BlockEntity; + } + switch( a_BlockType ) + { + case E_BLOCK_CHEST: + { + AddBlockEntity( new cChestEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World) ); + break; + } + case E_BLOCK_FURNACE: + { + AddBlockEntity( new cFurnaceEntity( WorldPos.x, WorldPos.y, WorldPos.z, m_World) ); + break; + } + case E_BLOCK_SIGN_POST: + case E_BLOCK_WALLSIGN: + { + AddBlockEntity( new cSignEntity( (ENUM_BLOCK_ID)a_BlockType, WorldPos.x, WorldPos.y, WorldPos.z, m_World) ); + break; + } + } // switch (a_BlockType) +} + + + + + +void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) +{ + ASSERT(!((a_X < 0 || a_X >= Width || a_Y < 0 || a_Y >= Height || a_Z < 0 || a_Z >= Width))); + + ASSERT(IsValid()); + + const int index = MakeIndexNoCheck( a_X, a_Y, a_Z ); + const BLOCKTYPE OldBlock = m_BlockTypes[index]; + const BLOCKTYPE OldBlockMeta = GetNibble( m_BlockMeta, index ); + if ((OldBlock == a_BlockType) && (OldBlockMeta == a_BlockMeta)) + { + return; + } + + MarkDirty(); + + m_BlockTypes[index] = a_BlockType; + + { + cCSLock Lock(m_CSBlockLists); + m_PendingSendBlocks.push_back( index ); + } + + SetNibble( m_BlockMeta, index, a_BlockMeta ); + + // ONLY recalculate lighting if it's necessary! + if( + (g_BlockLightValue[ OldBlock ] != g_BlockLightValue[ a_BlockType ]) || + (g_BlockSpreadLightFalloff[ OldBlock ] != g_BlockSpreadLightFalloff[ a_BlockType ]) || + (g_BlockTransparent[ OldBlock ] != g_BlockTransparent[ a_BlockType ] ) + ) + { + m_IsLightValid = false; + } + + // Update heightmap, if needed: + if (a_Y >= m_HeightMap[a_X + a_Z * Width]) + { + if (a_BlockType != E_BLOCK_AIR) + { + m_HeightMap[a_X + a_Z * Width] = (unsigned char)a_Y; + } + else + { + for (int y = a_Y - 1; y > 0; --y) + { + if (m_BlockTypes[MakeIndexNoCheck(a_X, y, a_Z)] != E_BLOCK_AIR) + { + m_HeightMap[a_X + a_Z * Width] = (unsigned char)y; + break; + } + } // for y - column in m_BlockData + } + } +} + + + + + +void cChunk::SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client ) +{ + if( a_Client == 0 ) + { + cCSLock Lock(m_CSBlockLists); + unsigned int index = MakeIndex( a_X, a_Y, a_Z ); + if( index != INDEX_OUT_OF_RANGE ) + { + m_PendingSendBlocks.push_back( index ); + } + else + { + LOGWARN("cChunk::SendBlockTo Index out of range!"); + } + return; + } + + for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) + { + if ( *itr == a_Client ) + { + unsigned int index = MakeIndex( a_X, a_Y, a_Z ); + Vector3i WorldPos = PositionToWorldPosition( a_X, a_Y, a_Z ); + cPacket_BlockChange BlockChange; + BlockChange.m_PosX = WorldPos.x; + BlockChange.m_PosY = (unsigned char)WorldPos.y; + BlockChange.m_PosZ = WorldPos.z; + if( index != INDEX_OUT_OF_RANGE ) + { + BlockChange.m_BlockType = m_BlockTypes[ index ]; + BlockChange.m_BlockMeta = GetNibble( m_BlockMeta, index ); + } // else it's both 0 + a_Client->Send( BlockChange ); + break; + } + } +} + + + + + +void cChunk::AddBlockEntity( cBlockEntity* a_BlockEntity ) +{ + cCSLock Lock(m_CSBlockLists); + m_BlockEntities.push_back( a_BlockEntity ); +} + + + + + +cBlockEntity * cChunk::GetBlockEntity(int a_X, int a_Y, int a_Z) +{ + // Assumes that the m_CSBlockList is already locked, we're being called from SetBlock() + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + if ( + ((*itr)->GetPosX() == a_X) && + ((*itr)->GetPosY() == a_Y) && + ((*itr)->GetPosZ() == a_Z) + ) + { + return *itr; + } + } // for itr - m_BlockEntities[] + + return NULL; +} + + + + + +void cChunk::UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) +{ + cBlockEntity * be = GetBlockEntity(a_X, a_Y, a_Z); + if (be != NULL) + { + be->UsedBy(a_Player); + } +} + + + + + +void cChunk::CollectPickupsByPlayer(cPlayer * a_Player) +{ + double PosX = a_Player->GetPosX(); + double PosY = a_Player->GetPosY(); + double PosZ = a_Player->GetPosZ(); + + for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) + { + if ( (*itr)->GetEntityType() != cEntity::eEntityType_Pickup ) + { + continue; // Only pickups + } + float DiffX = (float)((*itr)->GetPosX() - PosX ); + float DiffY = (float)((*itr)->GetPosY() - PosY ); + float DiffZ = (float)((*itr)->GetPosZ() - PosZ ); + float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ; + if (SqrDist < 1.5f * 1.5f) // 1.5 block + { + MarkDirty(); + (reinterpret_cast<cPickup *>(*itr))->CollectedBy( a_Player ); + } + } +} + + + + + +void cChunk::UpdateSign(int a_PosX, int a_PosY, int a_PosZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) +{ + // Also sends update packets to all clients in the chunk + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + if ( + ((*itr)->GetPosX() == a_PosX) && + ((*itr)->GetPosY() == a_PosY) && + ((*itr)->GetPosZ() == a_PosZ) && + ( + ((*itr)->GetBlockType() == E_BLOCK_WALLSIGN) || + ((*itr)->GetBlockType() == E_BLOCK_SIGN_POST) + ) + ) + { + MarkDirty(); + (reinterpret_cast<cSignEntity *>(*itr))->SetLines(a_Line1, a_Line2, a_Line3, a_Line4); + (*itr)->SendTo(NULL); + } + } // for itr - m_BlockEntities[] +} + + + + + +void cChunk::RemoveBlockEntity( cBlockEntity* a_BlockEntity ) +{ + cCSLock Lock(m_CSBlockLists); + MarkDirty(); + m_BlockEntities.remove( a_BlockEntity ); +} + + + + + +bool cChunk::AddClient(cClientHandle* a_Client) +{ + for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) + { + if (a_Client == *itr) + { + // Already there, nothing needed + return false; + } + } + m_LoadedByClient.push_back( a_Client ); + + for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr ) + { + LOGD("cChunk: Entity #%d (%s) at [%i, %i, %i] spawning for player \"%s\"", (*itr)->GetUniqueID(), (*itr)->GetClass(), m_PosX, m_PosY, m_PosZ, a_Client->GetUsername().c_str() ); + (*itr)->SpawnOn( a_Client ); + } + return true; +} + + + + + +void cChunk::RemoveClient( cClientHandle* a_Client ) +{ + for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) + { + if (*itr != a_Client) + { + continue; + } + + m_LoadedByClient.erase(itr); + + if ( !a_Client->IsDestroyed() ) + { + for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr ) + { + LOGD("chunk [%i, %i] destroying entity #%i for player \"%s\"", m_PosX, m_PosZ, (*itr)->GetUniqueID(), a_Client->GetUsername().c_str() ); + cPacket_DestroyEntity DestroyEntity( *itr ); + a_Client->Send( DestroyEntity ); + } + } + return; + } // for itr - m_LoadedByClient[] +} + + + + + +bool cChunk::HasClient( cClientHandle* a_Client ) +{ + for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) + { + if ((*itr) == a_Client) + { + return true; + } + } + return false; +} + + + + + +bool cChunk::HasAnyClients(void) +{ + return !m_LoadedByClient.empty(); +} + + + + + +void cChunk::AddEntity( cEntity * a_Entity) +{ + if (a_Entity->GetEntityType() != cEntity::eEntityType_Player) + { + MarkDirty(); + } + m_Entities.push_back( a_Entity ); +} + + + + + +void cChunk::RemoveEntity(cEntity * a_Entity) +{ + size_t SizeBefore = m_Entities.size(); + m_Entities.remove(a_Entity); + size_t SizeAfter = m_Entities.size(); + + if (SizeBefore != SizeAfter) + { + // Mark as dirty if it was a server-generated entity: + if (a_Entity->GetEntityType() != cEntity::eEntityType_Player) + { + MarkDirty(); + } + } +} + + + + + +BLOCKTYPE cChunk::GetBlock( int a_X, int a_Y, int a_Z ) +{ + if ((a_X < 0) || (a_X >= Width) || (a_Y < 0) || (a_Y >= Height) || (a_Z < 0) || (a_Z >= Width)) return 0; // Clip + + return m_BlockTypes[ MakeIndexNoCheck( a_X, a_Y, a_Z ) ]; +} + + + + + +BLOCKTYPE cChunk::GetBlock( int a_BlockIdx ) +{ + if( a_BlockIdx < 0 || a_BlockIdx >= NumBlocks ) return 0; + return m_BlockTypes[ a_BlockIdx ]; +} + + + + + +void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) +{ + int Idx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); + a_BlockType = cChunkDef::GetBlock (m_BlockTypes, a_RelX, a_RelY, a_RelZ); + a_BlockMeta = cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ); +} + + + + + +/* +// _X 2012_02_23: Loading in old format not supported anymore +/// Loads the chunk from the old-format disk file, erases the file afterwards. Returns true if successful +bool cChunk::LoadFromDisk() +{ + AString SourceFile; + Printf(SourceFile, "world/X%i_Y%i_Z%i.bin", m_PosX, m_PosY, m_PosZ ); + + cFile f; + if (!f.Open(SourceFile, cFile::fmRead)) + { + return false; + } + + if (f.Read(m_BlockData, sizeof(m_BlockData)) != sizeof(m_BlockData)) + { + LOGERROR("ERROR READING FROM FILE %s", SourceFile.c_str()); + return false; + } + + // Now load Block Entities: + ENUM_BLOCK_ID BlockType; + while (f.Read(&BlockType, sizeof(ENUM_BLOCK_ID)) == sizeof(ENUM_BLOCK_ID)) + { + switch (BlockType) + { + case E_BLOCK_CHEST: + { + cChestEntity * ChestEntity = new cChestEntity( 0, 0, 0, m_World ); + if (!ChestEntity->LoadFromFile(f)) + { + LOGERROR("ERROR READING CHEST FROM FILE %s", SourceFile.c_str()); + delete ChestEntity; + return false; + } + m_BlockEntities.push_back( ChestEntity ); + break; + } + + case E_BLOCK_FURNACE: + { + cFurnaceEntity* FurnaceEntity = new cFurnaceEntity( 0, 0, 0, m_World ); + if (!FurnaceEntity->LoadFromFile(f)) + { + LOGERROR("ERROR READING FURNACE FROM FILE %s", SourceFile.c_str()); + delete FurnaceEntity; + return false; + } + m_BlockEntities.push_back( FurnaceEntity ); + break; + } + + case E_BLOCK_SIGN_POST: + case E_BLOCK_WALLSIGN: + { + cSignEntity * SignEntity = new cSignEntity(BlockType, 0, 0, 0, m_World ); + if (!SignEntity->LoadFromFile( f ) ) + { + LOGERROR("ERROR READING SIGN FROM FILE %s", SourceFile.c_str()); + delete SignEntity; + return false; + } + m_BlockEntities.push_back( SignEntity ); + break; + } + + default: + { + ASSERT(!"Unhandled block entity in file"); + break; + } + } + } + f.Close(); + + // Delete old format file + if (std::remove(SourceFile.c_str()) != 0) + { + LOGERROR("Could not delete file %s", SourceFile.c_str()); + } + else + { + LOGINFO("Successfully deleted old format file \"%s\"", SourceFile.c_str()); + } + m_IsDirty = false; + return true; +} +*/ + + + + + +void cChunk::Broadcast( const cPacket * a_Packet, cClientHandle* a_Exclude) +{ + for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) + { + if (*itr == a_Exclude) + { + continue; + } + (*itr)->Send(*a_Packet); + } // for itr - LoadedByClient[] +} + + + + + +void cChunk::PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z) +{ + a_Y = a_ChunkY; + a_X = m_PosX * Width + a_ChunkX; + a_Z = m_PosZ * Width + a_ChunkZ; +} + + + + + +Vector3i cChunk::PositionToWorldPosition( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) +{ + return Vector3i( m_PosX * Width + a_ChunkX, m_PosY * Height + a_ChunkY, m_PosZ * Width + a_ChunkZ ); +} + + + + + +#if !C_CHUNK_USE_INLINE +# include "cChunk.inl.h" +#endif + + + + diff --git a/source/cChunk.h b/source/cChunk.h index b92b62ff8..e24990982 100644 --- a/source/cChunk.h +++ b/source/cChunk.h @@ -1,271 +1,271 @@ -
-#pragma once
-
-#include "cEntity.h"
-#include "ChunkDef.h"
-
-
-
-
-
-#define C_CHUNK_USE_INLINE 1
-
-// Do not touch
-#if C_CHUNK_USE_INLINE
- #define __C_CHUNK_INLINE__ inline
-#else
- #define __C_CHUNK_INLINE__
-#endif
-
-
-
-
-
-namespace Json
-{
- class Value;
-};
-
-
-
-
-
-class cWorld;
-class cFurnaceEntity;
-class cPacket;
-class cClientHandle;
-class cServer;
-class MTRand;
-class cPlayer;
-class cChunkMap;
-
-typedef std::list<cClientHandle *> cClientHandleList;
-
-
-
-
-
-// This class is not to be used directly
-// Instead, call actions on cChunkMap (such as cChunkMap::SetBlock() etc.)
-class cChunk :
- public cChunkDef // The inheritance is "misused" here only to inherit the functions and constants defined in cChunkDef
-{
-public:
- cChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkMap * a_ChunkMap, cWorld * a_World);
- ~cChunk();
-
- bool IsValid(void) const {return m_IsValid; } // Returns true if the chunk block data is valid (loaded / generated)
- void SetValid(void); // Also wakes up any calls to cChunkMap::GetHeight()
- void MarkRegenerating(void); // Marks all clients attached to this chunk as wanting this chunk
- bool IsDirty(void) const {return m_IsDirty; } // Returns true if the chunk has changed since it was last saved
- bool HasLoadFailed(void) const {return m_HasLoadFailed; } // Returns true if the chunk failed to load and hasn't been generated since then
- bool CanUnload(void);
-
- bool IsLightValid(void) const {return m_IsLightValid; }
-
- /*
- To save a chunk, the WSSchema must:
- 1. Mark the chunk as being saved (MarkSaving() )
- 2. Get the chunk's data using GetAllData()
- 3. Mark the chunk as saved (MarkSaved() )
- If anywhere inside this sequence another thread mmodifies the chunk, the chunk will not get marked as saved in MarkSaved()
- */
- void MarkSaving(void); // Marks the chunk as being saved.
- void MarkSaved(void); // Marks the chunk as saved, if it didn't change from the last call to MarkSaving()
- void MarkLoaded(void); // Marks the chunk as freshly loaded. Fails if the chunk is already valid
- void MarkLoadFailed(void); // Marks the chunk as failed to load. Ignored is the chunk is already valid
-
- /// Gets all chunk data, calls the a_Callback's methods for each data type
- void GetAllData(cChunkDataCallback & a_Callback);
-
- /// Sets all chunk data
- void SetAllData(
- const BLOCKTYPE * a_BlockTypes,
- const NIBBLETYPE * a_BlockMeta,
- const NIBBLETYPE * a_BlockLight,
- const NIBBLETYPE * a_BlockSkyLight,
- const cChunkDef::HeightMap * a_HeightMap,
- const cChunkDef::BiomeMap & a_BiomeMap,
- cEntityList & a_Entities,
- cBlockEntityList & a_BlockEntities
- );
-
- void SetLight(
- const cChunkDef::BlockNibbles & a_BlockLight,
- const cChunkDef::BlockNibbles & a_SkyLight
- );
-
- /// Copies m_BlockData into a_BlockTypes, only the block types
- void GetBlockTypes(BLOCKTYPE * a_BlockTypes);
-
- /// Copies entire block data into a_BlockData, the entire 4 arrays (Type, Meta, Light, SkyLight)
- void GetBlockData(BLOCKTYPE * a_BlockData);
-
- /// Returns true if there is a block entity at the coords specified
- bool HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ);
-
- /// Sets or resets the internal flag that prevents chunk from being unloaded
- void Stay(bool a_Stay = true);
-
- void Tick(float a_Dt, MTRand & a_TickRandom);
-
- int GetPosX() { return m_PosX; }
- int GetPosY() { return m_PosY; }
- int GetPosZ() { return m_PosZ; }
- cWorld * GetWorld() { return m_World; }
-
- // OBSOLETE void SendTo( cClientHandle * a_Client );
-
- void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta );
- // SetBlock() does a lot of work (heightmap, tickblocks, blockentities) so a BlockIdx version doesn't make sense
- void SetBlock( const Vector3i & a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) { SetBlock( a_RelBlockPos.x, a_RelBlockPos.y, a_RelBlockPos.z, a_BlockType, a_BlockMeta ); }
- void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta ); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc.
- BLOCKTYPE GetBlock( int a_X, int a_Y, int a_Z );
- BLOCKTYPE GetBlock( int a_BlockIdx );
- void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta);
-
- EMCSBiome GetBiomeAt(int a_RelX, int a_RelZ) const {return cChunkDef::GetBiome(m_BiomeMap, a_RelX, a_RelZ); }
-
- void CollectPickupsByPlayer(cPlayer * a_Player);
- void UpdateSign(int a_PosX, int a_PosY, int a_PosZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); // Also sends update packets to all clients in the chunk
-
- int GetHeight( int a_X, int a_Z );
-
- void SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client );
-
- /// Adds a client to the chunk; returns true if added, false if already there
- bool AddClient (cClientHandle* a_Client );
-
- void RemoveClient (cClientHandle* a_Client );
- bool HasClient (cClientHandle* a_Client );
- bool HasAnyClients(void); // Returns true if theres any client in the chunk; false otherwise
-
- void AddEntity( cEntity * a_Entity);
- void RemoveEntity( cEntity * a_Entity);
-
- void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); // [x, y, z] in world block coords
-
- void CalculateLighting(); // Recalculate right now
- void CalculateHeightmap();
-
- // Broadcasts to all clients that have loaded this chunk
- void Broadcast( const cPacket & a_Packet, cClientHandle * a_Exclude = NULL) {Broadcast(&a_Packet, a_Exclude); }
- void Broadcast( const cPacket * a_Packet, cClientHandle * a_Exclude = NULL);
-
- void PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z);
- Vector3i PositionToWorldPosition( const Vector3i & a_InChunkPos ) { return PositionToWorldPosition( a_InChunkPos.x, a_InChunkPos.y, a_InChunkPos.z ); }
- Vector3i PositionToWorldPosition( int a_ChunkX, int a_ChunkY, int a_ChunkZ );
-
- inline void MarkDirty(void)
- {
- m_IsDirty = true;
- m_IsSaving = false;
- }
-
- /// Sets the blockticking to start at the specified block. Only one blocktick may be set, second call overwrites the first call
- inline void SetNextBlockTick(int a_RelX, int a_RelY, int a_RelZ)
- {
- m_BlockTickX = a_RelX;
- m_BlockTickY = a_RelY;
- m_BlockTickZ = a_RelZ;
- }
-
- inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ); }
- inline NIBBLETYPE GetMeta(int a_BlockIdx) {return cChunkDef::GetNibble(m_BlockMeta, a_BlockIdx); }
- inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta) { cChunkDef::SetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ, a_Meta); }
-
- inline NIBBLETYPE GetLight(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockLight, a_RelX, a_RelY, a_RelZ); }
- inline NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockSkyLight, a_RelX, a_RelY, a_RelZ); }
-
-private:
-
- friend class cChunkMap;
-
- bool m_IsValid; // True if the chunk is loaded / generated
- bool m_IsLightValid; // True if the blocklight and skylight are calculated
- bool m_IsDirty; // True if the chunk has changed since it was last saved
- bool m_IsSaving; // True if the chunk is being saved
- bool m_HasLoadFailed; // True if chunk failed to load and hasn't been generated yet since then
-
- cCriticalSection m_CSBlockLists;
- std::deque< unsigned int > m_ToTickBlocks;
- std::vector< unsigned int > m_PendingSendBlocks;
-
- // A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers
- cClientHandleList m_LoadedByClient;
- cClientHandleList m_UnloadQuery;
- cEntityList m_Entities;
- cBlockEntityList m_BlockEntities;
-
- /// Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded
- int m_StayCount;
-
- int m_PosX, m_PosY, m_PosZ;
- cWorld * m_World;
- cChunkMap * m_ChunkMap;
-
- // TODO: Make these pointers and don't allocate what isn't needed
- BLOCKTYPE m_BlockTypes [cChunkDef::NumBlocks];
- NIBBLETYPE m_BlockMeta [cChunkDef::NumBlocks / 2];
- NIBBLETYPE m_BlockLight [cChunkDef::NumBlocks / 2];
- NIBBLETYPE m_BlockSkyLight[cChunkDef::NumBlocks / 2];
-
- cChunkDef::HeightMap m_HeightMap;
- cChunkDef::BiomeMap m_BiomeMap;
-
- int m_BlockTickX, m_BlockTickY, m_BlockTickZ;
-
- void RemoveBlockEntity( cBlockEntity* a_BlockEntity );
- void AddBlockEntity( cBlockEntity* a_BlockEntity );
- cBlockEntity * GetBlockEntity( int a_X, int a_Y, int a_Z );
- cBlockEntity * GetBlockEntity( const Vector3i & a_BlockPos ) { return GetBlockEntity( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); }
-
- void SpreadLightOfBlock(NIBBLETYPE * a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff);
-
- void CreateBlockEntities(void);
-
- // Makes a copy of the list
- cClientHandleList GetAllClients(void) const {return m_LoadedByClient; }
-
- /// Checks the block scheduled for checking in m_ToTickBlocks[]
- void CheckBlocks(void);
-
- void TickBlocks (MTRand & a_TickRandom);
- void TickGrass (int a_RelX, int a_RelY, int a_RelZ, MTRand & a_TickRandom);
- void TickMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, int a_BlockIdx, BLOCKTYPE a_BlockType, MTRand & a_TickRandom);
- void TickFarmland (int a_RelX, int a_RelY, int a_RelZ);
-
- /// Grows sugarcane by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking)
- void GrowSugarcane (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks);
-
- /// Grows cactus by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking)
- void GrowCactus (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks);
-
- /// Grows a melon or a pumpkin next to the block specified (assumed to be the stem)
- void GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_Random);
-
- /// Same as GetBlock(), but relative coords needn't be in this chunk (uses m_ChunkMap in such a case); returns true on success; only usable in Tick()
- bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta);
-
- /// Same as SetBlock(), but relative coords needn't be in this chunk (uses m_ChunkMap in such a case); returns true on success; only usable in Tick()
- bool UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
-
- /// Same as FastSetBlock(), but relative coords needn't be in this chunk (uses m_ChunkMap in such a case); returns true on success; only usable in Tick()
- bool UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
-};
-
-typedef cChunk * cChunkPtr;
-
-typedef std::list<cChunkPtr> cChunkPtrList;
-
-
-
-
-
-#if C_CHUNK_USE_INLINE
- #include "cChunk.inl.h"
-#endif
-
-
-
-
+ +#pragma once + +#include "cEntity.h" +#include "ChunkDef.h" + + + + + +#define C_CHUNK_USE_INLINE 1 + +// Do not touch +#if C_CHUNK_USE_INLINE + #define __C_CHUNK_INLINE__ inline +#else + #define __C_CHUNK_INLINE__ +#endif + + + + + +namespace Json +{ + class Value; +}; + + + + + +class cWorld; +class cFurnaceEntity; +class cPacket; +class cClientHandle; +class cServer; +class MTRand; +class cPlayer; +class cChunkMap; + +typedef std::list<cClientHandle *> cClientHandleList; + + + + + +// This class is not to be used directly +// Instead, call actions on cChunkMap (such as cChunkMap::SetBlock() etc.) +class cChunk : + public cChunkDef // The inheritance is "misused" here only to inherit the functions and constants defined in cChunkDef +{ +public: + cChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkMap * a_ChunkMap, cWorld * a_World); + ~cChunk(); + + bool IsValid(void) const {return m_IsValid; } // Returns true if the chunk block data is valid (loaded / generated) + void SetValid(void); // Also wakes up any calls to cChunkMap::GetHeight() + void MarkRegenerating(void); // Marks all clients attached to this chunk as wanting this chunk + bool IsDirty(void) const {return m_IsDirty; } // Returns true if the chunk has changed since it was last saved + bool HasLoadFailed(void) const {return m_HasLoadFailed; } // Returns true if the chunk failed to load and hasn't been generated since then + bool CanUnload(void); + + bool IsLightValid(void) const {return m_IsLightValid; } + + /* + To save a chunk, the WSSchema must: + 1. Mark the chunk as being saved (MarkSaving() ) + 2. Get the chunk's data using GetAllData() + 3. Mark the chunk as saved (MarkSaved() ) + If anywhere inside this sequence another thread mmodifies the chunk, the chunk will not get marked as saved in MarkSaved() + */ + void MarkSaving(void); // Marks the chunk as being saved. + void MarkSaved(void); // Marks the chunk as saved, if it didn't change from the last call to MarkSaving() + void MarkLoaded(void); // Marks the chunk as freshly loaded. Fails if the chunk is already valid + void MarkLoadFailed(void); // Marks the chunk as failed to load. Ignored is the chunk is already valid + + /// Gets all chunk data, calls the a_Callback's methods for each data type + void GetAllData(cChunkDataCallback & a_Callback); + + /// Sets all chunk data + void SetAllData( + const BLOCKTYPE * a_BlockTypes, + const NIBBLETYPE * a_BlockMeta, + const NIBBLETYPE * a_BlockLight, + const NIBBLETYPE * a_BlockSkyLight, + const cChunkDef::HeightMap * a_HeightMap, + const cChunkDef::BiomeMap & a_BiomeMap, + cEntityList & a_Entities, + cBlockEntityList & a_BlockEntities + ); + + void SetLight( + const cChunkDef::BlockNibbles & a_BlockLight, + const cChunkDef::BlockNibbles & a_SkyLight + ); + + /// Copies m_BlockData into a_BlockTypes, only the block types + void GetBlockTypes(BLOCKTYPE * a_BlockTypes); + + /// Copies entire block data into a_BlockData, the entire 4 arrays (Type, Meta, Light, SkyLight) + void GetBlockData(BLOCKTYPE * a_BlockData); + + /// Returns true if there is a block entity at the coords specified + bool HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ); + + /// Sets or resets the internal flag that prevents chunk from being unloaded + void Stay(bool a_Stay = true); + + void Tick(float a_Dt, MTRand & a_TickRandom); + + int GetPosX() { return m_PosX; } + int GetPosY() { return m_PosY; } + int GetPosZ() { return m_PosZ; } + cWorld * GetWorld() { return m_World; } + + // OBSOLETE void SendTo( cClientHandle * a_Client ); + + void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ); + // SetBlock() does a lot of work (heightmap, tickblocks, blockentities) so a BlockIdx version doesn't make sense + void SetBlock( const Vector3i & a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) { SetBlock( a_RelBlockPos.x, a_RelBlockPos.y, a_RelBlockPos.z, a_BlockType, a_BlockMeta ); } + void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta ); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc. + BLOCKTYPE GetBlock( int a_X, int a_Y, int a_Z ); + BLOCKTYPE GetBlock( int a_BlockIdx ); + void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); + + EMCSBiome GetBiomeAt(int a_RelX, int a_RelZ) const {return cChunkDef::GetBiome(m_BiomeMap, a_RelX, a_RelZ); } + + void CollectPickupsByPlayer(cPlayer * a_Player); + void UpdateSign(int a_PosX, int a_PosY, int a_PosZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); // Also sends update packets to all clients in the chunk + + int GetHeight( int a_X, int a_Z ); + + void SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client ); + + /// Adds a client to the chunk; returns true if added, false if already there + bool AddClient (cClientHandle* a_Client ); + + void RemoveClient (cClientHandle* a_Client ); + bool HasClient (cClientHandle* a_Client ); + bool HasAnyClients(void); // Returns true if theres any client in the chunk; false otherwise + + void AddEntity( cEntity * a_Entity); + void RemoveEntity( cEntity * a_Entity); + + void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); // [x, y, z] in world block coords + + void CalculateLighting(); // Recalculate right now + void CalculateHeightmap(); + + // Broadcasts to all clients that have loaded this chunk + void Broadcast( const cPacket & a_Packet, cClientHandle * a_Exclude = NULL) {Broadcast(&a_Packet, a_Exclude); } + void Broadcast( const cPacket * a_Packet, cClientHandle * a_Exclude = NULL); + + void PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z); + Vector3i PositionToWorldPosition( const Vector3i & a_InChunkPos ) { return PositionToWorldPosition( a_InChunkPos.x, a_InChunkPos.y, a_InChunkPos.z ); } + Vector3i PositionToWorldPosition( int a_ChunkX, int a_ChunkY, int a_ChunkZ ); + + inline void MarkDirty(void) + { + m_IsDirty = true; + m_IsSaving = false; + } + + /// Sets the blockticking to start at the specified block. Only one blocktick may be set, second call overwrites the first call + inline void SetNextBlockTick(int a_RelX, int a_RelY, int a_RelZ) + { + m_BlockTickX = a_RelX; + m_BlockTickY = a_RelY; + m_BlockTickZ = a_RelZ; + } + + inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ); } + inline NIBBLETYPE GetMeta(int a_BlockIdx) {return cChunkDef::GetNibble(m_BlockMeta, a_BlockIdx); } + inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta) { cChunkDef::SetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ, a_Meta); } + + inline NIBBLETYPE GetLight(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockLight, a_RelX, a_RelY, a_RelZ); } + inline NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockSkyLight, a_RelX, a_RelY, a_RelZ); } + +private: + + friend class cChunkMap; + + bool m_IsValid; // True if the chunk is loaded / generated + bool m_IsLightValid; // True if the blocklight and skylight are calculated + bool m_IsDirty; // True if the chunk has changed since it was last saved + bool m_IsSaving; // True if the chunk is being saved + bool m_HasLoadFailed; // True if chunk failed to load and hasn't been generated yet since then + + cCriticalSection m_CSBlockLists; + std::deque< unsigned int > m_ToTickBlocks; + std::vector< unsigned int > m_PendingSendBlocks; + + // A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers + cClientHandleList m_LoadedByClient; + cClientHandleList m_UnloadQuery; + cEntityList m_Entities; + cBlockEntityList m_BlockEntities; + + /// Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded + int m_StayCount; + + int m_PosX, m_PosY, m_PosZ; + cWorld * m_World; + cChunkMap * m_ChunkMap; + + // TODO: Make these pointers and don't allocate what isn't needed + BLOCKTYPE m_BlockTypes [cChunkDef::NumBlocks]; + NIBBLETYPE m_BlockMeta [cChunkDef::NumBlocks / 2]; + NIBBLETYPE m_BlockLight [cChunkDef::NumBlocks / 2]; + NIBBLETYPE m_BlockSkyLight[cChunkDef::NumBlocks / 2]; + + cChunkDef::HeightMap m_HeightMap; + cChunkDef::BiomeMap m_BiomeMap; + + int m_BlockTickX, m_BlockTickY, m_BlockTickZ; + + void RemoveBlockEntity( cBlockEntity* a_BlockEntity ); + void AddBlockEntity( cBlockEntity* a_BlockEntity ); + cBlockEntity * GetBlockEntity( int a_X, int a_Y, int a_Z ); + cBlockEntity * GetBlockEntity( const Vector3i & a_BlockPos ) { return GetBlockEntity( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); } + + void SpreadLightOfBlock(NIBBLETYPE * a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff); + + void CreateBlockEntities(void); + + // Makes a copy of the list + cClientHandleList GetAllClients(void) const {return m_LoadedByClient; } + + /// Checks the block scheduled for checking in m_ToTickBlocks[] + void CheckBlocks(void); + + void TickBlocks (MTRand & a_TickRandom); + void TickGrass (int a_RelX, int a_RelY, int a_RelZ, MTRand & a_TickRandom); + void TickMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, int a_BlockIdx, BLOCKTYPE a_BlockType, MTRand & a_TickRandom); + void TickFarmland (int a_RelX, int a_RelY, int a_RelZ); + + /// Grows sugarcane by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking) + void GrowSugarcane (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks); + + /// Grows cactus by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking) + void GrowCactus (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks); + + /// Grows a melon or a pumpkin next to the block specified (assumed to be the stem) + void GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_Random); + + /// Same as GetBlock(), but relative coords needn't be in this chunk (uses m_ChunkMap in such a case); returns true on success; only usable in Tick() + bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); + + /// Same as SetBlock(), but relative coords needn't be in this chunk (uses m_ChunkMap in such a case); returns true on success; only usable in Tick() + bool UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + + /// Same as FastSetBlock(), but relative coords needn't be in this chunk (uses m_ChunkMap in such a case); returns true on success; only usable in Tick() + bool UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); +}; + +typedef cChunk * cChunkPtr; + +typedef std::list<cChunkPtr> cChunkPtrList; + + + + + +#if C_CHUNK_USE_INLINE + #include "cChunk.inl.h" +#endif + + + + diff --git a/source/cChunk.inl.h b/source/cChunk.inl.h index f0353521c..fb9c4dad1 100644 --- a/source/cChunk.inl.h +++ b/source/cChunk.inl.h @@ -1,34 +1,34 @@ -
-#ifndef __C_CHUNK_INL_H__
-#define __C_CHUNK_INL_H__
-
-#ifndef MAX
-# define MAX(a,b) (((a)>(b))?(a):(b))
-#endif
-
-
-
-
-
-__C_CHUNK_INLINE__
-void cChunk::SpreadLightOfBlock(NIBBLETYPE * a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff)
-{
- unsigned char CurrentLight = cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z );
- cChunkDef::SetNibble( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X-1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
- cChunkDef::SetNibble( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X+1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
- cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y-1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
- cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y+1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
- cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z-1 ), MAX(0,CurrentLight-a_Falloff) ) );
- cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z+1 ), MAX(0,CurrentLight-a_Falloff) ) );
- MarkDirty();
-}
-
-
-
-
-
-#endif
-
-
-
-
+ +#ifndef __C_CHUNK_INL_H__ +#define __C_CHUNK_INL_H__ + +#ifndef MAX +# define MAX(a,b) (((a)>(b))?(a):(b)) +#endif + + + + + +__C_CHUNK_INLINE__ +void cChunk::SpreadLightOfBlock(NIBBLETYPE * a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff) +{ + unsigned char CurrentLight = cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z ); + cChunkDef::SetNibble( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X-1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); + cChunkDef::SetNibble( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X+1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); + cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y-1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); + cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y+1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) ); + cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z-1 ), MAX(0,CurrentLight-a_Falloff) ) ); + cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z+1 ), MAX(0,CurrentLight-a_Falloff) ) ); + MarkDirty(); +} + + + + + +#endif + + + + diff --git a/source/cChunkGenerator.cpp b/source/cChunkGenerator.cpp index 82dc432e3..bed9d5cb8 100644 --- a/source/cChunkGenerator.cpp +++ b/source/cChunkGenerator.cpp @@ -1,544 +1,544 @@ -
-#include "Globals.h"
-
-#include "cChunkGenerator.h"
-#include "cWorld.h"
-#include "../iniFile/iniFile.h"
-#include "BioGen.h"
-#include "HeiGen.h"
-#include "CompoGen.h"
-#include "StructGen.h"
-#include "FinishGen.h"
-#include "cRoot.h"
-#include "cPluginManager.h"
-#include "cLuaChunk.h"
-
-
-
-
-
-/// If the generation queue size exceeds this number, a warning will be output
-const int QUEUE_WARNING_LIMIT = 1000;
-
-/// If the generation queue size exceeds this number, chunks with no clients will be skipped
-const int QUEUE_SKIP_LIMIT = 500;
-
-
-
-
-
-static BLOCKTYPE GetIniBlock(cIniFile & a_IniFile, const AString & a_SectionName, const AString & a_ValueName, const AString & a_Default)
-{
- AString BlockType = a_IniFile.GetValueSet(a_SectionName, a_ValueName, a_Default);
- BLOCKTYPE Block = BlockStringToType(BlockType);
- if (Block < 0)
- {
- LOGWARN("[&s].%s Could not parse block value \"%s\". Using default: \"%s\".", a_SectionName.c_str(), a_ValueName.c_str(), BlockType.c_str(),a_Default.c_str());
- return BlockStringToType(a_Default);
- }
- return Block;
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cChunkGenerator:
-
-cChunkGenerator::cChunkGenerator(void)
- : super("cChunkGenerator")
- , m_World(NULL)
- , m_BiomeGen(NULL)
- , m_HeightGen(NULL)
- , m_CompositionGen(NULL)
-{
-}
-
-
-
-
-
-cChunkGenerator::~cChunkGenerator()
-{
- Stop();
-}
-
-
-
-
-
-bool cChunkGenerator::Start(cWorld * a_World, cIniFile & a_IniFile)
-{
- MTRand rnd;
- m_World = a_World;
- m_Seed = a_IniFile.GetValueSetI("Seed", "Seed", rnd.randInt());
-
- InitBiomeGen(a_IniFile);
- InitHeightGen(a_IniFile);
- InitCompositionGen(a_IniFile);
- InitStructureGens(a_IniFile);
- InitFinishGens(a_IniFile);
-
- a_IniFile.WriteFile();
-
- return super::Start();
-}
-
-
-
-
-
-void cChunkGenerator::Stop(void)
-{
- m_ShouldTerminate = true;
- m_Event.Set();
- m_evtRemoved.Set(); // Wake up anybody waiting for empty queue
- Wait();
-
- // Delete the generating composition:
- for (cFinishGenList::const_iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr)
- {
- delete *itr;
- }
- m_FinishGens.clear();
- for (cStructureGenList::const_iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr)
- {
- delete *itr;
- }
- m_StructureGens.clear();
- delete m_CompositionGen;
- m_CompositionGen = NULL;
- delete m_HeightGen;
- m_HeightGen = NULL;
- delete m_BiomeGen;
- m_BiomeGen = NULL;
-}
-
-
-
-
-
-void cChunkGenerator::InitBiomeGen(cIniFile & a_IniFile)
-{
- AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", "");
- if (BiomeGenName.empty())
- {
- LOGWARN("[Generator]::BiomeGen value not found in world.ini, using \"DistortedVoronoi\".");
- BiomeGenName = "DistortedVoronoi";
- }
-
- bool CacheOffByDefault = false;
- if (NoCaseCompare(BiomeGenName, "constant") == 0)
- {
- AString Biome = a_IniFile.GetValueSet("Generator", "ConstantBiome", "Plains");
- EMCSBiome b = StringToBiome(Biome);
- if (b == -1)
- {
- LOGWARN("[Generator]::ConstantBiome value \"%s\" not recognized, using \"Plains\".", Biome.c_str());
- b = biPlains;
- }
- m_BiomeGen = new cBioGenConstant(b);
- CacheOffByDefault = true; // we're generating faster than a cache would retrieve data :)
- }
- else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0)
- {
- int BiomeSize = a_IniFile.GetValueSetI("Generator", "CheckerboardBiomeSize", 64);
- AString Biomes = a_IniFile.GetValueSet ("Generator", "CheckerBoardBiomes", "");
- m_BiomeGen = new cBioGenCheckerboard(BiomeSize, Biomes);
- CacheOffByDefault = true; // we're (probably) generating faster than a cache would retrieve data
- }
- else if (NoCaseCompare(BiomeGenName, "voronoi") == 0)
- {
- int CellSize = a_IniFile.GetValueSetI("Generator", "VoronoiCellSize", 64);
- AString Biomes = a_IniFile.GetValueSet ("Generator", "VoronoiBiomes", "");
- m_BiomeGen = new cBioGenVoronoi(m_Seed, CellSize, Biomes);
- }
- else
- {
- if (NoCaseCompare(BiomeGenName, "distortedvoronoi") != 0)
- {
- LOGWARNING("Unknown BiomeGen \"%s\", using \"DistortedVoronoi\" instead.", BiomeGenName.c_str());
- }
- int CellSize = a_IniFile.GetValueSetI("Generator", "DistortedVoronoiCellSize", 96);
- AString Biomes = a_IniFile.GetValueSet ("Generator", "DistortedVoronoiBiomes", "");
- m_BiomeGen = new cBioGenDistortedVoronoi(m_Seed, CellSize, Biomes);
- }
-
- // Add a cache, if requested:
- int CacheSize = a_IniFile.GetValueSetI("Generator", "BiomeGenCacheSize", CacheOffByDefault ? 0 : 64);
- if (CacheSize > 0)
- {
- if (CacheSize < 4)
- {
- LOGWARNING("Biomegen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d",
- CacheSize, 4
- );
- CacheSize = 4;
- }
- LOGINFO("Using a cache for biomegen of size %d.", CacheSize);
- m_BiomeGen = new cBioGenCache(m_BiomeGen, CacheSize);
- }
-}
-
-
-
-
-
-void cChunkGenerator::InitHeightGen(cIniFile & a_IniFile)
-{
- AString HeightGenName = a_IniFile.GetValueSet("Generator", "HeightGen", "");
- if (HeightGenName.empty())
- {
- LOGWARN("[Generator]::HeightGen value not found in world.ini, using \"Biomal\".");
- HeightGenName = "Biomal";
- }
-
- bool CacheOffByDefault = false;
- if (NoCaseCompare(HeightGenName, "flat") == 0)
- {
- int Height = a_IniFile.GetValueSetI("Generator", "FlatHeight", 5);
- m_HeightGen = new cHeiGenFlat(Height);
- CacheOffByDefault = true; // We're generating faster than a cache would retrieve data
- }
- else if (NoCaseCompare(HeightGenName, "classic") == 0)
- {
- // These used to be in terrain.ini, but now they are in world.ini (so that multiple worlds can have different values):
- float HeightFreq1 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq1", 0.1);
- float HeightFreq2 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq2", 1.0);
- float HeightFreq3 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq3", 2.0);
- float HeightAmp1 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp1", 1.0);
- float HeightAmp2 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp2", 0.5);
- float HeightAmp3 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp3", 0.5);
- m_HeightGen = new cHeiGenClassic(m_Seed, HeightFreq1, HeightAmp1, HeightFreq2, HeightAmp2, HeightFreq3, HeightAmp3);
- }
- else // "biomal" or <not found>
- {
- if (NoCaseCompare(HeightGenName, "biomal") != 0)
- {
- LOGWARN("Unknown HeightGen \"%s\", using \"Biomal\" instead.", HeightGenName.c_str());
- }
- m_HeightGen = new cHeiGenBiomal(m_Seed, *m_BiomeGen);
- }
-
- // Add a cache, if requested:
- int CacheSize = a_IniFile.GetValueSetI("Generator", "HeightGenCacheSize", CacheOffByDefault ? 0 : 64);
- if (CacheSize > 0)
- {
- if (CacheSize < 4)
- {
- LOGWARNING("Heightgen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d",
- CacheSize, 4
- );
- CacheSize = 4;
- }
- LOGINFO("Using a cache for Heightgen of size %d.", CacheSize);
- m_HeightGen = new cHeiGenCache(m_HeightGen, CacheSize);
- }
-}
-
-
-
-
-
-void cChunkGenerator::InitCompositionGen(cIniFile & a_IniFile)
-{
- AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", "");
- if (CompoGenName.empty())
- {
- LOGWARN("[Generator]::CompositionGen value not found in world.ini, using \"Biomal\".");
- CompoGenName = "Biomal";
- }
- if (NoCaseCompare(CompoGenName, "sameblock") == 0)
- {
- AString BlockType = a_IniFile.GetValueSet("Generator", "SameBlockType", "");
- if (BlockType.empty())
- {
- LOGWARN("[Generator]::SameBlockType value not found in world.ini, using \"stone\".");
- BlockType = "stone";
- }
- int Block = GetIniBlock(a_IniFile, "[Generator]", "SameBlockType", "stone");
- bool Bedrocked = (a_IniFile.GetValueSetI("Generator", "SameBlockBedrocked", 1) != 0);
- m_CompositionGen = new cCompoGenSameBlock((BLOCKTYPE)Block, Bedrocked);
- }
- else if (NoCaseCompare(CompoGenName, "debugbiomes") == 0)
- {
- m_CompositionGen = new cCompoGenDebugBiomes;
- }
- else if (NoCaseCompare(CompoGenName, "classic") == 0)
- {
- int SeaLevel = a_IniFile.GetValueSetI("Generator", "ClassicSeaLevel", 60);
- int BeachHeight = a_IniFile.GetValueSetI("Generator", "ClassicBeachHeight", 2);
- int BeachDepth = a_IniFile.GetValueSetI("Generator", "ClassicBeachDepth", 4);
- BLOCKTYPE BlockTop = GetIniBlock(a_IniFile, "Generator", "ClassicBlockTop", "grass");
- BLOCKTYPE BlockMiddle = GetIniBlock(a_IniFile, "Generator", "ClassicBlockMiddle", "dirt");
- BLOCKTYPE BlockBottom = GetIniBlock(a_IniFile, "Generator", "ClassicBlockBottom", "stone");
- BLOCKTYPE BlockBeach = GetIniBlock(a_IniFile, "Generator", "ClassicBlockBeach", "sand");
- BLOCKTYPE BlockBeachBottom = GetIniBlock(a_IniFile, "Generator", "ClassicBlockBeachBottom", "sandstone");
- BLOCKTYPE BlockSea = GetIniBlock(a_IniFile, "Generator", "ClassicBlockSea", "9");
- m_CompositionGen = new cCompoGenClassic(
- SeaLevel, BeachHeight, BeachDepth, BlockTop, BlockMiddle, BlockBottom, BlockBeach,
- BlockBeachBottom, BlockSea
- );
- }
- else
- {
- if (NoCaseCompare(CompoGenName, "biomal") != 0)
- {
- LOGWARN("Unknown CompositionGen \"%s\", using \"biomal\" instead.", CompoGenName.c_str());
- }
- int SeaLevel = a_IniFile.GetValueSetI("Generator", "BiomalSeaLevel", 62);
- m_CompositionGen = new cCompoGenBiomal(m_Seed, SeaLevel);
- }
-}
-
-
-
-
-
-void cChunkGenerator::InitStructureGens(cIniFile & a_IniFile)
-{
- AString Structures = a_IniFile.GetValueSet("Generator", "Structures", "Trees,MarbleCaves,OreNests");
-
- AStringVector Str = StringSplit(Structures, ",");
- for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr)
- {
- if (NoCaseCompare(*itr, "trees") == 0)
- {
- m_StructureGens.push_back(new cStructGenTrees(m_Seed, m_BiomeGen, m_HeightGen, m_CompositionGen));
- }
- else if (NoCaseCompare(*itr, "marblecaves") == 0)
- {
- m_StructureGens.push_back(new cStructGenMarbleCaves(m_Seed));
- }
- else if (NoCaseCompare(*itr, "orenests") == 0)
- {
- m_StructureGens.push_back(new cStructGenOreNests(m_Seed));
- }
- else
- {
- LOGWARNING("Unknown structure generator: \"%s\". Ignoring.", itr->c_str());
- }
- } // for itr - Str[]
-}
-
-
-
-
-
-void cChunkGenerator::InitFinishGens(cIniFile & a_IniFile)
-{
- AString Structures = a_IniFile.GetValueSet("Generator", "Finishers", "SprinkleFoliage,Ice,Snow");
-
- AStringVector Str = StringSplit(Structures, ",");
- for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr)
- {
- if (NoCaseCompare(*itr, "SprinkleFoliage") == 0)
- {
- m_FinishGens.push_back(new cFinishGenSprinkleFoliage(m_Seed));
- }
- else if (NoCaseCompare(*itr, "Snow") == 0)
- {
- m_FinishGens.push_back(new cFinishGenSnow);
- }
- else if (NoCaseCompare(*itr, "Ice") == 0)
- {
- m_FinishGens.push_back(new cFinishGenIce);
- }
- } // for itr - Str[]
-}
-
-
-
-
-
-void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- {
- cCSLock Lock(m_CS);
-
- // Check if it is already in the queue:
- for (cChunkCoordsList::iterator itr = m_Queue.begin(); itr != m_Queue.end(); ++itr)
- {
- if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ))
- {
- // Already in the queue, bail out
- return;
- }
- } // for itr - m_Queue[]
-
- // Add to queue, issue a warning if too many:
- if (m_Queue.size() >= QUEUE_WARNING_LIMIT)
- {
- LOGWARN("WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (%i)", a_ChunkX, a_ChunkZ, m_Queue.size());
- }
- m_Queue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
- }
-
- m_Event.Set();
-}
-
-
-
-
-
-void cChunkGenerator::GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
-{
- m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap);
-}
-
-
-
-
-
-void cChunkGenerator::WaitForQueueEmpty(void)
-{
- cCSLock Lock(m_CS);
- while (!m_ShouldTerminate && !m_Queue.empty())
- {
- cCSUnlock Unlock(Lock);
- m_evtRemoved.Wait();
- }
-}
-
-
-
-
-
-int cChunkGenerator::GetQueueLength(void)
-{
- cCSLock Lock(m_CS);
- return (int)m_Queue.size();
-}
-
-
-
-
-
-EMCSBiome cChunkGenerator::GetBiomeAt(int a_BlockX, int a_BlockZ)
-{
- cChunkDef::BiomeMap Biomes;
- int Y = 0;
- int ChunkX, ChunkZ;
- cWorld::AbsoluteToRelative(a_BlockX, Y, a_BlockZ, ChunkX, Y, ChunkZ);
- m_BiomeGen->GenBiomes(ChunkX, ChunkZ, Biomes);
- return cChunkDef::GetBiome(Biomes, a_BlockX, a_BlockZ);
-}
-
-
-
-
-
-void cChunkGenerator::Execute(void)
-{
- while (!m_ShouldTerminate)
- {
- cCSLock Lock(m_CS);
- while (m_Queue.size() == 0)
- {
- cCSUnlock Unlock(Lock);
- m_Event.Wait();
- if (m_ShouldTerminate)
- {
- return;
- }
- }
-
- cChunkCoords coords = m_Queue.front(); // Get next coord from queue
- m_Queue.erase( m_Queue.begin() ); // Remove coordinate from queue
- bool SkipEnabled = (m_Queue.size() > QUEUE_SKIP_LIMIT);
- Lock.Unlock(); // Unlock ASAP
- m_evtRemoved.Set();
-
- // Hack for regenerating chunks: if Y != 0, the chunk is considered invalid, even if it has its data set
- if ((coords.m_ChunkY == 0) && m_World->IsChunkValid(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ))
- {
- LOGD("Chunk [%d, %d] already generated, skipping generation", coords.m_ChunkX, coords.m_ChunkZ);
- // Already generated, ignore request
- continue;
- }
-
- if (SkipEnabled && !m_World->HasChunkAnyClients(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ))
- {
- LOGWARNING("Chunk generator overloaded, skipping chunk [%d, %d, %d]", coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ);
- continue;
- }
-
- LOGD("Generating chunk [%d, %d, %d]", coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ);
- DoGenerate(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ);
-
- // Save the chunk right after generating, so that we don't have to generate it again on next run
- m_World->GetStorage().QueueSaveChunk(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ);
- } // while (!bStop)
-}
-
-
-
-
-void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- cChunkDef::BiomeMap BiomeMap;
- cChunkDef::BlockTypes BlockTypes;
- cChunkDef::BlockNibbles BlockMeta;
- cChunkDef::HeightMap HeightMap;
- cEntityList Entities;
- cBlockEntityList BlockEntities;
-
- cLuaChunk LuaChunk( BlockTypes, BlockMeta, HeightMap, BiomeMap );
- if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_CHUNK_GENERATING, 3, a_ChunkX, a_ChunkZ, &LuaChunk ) )
- {
- // A plugin interrupted generation, handle something plugin specific
- if( LuaChunk.IsUsingDefaultBiomes() )
- {
- m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, BiomeMap);
- }
- if( LuaChunk.IsUsingDefaultComposition() )
- {
- m_CompositionGen->ComposeTerrain(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities);
- }
- if( LuaChunk.IsUsingDefaultStructures() )
- {
- for (cStructureGenList::iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr)
- {
- (*itr)->GenStructures(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, Entities, BlockEntities);
- } // for itr - m_StructureGens[]
- }
- if( LuaChunk.IsUsingDefaultFinish() )
- {
- for (cFinishGenList::iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr)
- {
- (*itr)->GenFinish(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities);
- } // for itr - m_FinishGens[]
- }
- }
- else
- {
- // Use the composed generator:
- m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, BiomeMap);
- m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, HeightMap);
- m_CompositionGen->ComposeTerrain(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities);
- for (cStructureGenList::iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr)
- {
- (*itr)->GenStructures(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, Entities, BlockEntities);
- } // for itr - m_StructureGens[]
- for (cFinishGenList::iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr)
- {
- (*itr)->GenFinish(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities);
- } // for itr - m_FinishGens[]
- }
-
- m_World->SetChunkData(
- a_ChunkX, a_ChunkY, a_ChunkZ,
- BlockTypes, BlockMeta,
- NULL, NULL, // We don't have lighting, chunk will be lighted when needed
- &HeightMap, &BiomeMap,
- Entities, BlockEntities,
- true
- );
-
- cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_CHUNK_GENERATED, 3, m_World, a_ChunkX, a_ChunkZ);
-}
-
-
-
-
+ +#include "Globals.h" + +#include "cChunkGenerator.h" +#include "cWorld.h" +#include "../iniFile/iniFile.h" +#include "BioGen.h" +#include "HeiGen.h" +#include "CompoGen.h" +#include "StructGen.h" +#include "FinishGen.h" +#include "cRoot.h" +#include "cPluginManager.h" +#include "cLuaChunk.h" + + + + + +/// If the generation queue size exceeds this number, a warning will be output +const int QUEUE_WARNING_LIMIT = 1000; + +/// If the generation queue size exceeds this number, chunks with no clients will be skipped +const int QUEUE_SKIP_LIMIT = 500; + + + + + +static BLOCKTYPE GetIniBlock(cIniFile & a_IniFile, const AString & a_SectionName, const AString & a_ValueName, const AString & a_Default) +{ + AString BlockType = a_IniFile.GetValueSet(a_SectionName, a_ValueName, a_Default); + BLOCKTYPE Block = BlockStringToType(BlockType); + if (Block < 0) + { + LOGWARN("[&s].%s Could not parse block value \"%s\". Using default: \"%s\".", a_SectionName.c_str(), a_ValueName.c_str(), BlockType.c_str(),a_Default.c_str()); + return BlockStringToType(a_Default); + } + return Block; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cChunkGenerator: + +cChunkGenerator::cChunkGenerator(void) + : super("cChunkGenerator") + , m_World(NULL) + , m_BiomeGen(NULL) + , m_HeightGen(NULL) + , m_CompositionGen(NULL) +{ +} + + + + + +cChunkGenerator::~cChunkGenerator() +{ + Stop(); +} + + + + + +bool cChunkGenerator::Start(cWorld * a_World, cIniFile & a_IniFile) +{ + MTRand rnd; + m_World = a_World; + m_Seed = a_IniFile.GetValueSetI("Seed", "Seed", rnd.randInt()); + + InitBiomeGen(a_IniFile); + InitHeightGen(a_IniFile); + InitCompositionGen(a_IniFile); + InitStructureGens(a_IniFile); + InitFinishGens(a_IniFile); + + a_IniFile.WriteFile(); + + return super::Start(); +} + + + + + +void cChunkGenerator::Stop(void) +{ + m_ShouldTerminate = true; + m_Event.Set(); + m_evtRemoved.Set(); // Wake up anybody waiting for empty queue + Wait(); + + // Delete the generating composition: + for (cFinishGenList::const_iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr) + { + delete *itr; + } + m_FinishGens.clear(); + for (cStructureGenList::const_iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr) + { + delete *itr; + } + m_StructureGens.clear(); + delete m_CompositionGen; + m_CompositionGen = NULL; + delete m_HeightGen; + m_HeightGen = NULL; + delete m_BiomeGen; + m_BiomeGen = NULL; +} + + + + + +void cChunkGenerator::InitBiomeGen(cIniFile & a_IniFile) +{ + AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", ""); + if (BiomeGenName.empty()) + { + LOGWARN("[Generator]::BiomeGen value not found in world.ini, using \"DistortedVoronoi\"."); + BiomeGenName = "DistortedVoronoi"; + } + + bool CacheOffByDefault = false; + if (NoCaseCompare(BiomeGenName, "constant") == 0) + { + AString Biome = a_IniFile.GetValueSet("Generator", "ConstantBiome", "Plains"); + EMCSBiome b = StringToBiome(Biome); + if (b == -1) + { + LOGWARN("[Generator]::ConstantBiome value \"%s\" not recognized, using \"Plains\".", Biome.c_str()); + b = biPlains; + } + m_BiomeGen = new cBioGenConstant(b); + CacheOffByDefault = true; // we're generating faster than a cache would retrieve data :) + } + else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0) + { + int BiomeSize = a_IniFile.GetValueSetI("Generator", "CheckerboardBiomeSize", 64); + AString Biomes = a_IniFile.GetValueSet ("Generator", "CheckerBoardBiomes", ""); + m_BiomeGen = new cBioGenCheckerboard(BiomeSize, Biomes); + CacheOffByDefault = true; // we're (probably) generating faster than a cache would retrieve data + } + else if (NoCaseCompare(BiomeGenName, "voronoi") == 0) + { + int CellSize = a_IniFile.GetValueSetI("Generator", "VoronoiCellSize", 64); + AString Biomes = a_IniFile.GetValueSet ("Generator", "VoronoiBiomes", ""); + m_BiomeGen = new cBioGenVoronoi(m_Seed, CellSize, Biomes); + } + else + { + if (NoCaseCompare(BiomeGenName, "distortedvoronoi") != 0) + { + LOGWARNING("Unknown BiomeGen \"%s\", using \"DistortedVoronoi\" instead.", BiomeGenName.c_str()); + } + int CellSize = a_IniFile.GetValueSetI("Generator", "DistortedVoronoiCellSize", 96); + AString Biomes = a_IniFile.GetValueSet ("Generator", "DistortedVoronoiBiomes", ""); + m_BiomeGen = new cBioGenDistortedVoronoi(m_Seed, CellSize, Biomes); + } + + // Add a cache, if requested: + int CacheSize = a_IniFile.GetValueSetI("Generator", "BiomeGenCacheSize", CacheOffByDefault ? 0 : 64); + if (CacheSize > 0) + { + if (CacheSize < 4) + { + LOGWARNING("Biomegen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d", + CacheSize, 4 + ); + CacheSize = 4; + } + LOGINFO("Using a cache for biomegen of size %d.", CacheSize); + m_BiomeGen = new cBioGenCache(m_BiomeGen, CacheSize); + } +} + + + + + +void cChunkGenerator::InitHeightGen(cIniFile & a_IniFile) +{ + AString HeightGenName = a_IniFile.GetValueSet("Generator", "HeightGen", ""); + if (HeightGenName.empty()) + { + LOGWARN("[Generator]::HeightGen value not found in world.ini, using \"Biomal\"."); + HeightGenName = "Biomal"; + } + + bool CacheOffByDefault = false; + if (NoCaseCompare(HeightGenName, "flat") == 0) + { + int Height = a_IniFile.GetValueSetI("Generator", "FlatHeight", 5); + m_HeightGen = new cHeiGenFlat(Height); + CacheOffByDefault = true; // We're generating faster than a cache would retrieve data + } + else if (NoCaseCompare(HeightGenName, "classic") == 0) + { + // These used to be in terrain.ini, but now they are in world.ini (so that multiple worlds can have different values): + float HeightFreq1 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq1", 0.1); + float HeightFreq2 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq2", 1.0); + float HeightFreq3 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq3", 2.0); + float HeightAmp1 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp1", 1.0); + float HeightAmp2 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp2", 0.5); + float HeightAmp3 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp3", 0.5); + m_HeightGen = new cHeiGenClassic(m_Seed, HeightFreq1, HeightAmp1, HeightFreq2, HeightAmp2, HeightFreq3, HeightAmp3); + } + else // "biomal" or <not found> + { + if (NoCaseCompare(HeightGenName, "biomal") != 0) + { + LOGWARN("Unknown HeightGen \"%s\", using \"Biomal\" instead.", HeightGenName.c_str()); + } + m_HeightGen = new cHeiGenBiomal(m_Seed, *m_BiomeGen); + } + + // Add a cache, if requested: + int CacheSize = a_IniFile.GetValueSetI("Generator", "HeightGenCacheSize", CacheOffByDefault ? 0 : 64); + if (CacheSize > 0) + { + if (CacheSize < 4) + { + LOGWARNING("Heightgen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d", + CacheSize, 4 + ); + CacheSize = 4; + } + LOGINFO("Using a cache for Heightgen of size %d.", CacheSize); + m_HeightGen = new cHeiGenCache(m_HeightGen, CacheSize); + } +} + + + + + +void cChunkGenerator::InitCompositionGen(cIniFile & a_IniFile) +{ + AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", ""); + if (CompoGenName.empty()) + { + LOGWARN("[Generator]::CompositionGen value not found in world.ini, using \"Biomal\"."); + CompoGenName = "Biomal"; + } + if (NoCaseCompare(CompoGenName, "sameblock") == 0) + { + AString BlockType = a_IniFile.GetValueSet("Generator", "SameBlockType", ""); + if (BlockType.empty()) + { + LOGWARN("[Generator]::SameBlockType value not found in world.ini, using \"stone\"."); + BlockType = "stone"; + } + int Block = GetIniBlock(a_IniFile, "[Generator]", "SameBlockType", "stone"); + bool Bedrocked = (a_IniFile.GetValueSetI("Generator", "SameBlockBedrocked", 1) != 0); + m_CompositionGen = new cCompoGenSameBlock((BLOCKTYPE)Block, Bedrocked); + } + else if (NoCaseCompare(CompoGenName, "debugbiomes") == 0) + { + m_CompositionGen = new cCompoGenDebugBiomes; + } + else if (NoCaseCompare(CompoGenName, "classic") == 0) + { + int SeaLevel = a_IniFile.GetValueSetI("Generator", "ClassicSeaLevel", 60); + int BeachHeight = a_IniFile.GetValueSetI("Generator", "ClassicBeachHeight", 2); + int BeachDepth = a_IniFile.GetValueSetI("Generator", "ClassicBeachDepth", 4); + BLOCKTYPE BlockTop = GetIniBlock(a_IniFile, "Generator", "ClassicBlockTop", "grass"); + BLOCKTYPE BlockMiddle = GetIniBlock(a_IniFile, "Generator", "ClassicBlockMiddle", "dirt"); + BLOCKTYPE BlockBottom = GetIniBlock(a_IniFile, "Generator", "ClassicBlockBottom", "stone"); + BLOCKTYPE BlockBeach = GetIniBlock(a_IniFile, "Generator", "ClassicBlockBeach", "sand"); + BLOCKTYPE BlockBeachBottom = GetIniBlock(a_IniFile, "Generator", "ClassicBlockBeachBottom", "sandstone"); + BLOCKTYPE BlockSea = GetIniBlock(a_IniFile, "Generator", "ClassicBlockSea", "9"); + m_CompositionGen = new cCompoGenClassic( + SeaLevel, BeachHeight, BeachDepth, BlockTop, BlockMiddle, BlockBottom, BlockBeach, + BlockBeachBottom, BlockSea + ); + } + else + { + if (NoCaseCompare(CompoGenName, "biomal") != 0) + { + LOGWARN("Unknown CompositionGen \"%s\", using \"biomal\" instead.", CompoGenName.c_str()); + } + int SeaLevel = a_IniFile.GetValueSetI("Generator", "BiomalSeaLevel", 62); + m_CompositionGen = new cCompoGenBiomal(m_Seed, SeaLevel); + } +} + + + + + +void cChunkGenerator::InitStructureGens(cIniFile & a_IniFile) +{ + AString Structures = a_IniFile.GetValueSet("Generator", "Structures", "Trees,MarbleCaves,OreNests"); + + AStringVector Str = StringSplit(Structures, ","); + for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) + { + if (NoCaseCompare(*itr, "trees") == 0) + { + m_StructureGens.push_back(new cStructGenTrees(m_Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); + } + else if (NoCaseCompare(*itr, "marblecaves") == 0) + { + m_StructureGens.push_back(new cStructGenMarbleCaves(m_Seed)); + } + else if (NoCaseCompare(*itr, "orenests") == 0) + { + m_StructureGens.push_back(new cStructGenOreNests(m_Seed)); + } + else + { + LOGWARNING("Unknown structure generator: \"%s\". Ignoring.", itr->c_str()); + } + } // for itr - Str[] +} + + + + + +void cChunkGenerator::InitFinishGens(cIniFile & a_IniFile) +{ + AString Structures = a_IniFile.GetValueSet("Generator", "Finishers", "SprinkleFoliage,Ice,Snow"); + + AStringVector Str = StringSplit(Structures, ","); + for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) + { + if (NoCaseCompare(*itr, "SprinkleFoliage") == 0) + { + m_FinishGens.push_back(new cFinishGenSprinkleFoliage(m_Seed)); + } + else if (NoCaseCompare(*itr, "Snow") == 0) + { + m_FinishGens.push_back(new cFinishGenSnow); + } + else if (NoCaseCompare(*itr, "Ice") == 0) + { + m_FinishGens.push_back(new cFinishGenIce); + } + } // for itr - Str[] +} + + + + + +void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + { + cCSLock Lock(m_CS); + + // Check if it is already in the queue: + for (cChunkCoordsList::iterator itr = m_Queue.begin(); itr != m_Queue.end(); ++itr) + { + if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ)) + { + // Already in the queue, bail out + return; + } + } // for itr - m_Queue[] + + // Add to queue, issue a warning if too many: + if (m_Queue.size() >= QUEUE_WARNING_LIMIT) + { + LOGWARN("WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (%i)", a_ChunkX, a_ChunkZ, m_Queue.size()); + } + m_Queue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + } + + m_Event.Set(); +} + + + + + +void cChunkGenerator::GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) +{ + m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); +} + + + + + +void cChunkGenerator::WaitForQueueEmpty(void) +{ + cCSLock Lock(m_CS); + while (!m_ShouldTerminate && !m_Queue.empty()) + { + cCSUnlock Unlock(Lock); + m_evtRemoved.Wait(); + } +} + + + + + +int cChunkGenerator::GetQueueLength(void) +{ + cCSLock Lock(m_CS); + return (int)m_Queue.size(); +} + + + + + +EMCSBiome cChunkGenerator::GetBiomeAt(int a_BlockX, int a_BlockZ) +{ + cChunkDef::BiomeMap Biomes; + int Y = 0; + int ChunkX, ChunkZ; + cWorld::AbsoluteToRelative(a_BlockX, Y, a_BlockZ, ChunkX, Y, ChunkZ); + m_BiomeGen->GenBiomes(ChunkX, ChunkZ, Biomes); + return cChunkDef::GetBiome(Biomes, a_BlockX, a_BlockZ); +} + + + + + +void cChunkGenerator::Execute(void) +{ + while (!m_ShouldTerminate) + { + cCSLock Lock(m_CS); + while (m_Queue.size() == 0) + { + cCSUnlock Unlock(Lock); + m_Event.Wait(); + if (m_ShouldTerminate) + { + return; + } + } + + cChunkCoords coords = m_Queue.front(); // Get next coord from queue + m_Queue.erase( m_Queue.begin() ); // Remove coordinate from queue + bool SkipEnabled = (m_Queue.size() > QUEUE_SKIP_LIMIT); + Lock.Unlock(); // Unlock ASAP + m_evtRemoved.Set(); + + // Hack for regenerating chunks: if Y != 0, the chunk is considered invalid, even if it has its data set + if ((coords.m_ChunkY == 0) && m_World->IsChunkValid(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ)) + { + LOGD("Chunk [%d, %d] already generated, skipping generation", coords.m_ChunkX, coords.m_ChunkZ); + // Already generated, ignore request + continue; + } + + if (SkipEnabled && !m_World->HasChunkAnyClients(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ)) + { + LOGWARNING("Chunk generator overloaded, skipping chunk [%d, %d, %d]", coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ); + continue; + } + + LOGD("Generating chunk [%d, %d, %d]", coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ); + DoGenerate(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ); + + // Save the chunk right after generating, so that we don't have to generate it again on next run + m_World->GetStorage().QueueSaveChunk(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ); + } // while (!bStop) +} + + + + +void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cChunkDef::BiomeMap BiomeMap; + cChunkDef::BlockTypes BlockTypes; + cChunkDef::BlockNibbles BlockMeta; + cChunkDef::HeightMap HeightMap; + cEntityList Entities; + cBlockEntityList BlockEntities; + + cLuaChunk LuaChunk( BlockTypes, BlockMeta, HeightMap, BiomeMap ); + if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_CHUNK_GENERATING, 3, a_ChunkX, a_ChunkZ, &LuaChunk ) ) + { + // A plugin interrupted generation, handle something plugin specific + if( LuaChunk.IsUsingDefaultBiomes() ) + { + m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, BiomeMap); + } + if( LuaChunk.IsUsingDefaultComposition() ) + { + m_CompositionGen->ComposeTerrain(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); + } + if( LuaChunk.IsUsingDefaultStructures() ) + { + for (cStructureGenList::iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr) + { + (*itr)->GenStructures(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, Entities, BlockEntities); + } // for itr - m_StructureGens[] + } + if( LuaChunk.IsUsingDefaultFinish() ) + { + for (cFinishGenList::iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr) + { + (*itr)->GenFinish(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); + } // for itr - m_FinishGens[] + } + } + else + { + // Use the composed generator: + m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, BiomeMap); + m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, HeightMap); + m_CompositionGen->ComposeTerrain(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); + for (cStructureGenList::iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr) + { + (*itr)->GenStructures(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, Entities, BlockEntities); + } // for itr - m_StructureGens[] + for (cFinishGenList::iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr) + { + (*itr)->GenFinish(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); + } // for itr - m_FinishGens[] + } + + m_World->SetChunkData( + a_ChunkX, a_ChunkY, a_ChunkZ, + BlockTypes, BlockMeta, + NULL, NULL, // We don't have lighting, chunk will be lighted when needed + &HeightMap, &BiomeMap, + Entities, BlockEntities, + true + ); + + cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_CHUNK_GENERATED, 3, m_World, a_ChunkX, a_ChunkZ); +} + + + + diff --git a/source/cChunkGenerator.h b/source/cChunkGenerator.h index 126d94fb8..2faacfd47 100644 --- a/source/cChunkGenerator.h +++ b/source/cChunkGenerator.h @@ -1,226 +1,226 @@ -
-// cChunkGenerator.h
-
-// Interfaces to the cChunkGenerator class representing the thread that generates chunks
-
-/*
-The object takes requests for generating chunks and processes them in a separate thread one by one.
-The requests are not added to the queue if there is already a request with the same coords
-Before generating, the thread checks if the chunk hasn't been already generated.
-It is theoretically possible to have multiple generator threads by having multiple instances of this object,
-but then it MAY happen that the chunk is generated twice.
-If the generator queue is overloaded, the generator skips chunks with no clients in them
-
-Generating works by composing several algorithms:
-Biome, TerrainHeight, TerrainComposition, Ores, Structures and SmallFoliage
-Each algorithm may be chosen from a pool of available algorithms in the same class and combined with others,
-based on user's preferences in the world.ini.
-See http://forum.mc-server.org/showthread.php?tid=409 for details.
-*/
-
-
-
-
-
-#pragma once
-
-#include "cIsThread.h"
-#include "ChunkDef.h"
-
-
-
-
-
-// fwd:
-class cWorld;
-class cIniFile;
-
-// TODO: remove this:
-class cWorldGenerator;
-
-
-
-
-
-/** The interface that a biome generator must implement
-A biome generator takes chunk coords on input and outputs an array of biome indices for that chunk on output.
-The output array is sequenced in the same way as the MapChunk packet's biome data.
-*/
-class cBiomeGen
-{
-public:
- virtual ~cBiomeGen() {} // Force a virtual destructor in descendants
-
- /// Generates biomes for the given chunk
- virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) = 0;
-} ;
-
-
-
-
-
-/** The interface that a terrain height generator must implement
-A terrain height generator takes chunk coords on input and outputs an array of terrain heights for that chunk.
-The output array is sequenced in the same way as the BiomeGen's biome data.
-The generator may request biome information from the underlying BiomeGen, it may even request information for
-other chunks than the one it's currently generating (possibly neighbors - for averaging)
-*/
-class cTerrainHeightGen
-{
-public:
- virtual ~cTerrainHeightGen() {} // Force a virtual destructor in descendants
-
- /// Generates heightmap for the given chunk
- virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) = 0;
-} ;
-
-
-
-
-
-/** The interface that a terrain composition generator must implement
-Terrain composition takes chunk coords on input and outputs the blockdata for that entire chunk, along with
-the list of entities. It is supposed to make use of the underlying TerrainHeightGen and BiomeGen for that purpose,
-but it may request information for other chunks than the one it's currently generating from them.
-*/
-class cTerrainCompositionGen
-{
-public:
- virtual ~cTerrainCompositionGen() {} // Force a virtual destructor in descendants
-
- virtual void ComposeTerrain(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated (the whole array gets initialized, even air)
- cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated (the whole array gets initialized)
- const cChunkDef::HeightMap & a_HeightMap, // The height map to fit
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entitites may be generated along with the terrain
- cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...)
- ) = 0;
-} ;
-
-
-
-
-
-/** The interface that a structure generator must implement
-Structures are generated after the terrain composition took place. It should modify the blocktype data to account
-for whatever structures the generator is generating.
-Note that ores are considered structures too, at least from the interface point of view.
-Also note that a worldgenerator may contain multiple structure generators, one for each type of structure
-*/
-class cStructureGen
-{
-public:
- virtual ~cStructureGen() {} // Force a virtual destructor in descendants
-
- virtual void GenStructures(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change
- cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
- cEntityList & a_Entities, // Entities may be added or deleted
- cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
- ) = 0;
-} ;
-
-typedef std::list<cStructureGen *> cStructureGenList;
-
-
-
-
-
-/** The interface that a finisher must implement
-Finisher implements small additions after all structures have been generated.
-*/
-class cFinishGen
-{
-public:
- virtual ~cFinishGen() {} // Force a virtual destructor in descendants
-
- virtual void GenFinish(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
- cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change
- cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
- const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
- cEntityList & a_Entities, // Entities may be added or deleted
- cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
- ) = 0;
-} ;
-
-typedef std::list<cFinishGen *> cFinishGenList;
-
-
-
-
-
-/// The chunk generator itself
-class cChunkGenerator :
- cIsThread
-{
- typedef cIsThread super;
-
-public:
-
- cChunkGenerator (void);
- ~cChunkGenerator();
-
- bool Start(cWorld * a_World, cIniFile & a_IniFile);
- void Stop(void);
-
- void QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Queues the chunk for generation; removes duplicate requests
-
- /// Generates the biomes for the specified chunk (directly, not in a separate thread)
- void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap);
-
- void WaitForQueueEmpty(void);
-
- int GetQueueLength(void);
-
- int GetSeed(void) const { return m_Seed; }
-
- EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ);
-
-private:
-
- cWorld * m_World;
-
- // The generation composition:
- cBiomeGen * m_BiomeGen;
- cTerrainHeightGen * m_HeightGen;
- cTerrainCompositionGen * m_CompositionGen;
- cStructureGenList m_StructureGens;
- cFinishGenList m_FinishGens;
-
- int m_Seed;
-
- cCriticalSection m_CS;
- cChunkCoordsList m_Queue;
- cEvent m_Event; // Set when an item is added to the queue or the thread should terminate
- cEvent m_evtRemoved; // Set when an item is removed from the queue
-
- /// Reads the biome gen settings from the ini and initializes m_BiomeGen accordingly
- void InitBiomeGen(cIniFile & a_IniFile);
-
- /// Reads the HeightGen settings from the ini and initializes m_HeightGen accordingly
- void InitHeightGen(cIniFile & a_IniFile);
-
- /// Reads the CompositionGen settings from the ini and initializes m_CompositionGen accordingly
- void InitCompositionGen(cIniFile & a_IniFile);
-
- /// Reads the structures to generate from the ini and initializes m_StructureGens accordingly
- void InitStructureGens(cIniFile & a_IniFile);
-
- /// Reads the finishers from the ini and initializes m_FinishGens accordingly
- void InitFinishGens(cIniFile & a_IniFile);
-
- // cIsThread override:
- virtual void Execute(void) override;
-
- void DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-};
-
-
-
-
+ +// cChunkGenerator.h + +// Interfaces to the cChunkGenerator class representing the thread that generates chunks + +/* +The object takes requests for generating chunks and processes them in a separate thread one by one. +The requests are not added to the queue if there is already a request with the same coords +Before generating, the thread checks if the chunk hasn't been already generated. +It is theoretically possible to have multiple generator threads by having multiple instances of this object, +but then it MAY happen that the chunk is generated twice. +If the generator queue is overloaded, the generator skips chunks with no clients in them + +Generating works by composing several algorithms: +Biome, TerrainHeight, TerrainComposition, Ores, Structures and SmallFoliage +Each algorithm may be chosen from a pool of available algorithms in the same class and combined with others, +based on user's preferences in the world.ini. +See http://forum.mc-server.org/showthread.php?tid=409 for details. +*/ + + + + + +#pragma once + +#include "cIsThread.h" +#include "ChunkDef.h" + + + + + +// fwd: +class cWorld; +class cIniFile; + +// TODO: remove this: +class cWorldGenerator; + + + + + +/** The interface that a biome generator must implement +A biome generator takes chunk coords on input and outputs an array of biome indices for that chunk on output. +The output array is sequenced in the same way as the MapChunk packet's biome data. +*/ +class cBiomeGen +{ +public: + virtual ~cBiomeGen() {} // Force a virtual destructor in descendants + + /// Generates biomes for the given chunk + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) = 0; +} ; + + + + + +/** The interface that a terrain height generator must implement +A terrain height generator takes chunk coords on input and outputs an array of terrain heights for that chunk. +The output array is sequenced in the same way as the BiomeGen's biome data. +The generator may request biome information from the underlying BiomeGen, it may even request information for +other chunks than the one it's currently generating (possibly neighbors - for averaging) +*/ +class cTerrainHeightGen +{ +public: + virtual ~cTerrainHeightGen() {} // Force a virtual destructor in descendants + + /// Generates heightmap for the given chunk + virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) = 0; +} ; + + + + + +/** The interface that a terrain composition generator must implement +Terrain composition takes chunk coords on input and outputs the blockdata for that entire chunk, along with +the list of entities. It is supposed to make use of the underlying TerrainHeightGen and BiomeGen for that purpose, +but it may request information for other chunks than the one it's currently generating from them. +*/ +class cTerrainCompositionGen +{ +public: + virtual ~cTerrainCompositionGen() {} // Force a virtual destructor in descendants + + virtual void ComposeTerrain( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated (the whole array gets initialized, even air) + cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated (the whole array gets initialized) + const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) + ) = 0; +} ; + + + + + +/** The interface that a structure generator must implement +Structures are generated after the terrain composition took place. It should modify the blocktype data to account +for whatever structures the generator is generating. +Note that ores are considered structures too, at least from the interface point of view. +Also note that a worldgenerator may contain multiple structure generators, one for each type of structure +*/ +class cStructureGen +{ +public: + virtual ~cStructureGen() {} // Force a virtual destructor in descendants + + virtual void GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) = 0; +} ; + +typedef std::list<cStructureGen *> cStructureGenList; + + + + + +/** The interface that a finisher must implement +Finisher implements small additions after all structures have been generated. +*/ +class cFinishGen +{ +public: + virtual ~cFinishGen() {} // Force a virtual destructor in descendants + + virtual void GenFinish( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) = 0; +} ; + +typedef std::list<cFinishGen *> cFinishGenList; + + + + + +/// The chunk generator itself +class cChunkGenerator : + cIsThread +{ + typedef cIsThread super; + +public: + + cChunkGenerator (void); + ~cChunkGenerator(); + + bool Start(cWorld * a_World, cIniFile & a_IniFile); + void Stop(void); + + void QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Queues the chunk for generation; removes duplicate requests + + /// Generates the biomes for the specified chunk (directly, not in a separate thread) + void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap); + + void WaitForQueueEmpty(void); + + int GetQueueLength(void); + + int GetSeed(void) const { return m_Seed; } + + EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ); + +private: + + cWorld * m_World; + + // The generation composition: + cBiomeGen * m_BiomeGen; + cTerrainHeightGen * m_HeightGen; + cTerrainCompositionGen * m_CompositionGen; + cStructureGenList m_StructureGens; + cFinishGenList m_FinishGens; + + int m_Seed; + + cCriticalSection m_CS; + cChunkCoordsList m_Queue; + cEvent m_Event; // Set when an item is added to the queue or the thread should terminate + cEvent m_evtRemoved; // Set when an item is removed from the queue + + /// Reads the biome gen settings from the ini and initializes m_BiomeGen accordingly + void InitBiomeGen(cIniFile & a_IniFile); + + /// Reads the HeightGen settings from the ini and initializes m_HeightGen accordingly + void InitHeightGen(cIniFile & a_IniFile); + + /// Reads the CompositionGen settings from the ini and initializes m_CompositionGen accordingly + void InitCompositionGen(cIniFile & a_IniFile); + + /// Reads the structures to generate from the ini and initializes m_StructureGens accordingly + void InitStructureGens(cIniFile & a_IniFile); + + /// Reads the finishers from the ini and initializes m_FinishGens accordingly + void InitFinishGens(cIniFile & a_IniFile); + + // cIsThread override: + virtual void Execute(void) override; + + void DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ); +}; + + + + diff --git a/source/cChunkMap.cpp b/source/cChunkMap.cpp index a881c71ef..c2c26bae7 100644 --- a/source/cChunkMap.cpp +++ b/source/cChunkMap.cpp @@ -1,1485 +1,1485 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cChunkMap.h"
-#include "cWorld.h"
-#include "cRoot.h"
-#include "cMakeDir.h"
-#include "cPlayer.h"
-#include "BlockID.h"
-#include "cItem.h"
-#include "cPickup.h"
-#include "cChunk.h"
-#include "Trees.h" // used in cChunkMap::ReplaceTreeBlocks() for tree block discrimination
-
-#ifndef _WIN32
- #include <cstdlib> // abs
-#endif
-
-#include "zlib.h"
-#include <json/json.h>
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// cChunkMap:
-
-cChunkMap::cChunkMap(cWorld * a_World )
- : m_World( a_World )
-{
-}
-
-
-
-
-
-cChunkMap::~cChunkMap()
-{
- cCSLock Lock(m_CSLayers);
- for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
- {
- delete *itr;
- } // for itr - m_Layers[]
-}
-
-
-
-
-
-void cChunkMap::RemoveLayer( cChunkLayer* a_Layer )
-{
- cCSLock Lock(m_CSLayers);
- m_Layers.remove(a_Layer);
-}
-
-
-
-
-
-cChunkMap::cChunkLayer * cChunkMap::GetLayer(int a_LayerX, int a_LayerZ)
-{
- cCSLock Lock(m_CSLayers);
- for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
- {
- if (((*itr)->GetX() == a_LayerX) && ((*itr)->GetZ() == a_LayerZ))
- {
- return *itr;
- }
- }
-
- // Not found, create new:
- cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this);
- if (Layer == NULL)
- {
- LOGERROR("cChunkMap: Cannot create new layer, server out of memory?");
- return NULL;
- }
- m_Layers.push_back(Layer);
- return Layer;
-}
-
-
-
-
-
-cChunkMap::cChunkLayer * cChunkMap::GetLayerForChunk( int a_ChunkX, int a_ChunkZ )
-{
- const int LayerX = (int)(floorf((float)a_ChunkX / (float)(LAYER_SIZE)));
- const int LayerZ = (int)(floorf((float)a_ChunkZ / (float)(LAYER_SIZE)));
- return GetLayer( LayerX, LayerZ );
-}
-
-
-
-
-
-cChunkPtr cChunkMap::GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ )
-{
- // No need to lock m_CSLayers, since it's already locked by the operation that called us
- cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ );
- if (Layer == NULL)
- {
- // An error must have occurred, since layers are automatically created if they don't exist
- return NULL;
- }
-
- cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
- if (Chunk == NULL)
- {
- return NULL;
- }
- if (!(Chunk->IsValid()))
- {
- m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ, true);
- }
- return Chunk;
-}
-
-
-
-
-
-cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkY, int a_ChunkZ )
-{
- // No need to lock m_CSLayers, since it's already locked by the operation that called us
- cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ );
- if (Layer == NULL)
- {
- // An error must have occurred, since layers are automatically created if they don't exist
- return NULL;
- }
-
- cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
- if (Chunk == NULL)
- {
- return NULL;
- }
- if (!(Chunk->IsValid()))
- {
- m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ, false);
- }
-
- return Chunk;
-}
-
-
-
-
-
-cChunkPtr cChunkMap::GetChunkNoLoad( int a_ChunkX, int a_ChunkY, int a_ChunkZ )
-{
- // No need to lock m_CSLayers, since it's already locked by the operation that called us
- cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ );
- if (Layer == NULL)
- {
- // An error must have occurred, since layers are automatically created if they don't exist
- return NULL;
- }
-
- return Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
-}
-
-
-
-
-
-bool cChunkMap::LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta)
-{
- // We already have m_CSLayers locked since this can be called only from within the tick thread
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
- cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if (Chunk == NULL)
- {
- return false;
- }
-
- int Index = cChunkDef::MakeIndexNoCheck(a_BlockX, a_BlockY, a_BlockZ);
- a_BlockType = Chunk->GetBlock(Index);
- a_BlockMeta = Chunk->GetMeta(Index);
- return true;
-}
-
-
-
-
-
-bool cChunkMap::LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
-{
- // We already have m_CSLayers locked since this can be called only from within the tick thread
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
- cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if (Chunk == NULL)
- {
- return false;
- }
-
- Chunk->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
- return true;
-}
-
-
-
-
-
-bool cChunkMap::LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
-{
- // We already have m_CSLayers locked since this can be called only from within the tick thread
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
- cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if (Chunk == NULL)
- {
- return false;
- }
-
- Chunk->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
- return true;
-}
-
-
-
-
-
-void cChunkMap::BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude)
-{
- // Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude
-
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
- if (Chunk == NULL)
- {
- return;
- }
- // It's perfectly legal to broadcast packets even to invalid chunks!
- Chunk->Broadcast(a_Packet, a_Exclude);
-}
-
-
-
-
-
-void cChunkMap::BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, const cPacket * a_Packet, cClientHandle * a_Exclude)
-{
- // Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude
-
- cCSLock Lock(m_CSLayers);
- int ChunkX, ChunkZ;
- cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ);
- cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if (Chunk == NULL)
- {
- return;
- }
- // It's perfectly legal to broadcast packets even to invalid chunks!
- Chunk->Broadcast(a_Packet, a_Exclude);
-}
-
-
-
-
-
-void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z)
-{
- // a_Player rclked block entity at the coords specified, handle it
- cCSLock Lock(m_CSLayers);
- int ChunkX, ChunkZ;
- cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ);
- cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ);
- if ((Chunk == NULL) || !Chunk->IsValid())
- {
- return;
- }
- Chunk->UseBlockEntity(a_Player, a_X, a_Y, a_Z);
-}
-
-
-
-
-
-void cChunkMap::MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
- if ((Chunk == NULL) || !Chunk->IsValid())
- {
- return;
- }
- Chunk->MarkDirty();
-}
-
-
-
-
-
-void cChunkMap::MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
- if ((Chunk == NULL) || !Chunk->IsValid())
- {
- return;
- }
- Chunk->MarkSaving();
-}
-
-
-
-
-
-void cChunkMap::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
- if ((Chunk == NULL) || !Chunk->IsValid())
- {
- return;
- }
- Chunk->MarkSaved();
-}
-
-
-
-
-
-void cChunkMap::SetChunkData(
- int a_ChunkX, int a_ChunkY, int a_ChunkZ,
- const BLOCKTYPE * a_BlockTypes,
- const NIBBLETYPE * a_BlockMeta,
- const NIBBLETYPE * a_BlockLight,
- const NIBBLETYPE * a_BlockSkyLight,
- const cChunkDef::HeightMap * a_HeightMap,
- const cChunkDef::BiomeMap & a_BiomeMap,
- cEntityList & a_Entities,
- cBlockEntityList & a_BlockEntities,
- bool a_MarkDirty
-)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ);
- if (Chunk == NULL)
- {
- return;
- }
- Chunk->SetAllData(a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, a_HeightMap, a_BiomeMap, a_Entities, a_BlockEntities);
- Chunk->SetValid();
-
- if (a_MarkDirty)
- {
- Chunk->MarkDirty();
- }
-}
-
-
-
-
-
-void cChunkMap::ChunkLighted(
- int a_ChunkX, int a_ChunkZ,
- const cChunkDef::BlockNibbles & a_BlockLight,
- const cChunkDef::BlockNibbles & a_SkyLight
-)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
- if (Chunk == NULL)
- {
- return;
- }
- Chunk->SetLight(a_BlockLight, a_SkyLight);
- Chunk->MarkDirty();
-}
-
-
-
-
-
-bool cChunkMap::GetChunkData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
- if ((Chunk == NULL) || !Chunk->IsValid())
- {
- return false;
- }
- Chunk->GetAllData(a_Callback);
- return true;
-}
-
-
-
-
-
-bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
- if ((Chunk == NULL) || !Chunk->IsValid())
- {
- return false;
- }
- Chunk->GetBlockTypes(a_BlockTypes);
- return true;
-}
-
-
-
-
-
-bool cChunkMap::GetChunkBlockData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
- if ((Chunk == NULL) || !Chunk->IsValid())
- {
- return false;
- }
- Chunk->GetBlockData(a_BlockData);
- return true;
-}
-
-
-
-
-
-bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ);
- return (Chunk != NULL) && Chunk->IsValid();
-}
-
-
-
-
-
-bool cChunkMap::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
- return (Chunk != NULL) && Chunk->HasAnyClients();
-}
-
-
-
-
-
-int cChunkMap::GetHeight(int a_BlockX, int a_BlockZ)
-{
- cCSLock Lock(m_CSLayers);
- int ChunkX, ChunkZ, BlockY = 0;
- cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ);
- cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if (Chunk == NULL)
- {
- return 0;
- }
-
- // Wait for the chunk to become valid:
- while (!Chunk->IsValid())
- {
- GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); // Re-queue (in case it managed to get unloaded before we caught it
- cCSUnlock Unlock(Lock);
- m_evtChunkValid.Wait();
- }
-
- return Chunk->GetHeight(a_BlockX, a_BlockZ);
-}
-
-
-
-
-
-void cChunkMap::FastSetBlocks(sSetBlockList & a_BlockList)
-{
- sSetBlockList Failed;
-
- // Process all items from a_BlockList, either successfully or by placing into Failed
- while (!a_BlockList.empty())
- {
- int ChunkX = a_BlockList.front().ChunkX;
- int ChunkZ = a_BlockList.front().ChunkZ;
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if ((Chunk != NULL) && Chunk->IsValid())
- {
- for (sSetBlockList::iterator itr = a_BlockList.begin(); itr != a_BlockList.end();)
- {
- if ((itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ))
- {
- Chunk->FastSetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta);
- itr = a_BlockList.erase(itr);
- }
- else
- {
- ++itr;
- }
- } // for itr - a_BlockList[]
- }
- else
- {
- // The chunk is not valid, move all blocks within this chunk to Failed
- for (sSetBlockList::iterator itr = a_BlockList.begin(); itr != a_BlockList.end();)
- {
- if ((itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ))
- {
- Failed.push_back(*itr);
- itr = a_BlockList.erase(itr);
- }
- else
- {
- ++itr;
- }
- } // for itr - a_BlockList[]
- }
- }
-
- // Return the failed:
- std::swap(Failed, a_BlockList);
-}
-
-
-
-
-
-void cChunkMap::CollectPickupsByPlayer(cPlayer * a_Player)
-{
- int BlockX = (int)(a_Player->GetPosX()); // Truncating doesn't matter much; we're scanning entire chunks anyway
- int BlockY = (int)(a_Player->GetPosY());
- int BlockZ = (int)(a_Player->GetPosZ());
- int ChunkX, ChunkZ, ChunkY = ZERO_CHUNK_Y;
- cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
- int OtherChunkX = ChunkX + ((BlockX > 8) ? 1 : -1);
- int OtherChunkZ = ChunkZ + ((BlockZ > 8) ? 1 : -1);
-
- // We suppose that each player keeps their chunks in memory, therefore it makes little sense to try to re-load or even generate them.
- // The only time the chunks are not valid is when the player is downloading the initial world and they should not call this at that moment
-
- cCSLock Lock(m_CSLayers);
- GetChunkNoLoad(ChunkX, ChunkY, ChunkZ)->CollectPickupsByPlayer(a_Player);
-
- // Check the neighboring chunks as well:
- GetChunkNoLoad(OtherChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player);
- GetChunkNoLoad(OtherChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player);
- GetChunkNoLoad(ChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player);
- GetChunkNoLoad(ChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player);
-}
-
-
-
-
-
-BLOCKTYPE cChunkMap::GetBlock(int a_X, int a_Y, int a_Z)
-{
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ );
-
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if ((Chunk != NULL) && Chunk->IsValid())
- {
- return Chunk->GetBlock(a_X, a_Y, a_Z);
- }
- return 0;
-}
-
-
-
-
-
-BLOCKTYPE cChunkMap::GetBlockMeta(int a_X, int a_Y, int a_Z)
-{
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ );
-
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
- if ((Chunk != NULL) && Chunk->IsValid() )
- {
- return Chunk->GetMeta(a_X, a_Y, a_Z);
- }
- return 0;
-}
-
-
-
-
-
-BLOCKTYPE cChunkMap::GetBlockSkyLight(int a_X, int a_Y, int a_Z)
-{
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ );
-
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
- if ((Chunk != NULL) && Chunk->IsValid() )
- {
- return Chunk->GetSkyLight( a_X, a_Y, a_Z );
- }
- return 0;
-}
-
-
-
-
-
-void cChunkMap::SetBlockMeta(int a_X, int a_Y, int a_Z, char a_BlockMeta)
-{
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ );
-
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
- if ((Chunk != NULL) && Chunk->IsValid() )
- {
- Chunk->SetMeta(a_X, a_Y, a_Z, a_BlockMeta);
- Chunk->MarkDirty();
- Chunk->SendBlockTo( a_X, a_Y, a_Z, NULL );
- }
-}
-
-
-
-
-
-void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta)
-{
- int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ;
- cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ );
-
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
- if ((Chunk != NULL) && Chunk->IsValid())
- {
- Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta );
- }
-}
-
-
-
-
-
-void cChunkMap::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta)
-{
- int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ;
- cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ );
-
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
- if ((Chunk != NULL) && Chunk->IsValid())
- {
- Chunk->GetBlockTypeMeta(X, Y, Z, a_BlockType, a_BlockMeta);
- }
-}
-
-
-
-
-
-void cChunkMap::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType)
-{
- cCSLock Lock(m_CSLayers);
- for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
- {
- cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ );
- if ((Chunk == NULL) || !Chunk->IsValid())
- {
- continue;
- }
- if (Chunk->GetBlock(itr->x, itr->y, itr->z) == a_FilterBlockType)
- {
- Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta);
- }
- }
-}
-
-
-
-
-
-void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks)
-{
- cCSLock Lock(m_CSLayers);
- for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
- {
- cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ );
- if ((Chunk == NULL) || !Chunk->IsValid())
- {
- continue;
- }
- switch (Chunk->GetBlock(itr->x, itr->y, itr->z))
- {
- CASE_TREE_OVERWRITTEN_BLOCKS:
- {
- Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta);
- break;
- }
- }
- } // for itr - a_Blocks[]
-}
-
-
-
-
-
-EMCSBiome cChunkMap::GetBiomeAt (int a_BlockX, int a_BlockZ)
-{
- int ChunkX, ChunkZ, X = a_BlockX, Y = 0, Z = a_BlockZ;
- cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ );
-
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
- if ((Chunk != NULL) && Chunk->IsValid())
- {
- return Chunk->GetBiomeAt(X, Z);
- }
- else
- {
- return m_World->GetGenerator().GetBiomeAt(a_BlockX, a_BlockZ);
- }
-}
-
-
-
-
-
-bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure)
-{
- bool res = true;
- cCSLock Lock(m_CSLayers);
- for (sSetBlockVector::iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
- {
- cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ );
- if ((Chunk == NULL) || !Chunk->IsValid())
- {
- if (!a_ContinueOnFailure)
- {
- return false;
- }
- res = false;
- continue;
- }
- int idx = cChunkDef::MakeIndexNoCheck(itr->x, itr->y, itr->z);
- itr->BlockType = Chunk->GetBlock(idx);
- itr->BlockMeta = Chunk->GetMeta(idx);
- }
- return res;
-}
-
-
-
-
-
-bool cChunkMap::DigBlock(int a_X, int a_Y, int a_Z)
-{
- int PosX = a_X, PosY = a_Y, PosZ = a_Z, ChunkX, ChunkZ;
-
- cChunkDef::AbsoluteToRelative( PosX, PosY, PosZ, ChunkX, ChunkZ );
-
- {
- cCSLock Lock(m_CSLayers);
- cChunkPtr DestChunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
- if ((DestChunk == NULL) || !DestChunk->IsValid())
- {
- return false;
- }
-
- DestChunk->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, 0 );
- }
-
- m_World->GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z);
-
- return true;
-}
-
-
-
-
-
-void cChunkMap::SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player)
-{
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_X, a_Y, a_Z, ChunkX, ChunkZ);
-
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if (Chunk->IsValid())
- {
- Chunk->SendBlockTo(a_X, a_Y, a_Z, a_Player->GetClientHandle());
- }
-}
-
-
-
-
-
-void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk1 = GetChunkNoGen(a_ChunkX1, a_ChunkY1, a_ChunkZ1);
- if (Chunk1 == NULL)
- {
- return;
- }
- cChunkPtr Chunk2 = GetChunkNoGen(a_ChunkX2, a_ChunkY2, a_ChunkZ2);
- if (Chunk2 == NULL)
- {
- return;
- }
-
- cClientHandleList Clients1(Chunk1->GetAllClients());
- cClientHandleList Clients2(Chunk2->GetAllClients());
-
- // Find "removed" clients:
- for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1)
- {
- bool Found = false;
- for (cClientHandleList::iterator itr2 = Clients2.begin(); itr2 != Clients2.end(); ++itr2)
- {
- if (*itr1 == *itr2)
- {
- Found = true;
- break;
- }
- } // for itr2 - Clients2[]
- if (!Found)
- {
- a_Callback.Removed(*itr1);
- }
- } // for itr1 - Clients1[]
-
- // Find "added" clients:
- for (cClientHandleList::iterator itr2 = Clients2.begin(); itr2 != Clients2.end(); ++itr2)
- {
- bool Found = false;
- for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1)
- {
- if (*itr1 == *itr2)
- {
- Found = true;
- break;
- }
- } // for itr1 - Clients1[]
- if (!Found)
- {
- a_Callback.Added(*itr2);
- }
- } // for itr2 - Clients2[]
-}
-
-
-
-
-
-bool cChunkMap::AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
- if (Chunk == NULL)
- {
- return false;
- }
- return Chunk->AddClient(a_Client);
-}
-
-
-
-
-
-void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
- if (Chunk == NULL)
- {
- return;
- }
- Chunk->RemoveClient(a_Client);
-}
-
-
-
-
-
-void cChunkMap::RemoveClientFromChunks(cClientHandle * a_Client)
-{
- cCSLock Lock(m_CSLayers);
-
- for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
- {
- (*itr)->RemoveClient(a_Client);
- } // for itr - m_Layers[]
-}
-
-
-
-
-
-void cChunkMap::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr OldChunk = GetChunkNoGen(a_Entity->GetChunkX(), a_Entity->GetChunkY(), a_Entity->GetChunkZ());
- if (OldChunk != NULL)
- {
- OldChunk->RemoveEntity(a_Entity);
- }
- cChunkPtr NewChunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
- if (NewChunk != NULL)
- {
- NewChunk->AddEntity(a_Entity);
- }
-}
-
-
-
-
-
-void cChunkMap::RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
- if ((Chunk == NULL) && !Chunk->IsValid())
- {
- return;
- }
- Chunk->RemoveEntity(a_Entity);
-}
-
-
-
-
-
-void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- cCSLock Lock(m_CSLayers);
- GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
-}
-
-
-
-
-
-/// Loads the chunk synchronously, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before)
-bool cChunkMap::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- {
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
- if (Chunk == NULL)
- {
- // Internal error
- return false;
- }
- if (Chunk->IsValid())
- {
- // Already loaded
- return true;
- }
- if (Chunk->HasLoadFailed())
- {
- // Already tried loading and it failed
- return false;
- }
- }
- return m_World->GetStorage().LoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
-}
-
-
-
-
-
-/// Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid()
-void cChunkMap::LoadChunks(const cChunkCoordsList & a_Chunks)
-{
- for (cChunkCoordsList::const_iterator itr = a_Chunks.begin(); itr != a_Chunks.end(); ++itr)
- {
- LoadChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ);
- } // for itr - a_Chunks[]
-}
-
-
-
-
-
-void cChunkMap::ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ);
- if (Chunk == NULL)
- {
- return;
- }
- Chunk->MarkLoadFailed();
-}
-
-
-
-
-
-void cChunkMap::UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4)
-{
- cCSLock Lock(m_CSLayers);
- int ChunkX, ChunkZ;
- cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ);
- cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if ((Chunk == NULL) || !Chunk->IsValid())
- {
- return;
- }
- Chunk->UpdateSign(a_X, a_Y, a_Z, a_Line1, a_Line2, a_Line3, a_Line4);
-}
-
-
-
-
-
-void cChunkMap::ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay)
-{
- cCSLock Lock(m_CSLayers);
- for (cChunkCoordsList::const_iterator itr = a_Chunks.begin(); itr != a_Chunks.end(); ++itr)
- {
- cChunkPtr Chunk = GetChunkNoLoad(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ);
- if (Chunk == NULL)
- {
- continue;
- }
- Chunk->Stay(a_Stay);
- }
-}
-
-
-
-
-
-void cChunkMap::MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
- if (Chunk == NULL)
- {
- // Not present
- return;
- }
- Chunk->MarkRegenerating();
-}
-
-
-
-
-
-bool cChunkMap::IsChunkLighted(int a_ChunkX, int a_ChunkZ)
-{
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
- if (Chunk == NULL)
- {
- // Not present
- return false;
- }
- return Chunk->IsLightValid();
-}
-
-
-
-
-
-void cChunkMap::GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty)
-{
- a_NumChunksValid = 0;
- a_NumChunksDirty = 0;
- cCSLock Lock(m_CSLayers);
- for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
- {
- int NumValid = 0, NumDirty = 0;
- (*itr)->GetChunkStats(NumValid, NumDirty);
- a_NumChunksValid += NumValid;
- a_NumChunksDirty += NumDirty;
- } // for itr - m_Layers[]
-}
-
-
-
-
-
-void cChunkMap::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, MTRand & a_Rand)
-{
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
-
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if (Chunk != NULL)
- {
- Chunk->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_Rand);
- }
-}
-
-
-
-
-
-void cChunkMap::GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow)
-{
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
-
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if (Chunk != NULL)
- {
- Chunk->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, a_NumBlocksToGrow);
- }
-}
-
-
-
-
-
-void cChunkMap::GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow)
-{
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
-
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if (Chunk != NULL)
- {
- Chunk->GrowCactus(a_BlockX, a_BlockY, a_BlockZ, a_NumBlocksToGrow);
- }
-}
-
-
-
-
-
-void cChunkMap::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ)
-{
- int ChunkX, ChunkZ;
- cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
-
- cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ);
- if (Chunk != NULL)
- {
- Chunk->SetNextBlockTick(a_BlockX, a_BlockY, a_BlockZ);
- }
-}
-
-
-
-
-
-void cChunkMap::Tick( float a_Dt, MTRand & a_TickRandom )
-{
- cCSLock Lock(m_CSLayers);
- for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
- {
- (*itr)->Tick(a_Dt, a_TickRandom);
- } // for itr - m_Layers
-}
-
-
-
-
-
-void cChunkMap::UnloadUnusedChunks()
-{
- cCSLock Lock(m_CSLayers);
- for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
- {
- (*itr)->UnloadUnusedChunks();
- } // for itr - m_Layers
-}
-
-
-
-
-
-void cChunkMap::SaveAllChunks(void)
-{
- cCSLock Lock(m_CSLayers);
- for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
- {
- (*itr)->Save();
- } // for itr - m_Layers[]
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// cChunkMap::cChunkLayer:
-
-cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent)
- : m_LayerX( a_LayerX )
- , m_LayerZ( a_LayerZ )
- , m_Parent( a_Parent )
- , m_NumChunksLoaded( 0 )
-{
- memset(m_Chunks, 0, sizeof(m_Chunks));
-}
-
-
-
-
-
-cChunkMap::cChunkLayer::~cChunkLayer()
-{
- for (int i = 0; i < ARRAYCOUNT(m_Chunks); ++i)
- {
- delete m_Chunks[i];
- } // for i - m_Chunks[]
-}
-
-
-
-
-
-cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ )
-{
- // Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check
-
- const int LocalX = a_ChunkX - m_LayerX * LAYER_SIZE;
- const int LocalZ = a_ChunkZ - m_LayerZ * LAYER_SIZE;
-
- if (!((LocalX < LAYER_SIZE) && (LocalZ < LAYER_SIZE) && (LocalX > -1) && (LocalZ > -1)))
- {
- ASSERT(!"Asking a cChunkLayer for a chunk that doesn't belong to it!");
- return NULL;
- }
-
- int Index = LocalX + LocalZ * LAYER_SIZE;
- if (m_Chunks[Index] == NULL)
- {
- m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld());
- }
- return m_Chunks[Index];
-}
-
-
-
-
-
-void cChunkMap::cChunkLayer::Tick(float a_Dt, MTRand & a_TickRand)
-{
- for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++)
- {
- // Only tick chunks that are valid and have clients:
- if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->HasAnyClients())
- {
- m_Chunks[i]->Tick(a_Dt, a_TickRand);
- }
- } // for i - m_Chunks[]
-}
-
-
-
-
-
-void cChunkMap::cChunkLayer::RemoveClient(cClientHandle * a_Client)
-{
- for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++)
- {
- if (m_Chunks[i] != NULL)
- {
- m_Chunks[i]->RemoveClient(a_Client);
- }
- } // for i - m_Chunks[]
-}
-
-
-
-
-
-int cChunkMap::cChunkLayer::GetNumChunksLoaded(void) const
-{
- int NumChunks = 0;
- for ( int i = 0; i < ARRAYCOUNT(m_Chunks); ++i )
- {
- if (m_Chunks[i] != NULL)
- {
- NumChunks++;
- }
- } // for i - m_Chunks[]
- return NumChunks;
-}
-
-
-
-
-
-void cChunkMap::cChunkLayer::GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) const
-{
- int NumValid = 0;
- int NumDirty = 0;
- for ( int i = 0; i < ARRAYCOUNT(m_Chunks); ++i )
- {
- if (m_Chunks[i] == NULL)
- {
- continue;
- }
- NumValid++;
- if (m_Chunks[i]->IsDirty())
- {
- NumDirty++;
- }
- } // for i - m_Chunks[]
- a_NumChunksValid = NumValid;
- a_NumChunksDirty = NumDirty;
-}
-
-
-
-
-
-void cChunkMap::cChunkLayer::Save(void)
-{
- cWorld * World = m_Parent->GetWorld();
- for (int i = 0; i < ARRAYCOUNT(m_Chunks); ++i)
- {
- if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->IsDirty())
- {
- World->GetStorage().QueueSaveChunk(m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosY(), m_Chunks[i]->GetPosZ());
- }
- } // for i - m_Chunks[]
-}
-
-
-
-
-
-void cChunkMap::cChunkLayer::UnloadUnusedChunks(void)
-{
- for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++)
- {
- if ((m_Chunks[i] != NULL) && (m_Chunks[i]->CanUnload()))
- {
- // The cChunk destructor calls our GetChunk() while removing its entities
- // so we still need to be able to return the chunk. Therefore we first delete, then NULLify
- // Doing otherwise results in bug http://forum.mc-server.org/showthread.php?tid=355
- delete m_Chunks[i];
- m_Chunks[i] = NULL;
- }
- } // for i - m_Chunks[]
-}
-
-
-
-
-
-int cChunkMap::GetNumChunks(void)
-{
- cCSLock Lock(m_CSLayers);
- int NumChunks = 0;
- for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
- {
- NumChunks += (*itr)->GetNumChunksLoaded();
- }
- return NumChunks;
-}
-
-
-
-
-
-void cChunkMap::ChunkValidated(void)
-{
- m_evtChunkValid.Set();
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cChunkStay:
-
-cChunkStay::cChunkStay(cWorld * a_World) :
- m_World(a_World),
- m_IsEnabled(false)
-{
-}
-
-
-
-
-
-cChunkStay::~cChunkStay()
-{
- Clear();
-}
-
-
-
-
-
-void cChunkStay::Clear(void)
-{
- if (m_IsEnabled)
- {
- Disable();
- }
- m_Chunks.clear();
-}
-
-
-
-
-
-void cChunkStay::Add(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- ASSERT(!m_IsEnabled);
-
- for (cChunkCoordsList::const_iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr)
- {
- if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ))
- {
- // Already present
- return;
- }
- } // for itr - Chunks[]
- m_Chunks.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
-}
-
-
-
-
-
-void cChunkStay::Remove(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- ASSERT(!m_IsEnabled);
-
- for (cChunkCoordsList::iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr)
- {
- if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ))
- {
- // Found, un-"stay"
- m_Chunks.erase(itr);
- return;
- }
- } // for itr - m_Chunks[]
-}
-
-
-
-
-
-void cChunkStay::Enable(void)
-{
- ASSERT(!m_IsEnabled);
-
- m_World->ChunksStay(*this, true);
- m_IsEnabled = true;
-}
-
-
-
-
-
-void cChunkStay::Load(void)
-{
- for (cChunkCoordsList::iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr)
- {
- m_World->TouchChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ);
- } // for itr - m_Chunks[]
-}
-
-
-
-
-
-void cChunkStay::Disable(void)
-{
- ASSERT(m_IsEnabled);
-
- m_World->ChunksStay(*this, false);
- m_IsEnabled = false;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cChunkMap.h" +#include "cWorld.h" +#include "cRoot.h" +#include "cMakeDir.h" +#include "cPlayer.h" +#include "BlockID.h" +#include "cItem.h" +#include "cPickup.h" +#include "cChunk.h" +#include "Trees.h" // used in cChunkMap::ReplaceTreeBlocks() for tree block discrimination + +#ifndef _WIN32 + #include <cstdlib> // abs +#endif + +#include "zlib.h" +#include <json/json.h> + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cChunkMap: + +cChunkMap::cChunkMap(cWorld * a_World ) + : m_World( a_World ) +{ +} + + + + + +cChunkMap::~cChunkMap() +{ + cCSLock Lock(m_CSLayers); + for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + delete *itr; + } // for itr - m_Layers[] +} + + + + + +void cChunkMap::RemoveLayer( cChunkLayer* a_Layer ) +{ + cCSLock Lock(m_CSLayers); + m_Layers.remove(a_Layer); +} + + + + + +cChunkMap::cChunkLayer * cChunkMap::GetLayer(int a_LayerX, int a_LayerZ) +{ + cCSLock Lock(m_CSLayers); + for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + if (((*itr)->GetX() == a_LayerX) && ((*itr)->GetZ() == a_LayerZ)) + { + return *itr; + } + } + + // Not found, create new: + cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this); + if (Layer == NULL) + { + LOGERROR("cChunkMap: Cannot create new layer, server out of memory?"); + return NULL; + } + m_Layers.push_back(Layer); + return Layer; +} + + + + + +cChunkMap::cChunkLayer * cChunkMap::GetLayerForChunk( int a_ChunkX, int a_ChunkZ ) +{ + const int LayerX = (int)(floorf((float)a_ChunkX / (float)(LAYER_SIZE))); + const int LayerZ = (int)(floorf((float)a_ChunkZ / (float)(LAYER_SIZE))); + return GetLayer( LayerX, LayerZ ); +} + + + + + +cChunkPtr cChunkMap::GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) +{ + // No need to lock m_CSLayers, since it's already locked by the operation that called us + cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ ); + if (Layer == NULL) + { + // An error must have occurred, since layers are automatically created if they don't exist + return NULL; + } + + cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + return NULL; + } + if (!(Chunk->IsValid())) + { + m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ, true); + } + return Chunk; +} + + + + + +cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) +{ + // No need to lock m_CSLayers, since it's already locked by the operation that called us + cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ ); + if (Layer == NULL) + { + // An error must have occurred, since layers are automatically created if they don't exist + return NULL; + } + + cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + return NULL; + } + if (!(Chunk->IsValid())) + { + m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ, false); + } + + return Chunk; +} + + + + + +cChunkPtr cChunkMap::GetChunkNoLoad( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) +{ + // No need to lock m_CSLayers, since it's already locked by the operation that called us + cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ ); + if (Layer == NULL) + { + // An error must have occurred, since layers are automatically created if they don't exist + return NULL; + } + + return Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +bool cChunkMap::LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) +{ + // We already have m_CSLayers locked since this can be called only from within the tick thread + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk == NULL) + { + return false; + } + + int Index = cChunkDef::MakeIndexNoCheck(a_BlockX, a_BlockY, a_BlockZ); + a_BlockType = Chunk->GetBlock(Index); + a_BlockMeta = Chunk->GetMeta(Index); + return true; +} + + + + + +bool cChunkMap::LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + // We already have m_CSLayers locked since this can be called only from within the tick thread + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk == NULL) + { + return false; + } + + Chunk->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); + return true; +} + + + + + +bool cChunkMap::LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + // We already have m_CSLayers locked since this can be called only from within the tick thread + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk == NULL) + { + return false; + } + + Chunk->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); + return true; +} + + + + + +void cChunkMap::BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude) +{ + // Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + return; + } + // It's perfectly legal to broadcast packets even to invalid chunks! + Chunk->Broadcast(a_Packet, a_Exclude); +} + + + + + +void cChunkMap::BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, const cPacket * a_Packet, cClientHandle * a_Exclude) +{ + // Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude + + cCSLock Lock(m_CSLayers); + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk == NULL) + { + return; + } + // It's perfectly legal to broadcast packets even to invalid chunks! + Chunk->Broadcast(a_Packet, a_Exclude); +} + + + + + +void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) +{ + // a_Player rclked block entity at the coords specified, handle it + cCSLock Lock(m_CSLayers); + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return; + } + Chunk->UseBlockEntity(a_Player, a_X, a_Y, a_Z); +} + + + + + +void cChunkMap::MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return; + } + Chunk->MarkDirty(); +} + + + + + +void cChunkMap::MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return; + } + Chunk->MarkSaving(); +} + + + + + +void cChunkMap::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return; + } + Chunk->MarkSaved(); +} + + + + + +void cChunkMap::SetChunkData( + int a_ChunkX, int a_ChunkY, int a_ChunkZ, + const BLOCKTYPE * a_BlockTypes, + const NIBBLETYPE * a_BlockMeta, + const NIBBLETYPE * a_BlockLight, + const NIBBLETYPE * a_BlockSkyLight, + const cChunkDef::HeightMap * a_HeightMap, + const cChunkDef::BiomeMap & a_BiomeMap, + cEntityList & a_Entities, + cBlockEntityList & a_BlockEntities, + bool a_MarkDirty +) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + return; + } + Chunk->SetAllData(a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, a_HeightMap, a_BiomeMap, a_Entities, a_BlockEntities); + Chunk->SetValid(); + + if (a_MarkDirty) + { + Chunk->MarkDirty(); + } +} + + + + + +void cChunkMap::ChunkLighted( + int a_ChunkX, int a_ChunkZ, + const cChunkDef::BlockNibbles & a_BlockLight, + const cChunkDef::BlockNibbles & a_SkyLight +) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + if (Chunk == NULL) + { + return; + } + Chunk->SetLight(a_BlockLight, a_SkyLight); + Chunk->MarkDirty(); +} + + + + + +bool cChunkMap::GetChunkData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return false; + } + Chunk->GetAllData(a_Callback); + return true; +} + + + + + +bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return false; + } + Chunk->GetBlockTypes(a_BlockTypes); + return true; +} + + + + + +bool cChunkMap::GetChunkBlockData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return false; + } + Chunk->GetBlockData(a_BlockData); + return true; +} + + + + + +bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ); + return (Chunk != NULL) && Chunk->IsValid(); +} + + + + + +bool cChunkMap::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + return (Chunk != NULL) && Chunk->HasAnyClients(); +} + + + + + +int cChunkMap::GetHeight(int a_BlockX, int a_BlockZ) +{ + cCSLock Lock(m_CSLayers); + int ChunkX, ChunkZ, BlockY = 0; + cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk == NULL) + { + return 0; + } + + // Wait for the chunk to become valid: + while (!Chunk->IsValid()) + { + GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); // Re-queue (in case it managed to get unloaded before we caught it + cCSUnlock Unlock(Lock); + m_evtChunkValid.Wait(); + } + + return Chunk->GetHeight(a_BlockX, a_BlockZ); +} + + + + + +void cChunkMap::FastSetBlocks(sSetBlockList & a_BlockList) +{ + sSetBlockList Failed; + + // Process all items from a_BlockList, either successfully or by placing into Failed + while (!a_BlockList.empty()) + { + int ChunkX = a_BlockList.front().ChunkX; + int ChunkZ = a_BlockList.front().ChunkZ; + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if ((Chunk != NULL) && Chunk->IsValid()) + { + for (sSetBlockList::iterator itr = a_BlockList.begin(); itr != a_BlockList.end();) + { + if ((itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ)) + { + Chunk->FastSetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); + itr = a_BlockList.erase(itr); + } + else + { + ++itr; + } + } // for itr - a_BlockList[] + } + else + { + // The chunk is not valid, move all blocks within this chunk to Failed + for (sSetBlockList::iterator itr = a_BlockList.begin(); itr != a_BlockList.end();) + { + if ((itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ)) + { + Failed.push_back(*itr); + itr = a_BlockList.erase(itr); + } + else + { + ++itr; + } + } // for itr - a_BlockList[] + } + } + + // Return the failed: + std::swap(Failed, a_BlockList); +} + + + + + +void cChunkMap::CollectPickupsByPlayer(cPlayer * a_Player) +{ + int BlockX = (int)(a_Player->GetPosX()); // Truncating doesn't matter much; we're scanning entire chunks anyway + int BlockY = (int)(a_Player->GetPosY()); + int BlockZ = (int)(a_Player->GetPosZ()); + int ChunkX, ChunkZ, ChunkY = ZERO_CHUNK_Y; + cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); + int OtherChunkX = ChunkX + ((BlockX > 8) ? 1 : -1); + int OtherChunkZ = ChunkZ + ((BlockZ > 8) ? 1 : -1); + + // We suppose that each player keeps their chunks in memory, therefore it makes little sense to try to re-load or even generate them. + // The only time the chunks are not valid is when the player is downloading the initial world and they should not call this at that moment + + cCSLock Lock(m_CSLayers); + GetChunkNoLoad(ChunkX, ChunkY, ChunkZ)->CollectPickupsByPlayer(a_Player); + + // Check the neighboring chunks as well: + GetChunkNoLoad(OtherChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player); + GetChunkNoLoad(OtherChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player); + GetChunkNoLoad(ChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player); + GetChunkNoLoad(ChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player); +} + + + + + +BLOCKTYPE cChunkMap::GetBlock(int a_X, int a_Y, int a_Z) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if ((Chunk != NULL) && Chunk->IsValid()) + { + return Chunk->GetBlock(a_X, a_Y, a_Z); + } + return 0; +} + + + + + +BLOCKTYPE cChunkMap::GetBlockMeta(int a_X, int a_Y, int a_Z) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((Chunk != NULL) && Chunk->IsValid() ) + { + return Chunk->GetMeta(a_X, a_Y, a_Z); + } + return 0; +} + + + + + +BLOCKTYPE cChunkMap::GetBlockSkyLight(int a_X, int a_Y, int a_Z) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((Chunk != NULL) && Chunk->IsValid() ) + { + return Chunk->GetSkyLight( a_X, a_Y, a_Z ); + } + return 0; +} + + + + + +void cChunkMap::SetBlockMeta(int a_X, int a_Y, int a_Z, char a_BlockMeta) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((Chunk != NULL) && Chunk->IsValid() ) + { + Chunk->SetMeta(a_X, a_Y, a_Z, a_BlockMeta); + Chunk->MarkDirty(); + Chunk->SendBlockTo( a_X, a_Y, a_Z, NULL ); + } +} + + + + + +void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) +{ + int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; + cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((Chunk != NULL) && Chunk->IsValid()) + { + Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta ); + } +} + + + + + +void cChunkMap::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) +{ + int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; + cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((Chunk != NULL) && Chunk->IsValid()) + { + Chunk->GetBlockTypeMeta(X, Y, Z, a_BlockType, a_BlockMeta); + } +} + + + + + +void cChunkMap::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType) +{ + cCSLock Lock(m_CSLayers); + for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) + { + cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + continue; + } + if (Chunk->GetBlock(itr->x, itr->y, itr->z) == a_FilterBlockType) + { + Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); + } + } +} + + + + + +void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) +{ + cCSLock Lock(m_CSLayers); + for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) + { + cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + continue; + } + switch (Chunk->GetBlock(itr->x, itr->y, itr->z)) + { + CASE_TREE_OVERWRITTEN_BLOCKS: + { + Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); + break; + } + } + } // for itr - a_Blocks[] +} + + + + + +EMCSBiome cChunkMap::GetBiomeAt (int a_BlockX, int a_BlockZ) +{ + int ChunkX, ChunkZ, X = a_BlockX, Y = 0, Z = a_BlockZ; + cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((Chunk != NULL) && Chunk->IsValid()) + { + return Chunk->GetBiomeAt(X, Z); + } + else + { + return m_World->GetGenerator().GetBiomeAt(a_BlockX, a_BlockZ); + } +} + + + + + +bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) +{ + bool res = true; + cCSLock Lock(m_CSLayers); + for (sSetBlockVector::iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) + { + cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + if (!a_ContinueOnFailure) + { + return false; + } + res = false; + continue; + } + int idx = cChunkDef::MakeIndexNoCheck(itr->x, itr->y, itr->z); + itr->BlockType = Chunk->GetBlock(idx); + itr->BlockMeta = Chunk->GetMeta(idx); + } + return res; +} + + + + + +bool cChunkMap::DigBlock(int a_X, int a_Y, int a_Z) +{ + int PosX = a_X, PosY = a_Y, PosZ = a_Z, ChunkX, ChunkZ; + + cChunkDef::AbsoluteToRelative( PosX, PosY, PosZ, ChunkX, ChunkZ ); + + { + cCSLock Lock(m_CSLayers); + cChunkPtr DestChunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((DestChunk == NULL) || !DestChunk->IsValid()) + { + return false; + } + + DestChunk->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, 0 ); + } + + m_World->GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z); + + return true; +} + + + + + +void cChunkMap::SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_X, a_Y, a_Z, ChunkX, ChunkZ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk->IsValid()) + { + Chunk->SendBlockTo(a_X, a_Y, a_Z, a_Player->GetClientHandle()); + } +} + + + + + +void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk1 = GetChunkNoGen(a_ChunkX1, a_ChunkY1, a_ChunkZ1); + if (Chunk1 == NULL) + { + return; + } + cChunkPtr Chunk2 = GetChunkNoGen(a_ChunkX2, a_ChunkY2, a_ChunkZ2); + if (Chunk2 == NULL) + { + return; + } + + cClientHandleList Clients1(Chunk1->GetAllClients()); + cClientHandleList Clients2(Chunk2->GetAllClients()); + + // Find "removed" clients: + for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1) + { + bool Found = false; + for (cClientHandleList::iterator itr2 = Clients2.begin(); itr2 != Clients2.end(); ++itr2) + { + if (*itr1 == *itr2) + { + Found = true; + break; + } + } // for itr2 - Clients2[] + if (!Found) + { + a_Callback.Removed(*itr1); + } + } // for itr1 - Clients1[] + + // Find "added" clients: + for (cClientHandleList::iterator itr2 = Clients2.begin(); itr2 != Clients2.end(); ++itr2) + { + bool Found = false; + for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1) + { + if (*itr1 == *itr2) + { + Found = true; + break; + } + } // for itr1 - Clients1[] + if (!Found) + { + a_Callback.Added(*itr2); + } + } // for itr2 - Clients2[] +} + + + + + +bool cChunkMap::AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + return false; + } + return Chunk->AddClient(a_Client); +} + + + + + +void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + return; + } + Chunk->RemoveClient(a_Client); +} + + + + + +void cChunkMap::RemoveClientFromChunks(cClientHandle * a_Client) +{ + cCSLock Lock(m_CSLayers); + + for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + (*itr)->RemoveClient(a_Client); + } // for itr - m_Layers[] +} + + + + + +void cChunkMap::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr OldChunk = GetChunkNoGen(a_Entity->GetChunkX(), a_Entity->GetChunkY(), a_Entity->GetChunkZ()); + if (OldChunk != NULL) + { + OldChunk->RemoveEntity(a_Entity); + } + cChunkPtr NewChunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if (NewChunk != NULL) + { + NewChunk->AddEntity(a_Entity); + } +} + + + + + +void cChunkMap::RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if ((Chunk == NULL) && !Chunk->IsValid()) + { + return; + } + Chunk->RemoveEntity(a_Entity); +} + + + + + +void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +/// Loads the chunk synchronously, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) +bool cChunkMap::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + { + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + // Internal error + return false; + } + if (Chunk->IsValid()) + { + // Already loaded + return true; + } + if (Chunk->HasLoadFailed()) + { + // Already tried loading and it failed + return false; + } + } + return m_World->GetStorage().LoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +/// Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() +void cChunkMap::LoadChunks(const cChunkCoordsList & a_Chunks) +{ + for (cChunkCoordsList::const_iterator itr = a_Chunks.begin(); itr != a_Chunks.end(); ++itr) + { + LoadChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); + } // for itr - a_Chunks[] +} + + + + + +void cChunkMap::ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ); + if (Chunk == NULL) + { + return; + } + Chunk->MarkLoadFailed(); +} + + + + + +void cChunkMap::UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) +{ + cCSLock Lock(m_CSLayers); + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return; + } + Chunk->UpdateSign(a_X, a_Y, a_Z, a_Line1, a_Line2, a_Line3, a_Line4); +} + + + + + +void cChunkMap::ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay) +{ + cCSLock Lock(m_CSLayers); + for (cChunkCoordsList::const_iterator itr = a_Chunks.begin(); itr != a_Chunks.end(); ++itr) + { + cChunkPtr Chunk = GetChunkNoLoad(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); + if (Chunk == NULL) + { + continue; + } + Chunk->Stay(a_Stay); + } +} + + + + + +void cChunkMap::MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + if (Chunk == NULL) + { + // Not present + return; + } + Chunk->MarkRegenerating(); +} + + + + + +bool cChunkMap::IsChunkLighted(int a_ChunkX, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + if (Chunk == NULL) + { + // Not present + return false; + } + return Chunk->IsLightValid(); +} + + + + + +void cChunkMap::GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) +{ + a_NumChunksValid = 0; + a_NumChunksDirty = 0; + cCSLock Lock(m_CSLayers); + for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + int NumValid = 0, NumDirty = 0; + (*itr)->GetChunkStats(NumValid, NumDirty); + a_NumChunksValid += NumValid; + a_NumChunksDirty += NumDirty; + } // for itr - m_Layers[] +} + + + + + +void cChunkMap::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, MTRand & a_Rand) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk != NULL) + { + Chunk->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_Rand); + } +} + + + + + +void cChunkMap::GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk != NULL) + { + Chunk->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, a_NumBlocksToGrow); + } +} + + + + + +void cChunkMap::GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk != NULL) + { + Chunk->GrowCactus(a_BlockX, a_BlockY, a_BlockZ, a_NumBlocksToGrow); + } +} + + + + + +void cChunkMap::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk != NULL) + { + Chunk->SetNextBlockTick(a_BlockX, a_BlockY, a_BlockZ); + } +} + + + + + +void cChunkMap::Tick( float a_Dt, MTRand & a_TickRandom ) +{ + cCSLock Lock(m_CSLayers); + for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + (*itr)->Tick(a_Dt, a_TickRandom); + } // for itr - m_Layers +} + + + + + +void cChunkMap::UnloadUnusedChunks() +{ + cCSLock Lock(m_CSLayers); + for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + (*itr)->UnloadUnusedChunks(); + } // for itr - m_Layers +} + + + + + +void cChunkMap::SaveAllChunks(void) +{ + cCSLock Lock(m_CSLayers); + for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + (*itr)->Save(); + } // for itr - m_Layers[] +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cChunkMap::cChunkLayer: + +cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent) + : m_LayerX( a_LayerX ) + , m_LayerZ( a_LayerZ ) + , m_Parent( a_Parent ) + , m_NumChunksLoaded( 0 ) +{ + memset(m_Chunks, 0, sizeof(m_Chunks)); +} + + + + + +cChunkMap::cChunkLayer::~cChunkLayer() +{ + for (int i = 0; i < ARRAYCOUNT(m_Chunks); ++i) + { + delete m_Chunks[i]; + } // for i - m_Chunks[] +} + + + + + +cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) +{ + // Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check + + const int LocalX = a_ChunkX - m_LayerX * LAYER_SIZE; + const int LocalZ = a_ChunkZ - m_LayerZ * LAYER_SIZE; + + if (!((LocalX < LAYER_SIZE) && (LocalZ < LAYER_SIZE) && (LocalX > -1) && (LocalZ > -1))) + { + ASSERT(!"Asking a cChunkLayer for a chunk that doesn't belong to it!"); + return NULL; + } + + int Index = LocalX + LocalZ * LAYER_SIZE; + if (m_Chunks[Index] == NULL) + { + m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld()); + } + return m_Chunks[Index]; +} + + + + + +void cChunkMap::cChunkLayer::Tick(float a_Dt, MTRand & a_TickRand) +{ + for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++) + { + // Only tick chunks that are valid and have clients: + if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->HasAnyClients()) + { + m_Chunks[i]->Tick(a_Dt, a_TickRand); + } + } // for i - m_Chunks[] +} + + + + + +void cChunkMap::cChunkLayer::RemoveClient(cClientHandle * a_Client) +{ + for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++) + { + if (m_Chunks[i] != NULL) + { + m_Chunks[i]->RemoveClient(a_Client); + } + } // for i - m_Chunks[] +} + + + + + +int cChunkMap::cChunkLayer::GetNumChunksLoaded(void) const +{ + int NumChunks = 0; + for ( int i = 0; i < ARRAYCOUNT(m_Chunks); ++i ) + { + if (m_Chunks[i] != NULL) + { + NumChunks++; + } + } // for i - m_Chunks[] + return NumChunks; +} + + + + + +void cChunkMap::cChunkLayer::GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) const +{ + int NumValid = 0; + int NumDirty = 0; + for ( int i = 0; i < ARRAYCOUNT(m_Chunks); ++i ) + { + if (m_Chunks[i] == NULL) + { + continue; + } + NumValid++; + if (m_Chunks[i]->IsDirty()) + { + NumDirty++; + } + } // for i - m_Chunks[] + a_NumChunksValid = NumValid; + a_NumChunksDirty = NumDirty; +} + + + + + +void cChunkMap::cChunkLayer::Save(void) +{ + cWorld * World = m_Parent->GetWorld(); + for (int i = 0; i < ARRAYCOUNT(m_Chunks); ++i) + { + if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->IsDirty()) + { + World->GetStorage().QueueSaveChunk(m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosY(), m_Chunks[i]->GetPosZ()); + } + } // for i - m_Chunks[] +} + + + + + +void cChunkMap::cChunkLayer::UnloadUnusedChunks(void) +{ + for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++) + { + if ((m_Chunks[i] != NULL) && (m_Chunks[i]->CanUnload())) + { + // The cChunk destructor calls our GetChunk() while removing its entities + // so we still need to be able to return the chunk. Therefore we first delete, then NULLify + // Doing otherwise results in bug http://forum.mc-server.org/showthread.php?tid=355 + delete m_Chunks[i]; + m_Chunks[i] = NULL; + } + } // for i - m_Chunks[] +} + + + + + +int cChunkMap::GetNumChunks(void) +{ + cCSLock Lock(m_CSLayers); + int NumChunks = 0; + for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) + { + NumChunks += (*itr)->GetNumChunksLoaded(); + } + return NumChunks; +} + + + + + +void cChunkMap::ChunkValidated(void) +{ + m_evtChunkValid.Set(); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cChunkStay: + +cChunkStay::cChunkStay(cWorld * a_World) : + m_World(a_World), + m_IsEnabled(false) +{ +} + + + + + +cChunkStay::~cChunkStay() +{ + Clear(); +} + + + + + +void cChunkStay::Clear(void) +{ + if (m_IsEnabled) + { + Disable(); + } + m_Chunks.clear(); +} + + + + + +void cChunkStay::Add(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + ASSERT(!m_IsEnabled); + + for (cChunkCoordsList::const_iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) + { + if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ)) + { + // Already present + return; + } + } // for itr - Chunks[] + m_Chunks.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); +} + + + + + +void cChunkStay::Remove(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + ASSERT(!m_IsEnabled); + + for (cChunkCoordsList::iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) + { + if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ)) + { + // Found, un-"stay" + m_Chunks.erase(itr); + return; + } + } // for itr - m_Chunks[] +} + + + + + +void cChunkStay::Enable(void) +{ + ASSERT(!m_IsEnabled); + + m_World->ChunksStay(*this, true); + m_IsEnabled = true; +} + + + + + +void cChunkStay::Load(void) +{ + for (cChunkCoordsList::iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) + { + m_World->TouchChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); + } // for itr - m_Chunks[] +} + + + + + +void cChunkStay::Disable(void) +{ + ASSERT(m_IsEnabled); + + m_World->ChunksStay(*this, false); + m_IsEnabled = false; +} + + + + diff --git a/source/cChunkMap.h b/source/cChunkMap.h index 7ddb094c5..1d90c6aaa 100644 --- a/source/cChunkMap.h +++ b/source/cChunkMap.h @@ -1,281 +1,281 @@ -
-// cChunkMap.h
-
-// Interfaces to the cChunkMap class representing the chunk storage for a single world
-
-#pragma once
-
-#include "ChunkDef.h"
-
-
-
-
-
-class cWorld;
-class cItem;
-class MTRand;
-class cChunkStay;
-class cChunk;
-class cPacket;
-class cPlayer;
-
-typedef std::list<cClientHandle *> cClientHandleList;
-typedef cChunk * cChunkPtr;
-
-
-
-
-
-class cChunkMap
-{
-public:
-
- static const int LAYER_SIZE = 32;
-
- cChunkMap(cWorld* a_World );
- ~cChunkMap();
-
- // Direct action methods:
- /// Broadcast a_Packet to all clients in the chunk specified
- void BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude = NULL);
-
- /// Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude
- void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, const cPacket * a_Packet, cClientHandle * a_Exclude = NULL);
-
- /// a_Player rclked block entity at the coords specified, handle it
- void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z);
-
- void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void MarkChunkSaving (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- /** Sets the chunk data as either loaded from the storage or generated.
- a_BlockLight and a_BlockSkyLight are optional, if not present, chunk will be marked as unlighted.
- a_BiomeMap is optional, if not present, biomes will be calculated by the generator
- a_HeightMap is optional, if not present, will be calculated.
- If a_MarkDirty is set, the chunk is set as dirty (used after generating)
- */
- void SetChunkData(
- int a_ChunkX, int a_ChunkY, int a_ChunkZ,
- const BLOCKTYPE * a_BlockTypes,
- const NIBBLETYPE * a_BlockMeta,
- const NIBBLETYPE * a_BlockLight,
- const NIBBLETYPE * a_BlockSkyLight,
- const cChunkDef::HeightMap * a_HeightMap,
- const cChunkDef::BiomeMap & a_BiomeMap,
- cEntityList & a_Entities,
- cBlockEntityList & a_BlockEntities,
- bool a_MarkDirty
- );
-
- void ChunkLighted(
- int a_ChunkX, int a_ChunkZ,
- const cChunkDef::BlockNibbles & a_BlockLight,
- const cChunkDef::BlockNibbles & a_SkyLight
- );
-
- bool GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback);
-
- /// Gets the chunk's blocks, only the block types
- bool GetChunkBlockTypes (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_Blocks);
-
- /// Gets the chunk's block data, the entire 4 arrays (Types, Meta, Light, SkyLight)
- bool GetChunkBlockData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData);
-
- bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- bool HasChunkAnyClients (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- int GetHeight (int a_BlockX, int a_BlockZ);
- void FastSetBlocks (sSetBlockList & a_BlockList);
- void CollectPickupsByPlayer(cPlayer * a_Player);
- BLOCKTYPE GetBlock (int a_X, int a_Y, int a_Z);
- BLOCKTYPE GetBlockMeta (int a_X, int a_Y, int a_Z);
- BLOCKTYPE GetBlockSkyLight (int a_X, int a_Y, int a_Z);
- void SetBlockMeta (int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockMeta);
- void SetBlock (int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta);
- void GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta);
-
- /// Replaces world blocks with a_Blocks, if they are of type a_FilterBlockType
- void ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType);
-
- /// Special function used for growing trees, replaces only blocks that tree may overwrite
- void ReplaceTreeBlocks(const sSetBlockVector & a_Blocks);
-
- EMCSBiome GetBiomeAt (int a_BlockX, int a_BlockZ);
-
- /// Retrieves block types of the specified blocks. If a chunk is not loaded, doesn't modify the block. Returns true if all blocks were read.
- bool GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure);
-
- bool DigBlock (int a_X, int a_Y, int a_Z);
- void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player);
-
- /// Compares clients of two chunks, calls the callback accordingly
- void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback);
-
- /// Adds client to a chunk, if not already present; returns true if added, false if present
- bool AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
-
- /// Removes the client from the chunk
- void RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
-
- /// Removes the client from all chunks it is present in
- void RemoveClientFromChunks(cClientHandle * a_Client);
-
- /// Moves the entity from its current chunk to the new chunk specified
- void MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- /// Removes the entity from the chunk specified
- void RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- /// Touches the chunk, causing it to be loaded or generated
- void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- /// Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before)
- bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- /// Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid()
- void LoadChunks(const cChunkCoordsList & a_Chunks);
-
- /// Marks the chunk as failed-to-load:
- void ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- void UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4);
-
- /// Marks (a_Stay == true) or unmarks (a_Stay == false) chunks as non-unloadable; to be used only by cChunkStay!
- void ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay = true);
-
- /// Marks the chunk as being regenerated - all its clients want that chunk again (used by cWorld::RegenerateChunk() )
- void MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ);
-
- bool IsChunkLighted(int a_ChunkX, int a_ChunkZ);
-
- /// Returns the number of valid chunks and the number of dirty chunks
- void GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty);
-
- /// Grows a melon or a pumpkin next to the block specified (assumed to be the stem)
- void GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, MTRand & a_Rand);
-
- /// Grows a sugarcane present at the block specified by the amount of blocks specified, up to the max height of 3
- void GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow);
-
- /// Grows a cactus present at the block specified by the amount of blocks specified, up to the max height of 3
- void GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow);
-
- /// Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call
- void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ);
-
- void Tick( float a_Dt, MTRand & a_TickRand );
-
- void UnloadUnusedChunks();
- void SaveAllChunks();
-
- cWorld * GetWorld() { return m_World; }
-
- int GetNumChunks(void);
-
- void ChunkValidated(void); // Called by chunks that have become valid
-
-private:
-
- friend class cChunk; // The chunks can manipulate neighbors while in their Tick() method, using LockedGetBlock() and LockedSetBlock()
-
- class cChunkLayer
- {
- public:
- cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent);
- ~cChunkLayer();
-
- /// Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check
- cChunkPtr GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ );
-
- int GetX(void) const {return m_LayerX; }
- int GetZ(void) const {return m_LayerZ; }
-
- int GetNumChunksLoaded(void) const ;
-
- void GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) const;
-
- void Save(void);
- void UnloadUnusedChunks(void);
-
- void Tick( float a_Dt, MTRand & a_TickRand );
-
- void RemoveClient(cClientHandle * a_Client);
-
- protected:
-
- cChunkPtr m_Chunks[LAYER_SIZE * LAYER_SIZE];
- int m_LayerX;
- int m_LayerZ;
- cChunkMap * m_Parent;
- int m_NumChunksLoaded;
- };
-
- typedef std::list<cChunkLayer *> cChunkLayerList;
- // TODO: Use smart pointers for cChunkLayerList as well, so that ticking and saving needn't lock the entire layerlist
- // This however means that cChunkLayer needs to interlock its m_Chunks[]
-
- cChunkLayer * GetLayerForChunk( int a_ChunkX, int a_ChunkZ ); // Creates the layer if it doesn't already exist
- cChunkLayer * GetLayer( int a_LayerX, int a_LayerZ ); // Creates the layer if it doesn't already exist
- void RemoveLayer( cChunkLayer* a_Layer );
-
- cCriticalSection m_CSLayers;
- cChunkLayerList m_Layers;
- cEvent m_evtChunkValid; // Set whenever any chunk becomes valid, via ChunkValidated()
-
- cWorld * m_World;
-
- cChunkPtr GetChunk (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid
- cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate
- cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Doesn't load, doesn't generate
-
- /// Gets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load)
- bool LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta);
-
- /// Sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load)
- bool LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
-
- /// Fast-sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load)
- bool LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
-};
-
-
-
-
-
-/** Makes chunks stay loaded until this object is cleared or destroyed
-Works by setting internal flags in the cChunk that it should not be unloaded.
-To optimize for speed, cChunkStay has an Enabled flag, it will "stay" the chunks only when enabled and it will refuse manipulations when enabled
-The object itself is not made thread-safe, it's supposed to be used from a single thread only.
-*/
-class cChunkStay
-{
-public:
- cChunkStay(cWorld * a_World);
- ~cChunkStay();
-
- void Clear(void);
-
- void Add(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void Remove(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- void Enable(void);
- void Disable(void);
-
- /// Queues each chunk in m_Chunks[] for loading / generating
- void Load(void);
-
- // Allow cChunkStay be passed to functions expecting a const cChunkCoordsList &
- operator const cChunkCoordsList(void) const {return m_Chunks; }
-
-protected:
-
- cWorld * m_World;
-
- bool m_IsEnabled;
-
- cChunkCoordsList m_Chunks;
-} ;
-
-
-
-
+ +// cChunkMap.h + +// Interfaces to the cChunkMap class representing the chunk storage for a single world + +#pragma once + +#include "ChunkDef.h" + + + + + +class cWorld; +class cItem; +class MTRand; +class cChunkStay; +class cChunk; +class cPacket; +class cPlayer; + +typedef std::list<cClientHandle *> cClientHandleList; +typedef cChunk * cChunkPtr; + + + + + +class cChunkMap +{ +public: + + static const int LAYER_SIZE = 32; + + cChunkMap(cWorld* a_World ); + ~cChunkMap(); + + // Direct action methods: + /// Broadcast a_Packet to all clients in the chunk specified + void BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude = NULL); + + /// Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude + void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, const cPacket * a_Packet, cClientHandle * a_Exclude = NULL); + + /// a_Player rclked block entity at the coords specified, handle it + void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); + + void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void MarkChunkSaving (int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /** Sets the chunk data as either loaded from the storage or generated. + a_BlockLight and a_BlockSkyLight are optional, if not present, chunk will be marked as unlighted. + a_BiomeMap is optional, if not present, biomes will be calculated by the generator + a_HeightMap is optional, if not present, will be calculated. + If a_MarkDirty is set, the chunk is set as dirty (used after generating) + */ + void SetChunkData( + int a_ChunkX, int a_ChunkY, int a_ChunkZ, + const BLOCKTYPE * a_BlockTypes, + const NIBBLETYPE * a_BlockMeta, + const NIBBLETYPE * a_BlockLight, + const NIBBLETYPE * a_BlockSkyLight, + const cChunkDef::HeightMap * a_HeightMap, + const cChunkDef::BiomeMap & a_BiomeMap, + cEntityList & a_Entities, + cBlockEntityList & a_BlockEntities, + bool a_MarkDirty + ); + + void ChunkLighted( + int a_ChunkX, int a_ChunkZ, + const cChunkDef::BlockNibbles & a_BlockLight, + const cChunkDef::BlockNibbles & a_SkyLight + ); + + bool GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback); + + /// Gets the chunk's blocks, only the block types + bool GetChunkBlockTypes (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_Blocks); + + /// Gets the chunk's block data, the entire 4 arrays (Types, Meta, Light, SkyLight) + bool GetChunkBlockData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData); + + bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ); + bool HasChunkAnyClients (int a_ChunkX, int a_ChunkY, int a_ChunkZ); + int GetHeight (int a_BlockX, int a_BlockZ); + void FastSetBlocks (sSetBlockList & a_BlockList); + void CollectPickupsByPlayer(cPlayer * a_Player); + BLOCKTYPE GetBlock (int a_X, int a_Y, int a_Z); + BLOCKTYPE GetBlockMeta (int a_X, int a_Y, int a_Z); + BLOCKTYPE GetBlockSkyLight (int a_X, int a_Y, int a_Z); + void SetBlockMeta (int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockMeta); + void SetBlock (int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta); + void GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); + + /// Replaces world blocks with a_Blocks, if they are of type a_FilterBlockType + void ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType); + + /// Special function used for growing trees, replaces only blocks that tree may overwrite + void ReplaceTreeBlocks(const sSetBlockVector & a_Blocks); + + EMCSBiome GetBiomeAt (int a_BlockX, int a_BlockZ); + + /// Retrieves block types of the specified blocks. If a chunk is not loaded, doesn't modify the block. Returns true if all blocks were read. + bool GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure); + + bool DigBlock (int a_X, int a_Y, int a_Z); + void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player); + + /// Compares clients of two chunks, calls the callback accordingly + void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback); + + /// Adds client to a chunk, if not already present; returns true if added, false if present + bool AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); + + /// Removes the client from the chunk + void RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); + + /// Removes the client from all chunks it is present in + void RemoveClientFromChunks(cClientHandle * a_Client); + + /// Moves the entity from its current chunk to the new chunk specified + void MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Removes the entity from the chunk specified + void RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Touches the chunk, causing it to be loaded or generated + void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) + bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() + void LoadChunks(const cChunkCoordsList & a_Chunks); + + /// Marks the chunk as failed-to-load: + void ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + void UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); + + /// Marks (a_Stay == true) or unmarks (a_Stay == false) chunks as non-unloadable; to be used only by cChunkStay! + void ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay = true); + + /// Marks the chunk as being regenerated - all its clients want that chunk again (used by cWorld::RegenerateChunk() ) + void MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ); + + bool IsChunkLighted(int a_ChunkX, int a_ChunkZ); + + /// Returns the number of valid chunks and the number of dirty chunks + void GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty); + + /// Grows a melon or a pumpkin next to the block specified (assumed to be the stem) + void GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, MTRand & a_Rand); + + /// Grows a sugarcane present at the block specified by the amount of blocks specified, up to the max height of 3 + void GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow); + + /// Grows a cactus present at the block specified by the amount of blocks specified, up to the max height of 3 + void GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow); + + /// Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call + void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ); + + void Tick( float a_Dt, MTRand & a_TickRand ); + + void UnloadUnusedChunks(); + void SaveAllChunks(); + + cWorld * GetWorld() { return m_World; } + + int GetNumChunks(void); + + void ChunkValidated(void); // Called by chunks that have become valid + +private: + + friend class cChunk; // The chunks can manipulate neighbors while in their Tick() method, using LockedGetBlock() and LockedSetBlock() + + class cChunkLayer + { + public: + cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent); + ~cChunkLayer(); + + /// Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check + cChunkPtr GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ ); + + int GetX(void) const {return m_LayerX; } + int GetZ(void) const {return m_LayerZ; } + + int GetNumChunksLoaded(void) const ; + + void GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) const; + + void Save(void); + void UnloadUnusedChunks(void); + + void Tick( float a_Dt, MTRand & a_TickRand ); + + void RemoveClient(cClientHandle * a_Client); + + protected: + + cChunkPtr m_Chunks[LAYER_SIZE * LAYER_SIZE]; + int m_LayerX; + int m_LayerZ; + cChunkMap * m_Parent; + int m_NumChunksLoaded; + }; + + typedef std::list<cChunkLayer *> cChunkLayerList; + // TODO: Use smart pointers for cChunkLayerList as well, so that ticking and saving needn't lock the entire layerlist + // This however means that cChunkLayer needs to interlock its m_Chunks[] + + cChunkLayer * GetLayerForChunk( int a_ChunkX, int a_ChunkZ ); // Creates the layer if it doesn't already exist + cChunkLayer * GetLayer( int a_LayerX, int a_LayerZ ); // Creates the layer if it doesn't already exist + void RemoveLayer( cChunkLayer* a_Layer ); + + cCriticalSection m_CSLayers; + cChunkLayerList m_Layers; + cEvent m_evtChunkValid; // Set whenever any chunk becomes valid, via ChunkValidated() + + cWorld * m_World; + + cChunkPtr GetChunk (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid + cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate + cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Doesn't load, doesn't generate + + /// Gets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) + bool LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); + + /// Sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) + bool LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + + /// Fast-sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) + bool LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); +}; + + + + + +/** Makes chunks stay loaded until this object is cleared or destroyed +Works by setting internal flags in the cChunk that it should not be unloaded. +To optimize for speed, cChunkStay has an Enabled flag, it will "stay" the chunks only when enabled and it will refuse manipulations when enabled +The object itself is not made thread-safe, it's supposed to be used from a single thread only. +*/ +class cChunkStay +{ +public: + cChunkStay(cWorld * a_World); + ~cChunkStay(); + + void Clear(void); + + void Add(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void Remove(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + void Enable(void); + void Disable(void); + + /// Queues each chunk in m_Chunks[] for loading / generating + void Load(void); + + // Allow cChunkStay be passed to functions expecting a const cChunkCoordsList & + operator const cChunkCoordsList(void) const {return m_Chunks; } + +protected: + + cWorld * m_World; + + bool m_IsEnabled; + + cChunkCoordsList m_Chunks; +} ; + + + + diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index a005e8b25..58c344d4f 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -1,2084 +1,2084 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cClientHandle.h"
-#include "cServer.h"
-#include "cWorld.h"
-#include "cPickup.h"
-#include "cPluginManager.h"
-#include "cPlayer.h"
-#include "cInventory.h"
-#include "cChestEntity.h"
-#include "cSignEntity.h"
-#include "cWindow.h"
-#include "cCraftingWindow.h"
-#include "cItem.h"
-#include "cTorch.h"
-#include "cStairs.h"
-#include "cStep.h"
-#include "cDoors.h"
-#include "cLadder.h"
-#include "cSign.h"
-#include "cRedstone.h"
-#include "cPiston.h"
-#include "cBlockToPickup.h"
-#include "cMonster.h"
-#include "cChatColor.h"
-#include "cSocket.h"
-#include "cTimer.h"
-
-#include "cTracer.h"
-#include "Vector3f.h"
-#include "Vector3d.h"
-
-#include "cSleep.h"
-#include "cRoot.h"
-
-#include "cBlockingTCPLink.h"
-#include "cAuthenticator.h"
-#include "MersenneTwister.h"
-
-#include "packets/cPacket_KeepAlive.h"
-#include "packets/cPacket_Respawn.h"
-#include "packets/cPacket_UpdateHealth.h"
-#include "packets/cPacket_RelativeEntityMoveLook.h"
-#include "packets/cPacket_Chat.h"
-#include "packets/cPacket_Login.h"
-#include "packets/cPacket_WindowClick.h"
-#include "packets/cPacket_TimeUpdate.h"
-#include "packets/cPacket_BlockDig.h"
-#include "packets/cPacket_Handshake.h"
-#include "packets/cPacket_ArmAnim.h"
-#include "packets/cPacket_BlockPlace.h"
-#include "packets/cPacket_Flying.h"
-#include "packets/cPacket_Disconnect.h"
-#include "packets/cPacket_PickupSpawn.h"
-#include "packets/cPacket_ItemSwitch.h"
-#include "packets/cPacket_EntityEquipment.h"
-#include "packets/cPacket_CreativeInventoryAction.h"
-#include "packets/cPacket_NewInvalidState.h"
-#include "packets/cPacket_UseEntity.h"
-#include "packets/cPacket_WindowClose.h"
-#include "packets/cPacket_13.h"
-#include "packets/cPacket_UpdateSign.h"
-#include "packets/cPacket_Ping.h"
-#include "packets/cPacket_NamedEntitySpawn.h"
-#include "packets/cPacket_MapChunk.h"
-#include "packets/cPacket_PreChunk.h"
-
-// DEBUG:
-#include "packets/cPacket_BlockChange.h"
-#include "packets/cPacket_MultiBlock.h"
-
-
-
-
-
-#define AddPistonDir(x, y, z, dir, amount) switch (dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\
- case 2: (z)-=(amount); break; case 3: (z)+=(amount); break;\
- case 4: (x)-=(amount); break; case 5: (x)+=(amount); break; }
-
-
-
-
-
-/// If the number of queued outgoing packets reaches this, the client will be kicked
-#define MAX_OUTGOING_PACKETS 2000
-
-
-
-
-
-#define RECI_RAND_MAX (1.f/RAND_MAX)
-inline int fRadRand(MTRand & r1, int a_BlockCoord)
-{
- return a_BlockCoord * 32 + (int)(16 * ((float)r1.rand() * RECI_RAND_MAX) * 16 - 8);
-}
-
-
-
-
-
-int cClientHandle::s_ClientCount = 0;
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cClientHandle:
-
-cClientHandle::cClientHandle(const cSocket & a_Socket, int a_ViewDistance)
- : m_ViewDistance(a_ViewDistance)
- , m_ProtocolVersion(MCS_PROTOCOL_VERSION)
- , m_Socket(a_Socket)
- , m_bDestroyed(false)
- , m_Player(NULL)
- , m_bKicking(false)
- , m_TimeLastPacket(cWorld::GetTime())
- , m_bKeepThreadGoing(true)
- , m_Ping(1000)
- , m_State(csConnected)
- , m_LastStreamedChunkX(0x7fffffff) // bogus chunk coords to force streaming upon login
- , m_LastStreamedChunkZ(0x7fffffff)
- , m_UniqueID(0)
-{
- s_ClientCount++; // Not protected by CS because clients are always constructed from the same thread
- m_UniqueID = s_ClientCount;
-
- cTimer t1;
- m_LastPingTime = t1.GetNowTime();
-
- // All the packets that can be received from the client
- for (int i = 0; i < ARRAYCOUNT(m_PacketMap); ++i)
- {
- m_PacketMap[i] = NULL;
- }
- m_PacketMap[E_KEEP_ALIVE] = new cPacket_KeepAlive;
- m_PacketMap[E_HANDSHAKE] = new cPacket_Handshake;
- m_PacketMap[E_LOGIN] = new cPacket_Login;
- m_PacketMap[E_PLAYERPOS] = new cPacket_PlayerPosition;
- m_PacketMap[E_PLAYERLOOK] = new cPacket_PlayerLook;
- m_PacketMap[E_PLAYERMOVELOOK] = new cPacket_PlayerMoveLook;
- m_PacketMap[E_PLAYER_ABILITIES] = new cPacket_PlayerAbilities;
- m_PacketMap[E_CHAT] = new cPacket_Chat;
- m_PacketMap[E_ANIMATION] = new cPacket_ArmAnim;
- m_PacketMap[E_FLYING] = new cPacket_Flying;
- m_PacketMap[E_BLOCK_DIG] = new cPacket_BlockDig;
- m_PacketMap[E_BLOCK_PLACE] = new cPacket_BlockPlace;
- m_PacketMap[E_DISCONNECT] = new cPacket_Disconnect;
- m_PacketMap[E_ITEM_SWITCH] = new cPacket_ItemSwitch;
- m_PacketMap[E_ENTITY_EQUIPMENT] = new cPacket_EntityEquipment;
- m_PacketMap[E_CREATIVE_INVENTORY_ACTION] = new cPacket_CreativeInventoryAction;
- m_PacketMap[E_NEW_INVALID_STATE] = new cPacket_NewInvalidState;
- m_PacketMap[E_PICKUP_SPAWN] = new cPacket_PickupSpawn;
- m_PacketMap[E_USE_ENTITY] = new cPacket_UseEntity;
- m_PacketMap[E_WINDOW_CLOSE] = new cPacket_WindowClose;
- m_PacketMap[E_WINDOW_CLICK] = new cPacket_WindowClick;
- m_PacketMap[E_PACKET_13] = new cPacket_13;
- m_PacketMap[E_UPDATE_SIGN] = new cPacket_UpdateSign;
- m_PacketMap[E_RESPAWN] = new cPacket_Respawn;
- m_PacketMap[E_PING] = new cPacket_Ping;
-
- LOG("New ClientHandle created at %p", this);
-}
-
-
-
-
-
-cClientHandle::~cClientHandle()
-{
- LOG("Deleting client \"%s\" at %p", GetUsername().c_str(), this);
-
- // Remove from cSocketThreads, we're not to be called anymore:
- cRoot::Get()->GetServer()->ClientDestroying(this);
-
- {
- cCSLock Lock(m_CSChunkLists);
- m_LoadedChunks.clear();
- m_ChunksToSend.clear();
- }
-
- if (m_Player != NULL)
- {
- cWorld * World = m_Player->GetWorld();
- if (!m_Username.empty() && (World != NULL))
- {
- // Send the Offline PlayerList packet:
- AString NameColor = (m_Player ? m_Player->GetColor() : "");
- cPacket_PlayerListItem PlayerList(NameColor + GetUsername(), false, (short)9999);
- World->Broadcast(PlayerList, this);
-
- // Send the Chat packet:
- cPacket_Chat Left(m_Username + " left the game!");
- World->Broadcast(Left, this);
- }
- if (World != NULL)
- {
- World->RemovePlayer(m_Player);
- }
- }
-
- if (m_Socket.IsValid())
- {
- cPacket_Disconnect Disconnect;
- Disconnect.m_Reason = "Server shut down? Kthnxbai";
- m_Socket.Send(&Disconnect);
- }
-
- if (m_Player != NULL)
- {
- m_Player->Destroy();
- m_Player = NULL;
- }
- for (int i = 0; i < ARRAYCOUNT(m_PacketMap); i++)
- {
- delete m_PacketMap[i];
- }
-
- // Queue all remaining outgoing packets to cSocketThreads:
- {
- cCSLock Lock(m_CSPackets);
- for (PacketList::iterator itr = m_PendingNrmSendPackets.begin(); itr != m_PendingNrmSendPackets.end(); ++itr)
- {
- AString Data;
- (*itr)->Serialize(Data);
- cRoot::Get()->GetServer()->WriteToClient(&m_Socket, Data);
- delete *itr;
- }
- m_PendingNrmSendPackets.clear();
- for (PacketList::iterator itr = m_PendingLowSendPackets.begin(); itr != m_PendingLowSendPackets.end(); ++itr)
- {
- AString Data;
- (*itr)->Serialize(Data);
- cRoot::Get()->GetServer()->WriteToClient(&m_Socket, Data);
- delete *itr;
- }
- m_PendingLowSendPackets.clear();
- }
-
- // Queue the socket to close as soon as it sends all outgoing data:
- cRoot::Get()->GetServer()->QueueClientClose(&m_Socket);
-
- // We need to remove the socket from SocketThreads because we own it and it gets destroyed after this destructor finishes
- // TODO: The socket needs to stay alive, someone else has to own it
- cRoot::Get()->GetServer()->RemoveClient(&m_Socket);
-
- LOG("ClientHandle at %p deleted", this);
-}
-
-
-
-
-
-void cClientHandle::Destroy()
-{
- // Setting m_bDestroyed was moved to the bottom of Destroy(),
- // otherwise the destructor may be called within another thread before the client is removed from chunks
- // http://forum.mc-server.org/showthread.php?tid=366
-
- if ((m_Player != NULL) && (m_Player->GetWorld() != NULL))
- {
- RemoveFromAllChunks();
- m_Player->GetWorld()->RemoveClientFromChunkSender(this);
- }
-
- m_bDestroyed = true;
-}
-
-
-
-
-
-void cClientHandle::Kick(const AString & a_Reason)
-{
- if (m_State >= csAuthenticating) // Don't log pings
- {
- LOG("Kicking user \"%s\" for \"%s\"", m_Username.c_str(), a_Reason.c_str());
- }
- Send(cPacket_Disconnect(a_Reason));
- m_bKicking = true;
-}
-
-
-
-
-
-void cClientHandle::Authenticate(void)
-{
- if (m_State != csAuthenticating)
- {
- return;
- }
-
- ASSERT( m_Player == NULL );
-
- // Spawn player (only serversided, so data is loaded)
- m_Player = new cPlayer(this, GetUsername());
-
- cWorld * World = cRoot::Get()->GetWorld(m_Player->GetLoadedWorldName());
- if (World == NULL)
- {
- World = cRoot::Get()->GetDefaultWorld();
- }
-
- m_Player->LoginSetGameMode (World->GetGameMode()); //set player's gamemode to server's gamemode at login. TODO: set to last player's gamemode at logout
-
- m_Player->SetIP (m_Socket.GetIPString());
-
- cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_PLAYER_SPAWN, 1, m_Player);
-
- // Return a server login packet
- cPacket_Login LoginResponse;
- LoginResponse.m_ProtocolVersion = m_Player->GetUniqueID();
- //LoginResponse.m_Username = "";
- LoginResponse.m_ServerMode = m_Player->GetGameMode(); // set gamemode from player.
- LoginResponse.m_Dimension = 0;
- LoginResponse.m_MaxPlayers = (unsigned char)cRoot::Get()->GetDefaultWorld()->GetMaxPlayers();
- LoginResponse.m_Difficulty = 2;
- Send(LoginResponse);
-
- // Send Weather if raining:
- if ((World->GetWeather() == 1) || (World->GetWeather() == 2))
- {
- cPacket_NewInvalidState RainPacket;
- RainPacket.m_Reason = 1; //begin rain
- Send(RainPacket);
- }
-
- // Send time
- Send(cPacket_TimeUpdate(World->GetWorldTime()));
-
- // Send inventory
- m_Player->GetInventory().SendWholeInventory(this);
-
- // Send health
- cPacket_UpdateHealth Health;
- Health.m_Health = (short)m_Player->GetHealth();
- Health.m_Food = m_Player->GetFood();
- Health.m_Saturation = m_Player->GetFoodSaturation();
- Send(Health);
-
- m_Player->Initialize(World);
- StreamChunks();
- m_State = csDownloadingWorld;
-}
-
-
-
-
-
-void cClientHandle::StreamChunks(void)
-{
- if (m_State < csAuthenticating)
- {
- return;
- }
-
- ASSERT(m_Player != NULL);
-
- int ChunkPosX = FAST_FLOOR_DIV(m_Player->GetPosX(), cChunkDef::Width);
- int ChunkPosZ = FAST_FLOOR_DIV(m_Player->GetPosZ(), cChunkDef::Width);
- if ((ChunkPosX == m_LastStreamedChunkX) && (ChunkPosZ == m_LastStreamedChunkZ))
- {
- // Already streamed for this position
- return;
- }
- m_LastStreamedChunkX = ChunkPosX;
- m_LastStreamedChunkZ = ChunkPosZ;
-
- LOGD("Streaming chunks centered on [%d, %d], view distance %d", ChunkPosX, ChunkPosZ, m_ViewDistance);
-
- cWorld * World = m_Player->GetWorld();
- ASSERT(World != NULL);
-
- // Remove all loaded chunks that are no longer in range; deferred to out-of-CS:
- cChunkCoordsList RemoveChunks;
- {
- cCSLock Lock(m_CSChunkLists);
- for (cChunkCoordsList::iterator itr = m_LoadedChunks.begin(); itr != m_LoadedChunks.end();)
- {
- int RelX = (*itr).m_ChunkX - ChunkPosX;
- int RelZ = (*itr).m_ChunkZ - ChunkPosZ;
- if ((RelX > m_ViewDistance) || (RelX < -m_ViewDistance) || (RelZ > m_ViewDistance) || (RelZ < -m_ViewDistance))
- {
- RemoveChunks.push_back(*itr);
- itr = m_LoadedChunks.erase(itr);
- }
- else
- {
- ++itr;
- }
- } // for itr - m_LoadedChunks[]
- for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end();)
- {
- int RelX = (*itr).m_ChunkX - ChunkPosX;
- int RelZ = (*itr).m_ChunkZ - ChunkPosZ;
- if ((RelX > m_ViewDistance) || (RelX < -m_ViewDistance) || (RelZ > m_ViewDistance) || (RelZ < -m_ViewDistance))
- {
- itr = m_ChunksToSend.erase(itr);
- }
- else
- {
- ++itr;
- }
- } // for itr - m_ChunksToSend[]
- }
- for (cChunkCoordsList::iterator itr = RemoveChunks.begin(); itr != RemoveChunks.end(); ++itr)
- {
- World->RemoveChunkClient(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ, this);
- Send(cPacket_PreChunk(itr->m_ChunkX, itr->m_ChunkZ, false));
- } // for itr - RemoveChunks[]
-
- // Add all chunks that are in range and not yet in m_LoadedChunks:
- // Queue these smartly - from the center out to the edge
- for (int d = 0; d <= m_ViewDistance; ++d) // cycle through (square) distance, from nearest to furthest
- {
- // For each distance add chunks in a hollow square centered around current position:
- for (int i = -d; i <= d; ++i)
- {
- StreamChunk(ChunkPosX + d, ZERO_CHUNK_Y, ChunkPosZ + i);
- StreamChunk(ChunkPosX - d, ZERO_CHUNK_Y, ChunkPosZ + i);
- } // for i
- for (int i = -d + 1; i < d; ++i)
- {
- StreamChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ + d);
- StreamChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ - d);
- } // for i
- } // for d
-
- // Touch chunks GENERATEDISTANCE ahead to let them generate:
- for (int d = m_ViewDistance + 1; d <= m_ViewDistance + GENERATEDISTANCE; ++d) // cycle through (square) distance, from nearest to furthest
- {
- // For each distance touch chunks in a hollow square centered around current position:
- for (int i = -d; i <= d; ++i)
- {
- World->TouchChunk(ChunkPosX + d, ZERO_CHUNK_Y, ChunkPosZ + i);
- World->TouchChunk(ChunkPosX - d, ZERO_CHUNK_Y, ChunkPosZ + i);
- } // for i
- for (int i = -d + 1; i < d; ++i)
- {
- World->TouchChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ + d);
- World->TouchChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ - d);
- } // for i
- } // for d
-}
-
-
-
-
-void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- cWorld * World = m_Player->GetWorld();
- ASSERT(World != NULL);
-
- if (World->AddChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, this))
- {
- {
- cCSLock Lock(m_CSChunkLists);
- m_LoadedChunks.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
- m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
- }
- World->SendChunkTo(a_ChunkX, a_ChunkY, a_ChunkZ, this);
- }
-}
-
-
-
-
-
-// Removes the client from all chunks. Used when switching worlds or destroying the player
-void cClientHandle::RemoveFromAllChunks()
-{
- cWorld * World = m_Player->GetWorld();
- if (World != NULL)
- {
- World->RemoveClientFromChunks(this);
- }
-
- {
- cCSLock Lock(m_CSChunkLists);
- m_LoadedChunks.clear();
- m_ChunksToSend.clear();
- }
-}
-
-
-
-
-
-void cClientHandle::HandlePacket(cPacket * a_Packet)
-{
- m_TimeLastPacket = cWorld::GetTime();
-
- // LOG("Recv packet 0x%02x from client \"%s\" (\"%s\")", a_Packet->m_PacketID, m_Socket.GetIPString().c_str(), m_Username.c_str());
-
- if (m_bKicking)
- {
- return;
- }
-
- switch (m_State)
- {
- case csConnected:
- {
- switch (a_Packet->m_PacketID)
- {
- case E_NEW_INVALID_STATE: // New/Invalid State packet received. I'm guessing the client only sends it when there's a problem with the bed?
- {
- LOGINFO("Got New Invalid State packet");
- break;
- }
- case E_PING: HandlePing (); break;
- case E_HANDSHAKE: HandleHandshake(reinterpret_cast<cPacket_Handshake *>(a_Packet)); break;
- case E_LOGIN: HandleLogin (reinterpret_cast<cPacket_Login *> (a_Packet)); break;
-
- // Ignored packets:
- case E_PLAYERLOOK:
- case E_CHAT:
- case E_PLAYERMOVELOOK:
- case E_PLAYERPOS:
- case E_KEEP_ALIVE: break;
- default: HandleUnexpectedPacket(a_Packet); break;
- } // switch (PacketType)
- break;
- } // case csConnected
-
- case csAuthenticating:
- {
- // Waiting for external authentication, no packets are handled
- switch (a_Packet->m_PacketID)
- {
- // Ignored packets:
- case E_KEEP_ALIVE:
- case E_CHAT:
- case E_FLYING:
- case E_PLAYERLOOK:
- case E_PLAYERMOVELOOK:
- case E_PLAYERPOS: break;
-
- default: HandleUnexpectedPacket(a_Packet); break;
- }
- break;
- }
-
- case csDownloadingWorld:
- {
- // Waiting for chunks to stream to client, no packets are handled
- switch (a_Packet->m_PacketID)
- {
- // Ignored packets:
- case E_KEEP_ALIVE:
- case E_CHAT:
- case E_FLYING:
- case E_PLAYERLOOK:
- case E_PLAYERMOVELOOK:
- case E_PLAYERPOS: break;
-
- default: HandleUnexpectedPacket(a_Packet); break;
- }
- break;
- }
-
- case csConfirmingPos:
- {
- switch (a_Packet->m_PacketID)
- {
- // Ignored packets:
- case E_KEEP_ALIVE:
- case E_CHAT:
- case E_FLYING:
- case E_PLAYERLOOK:
- case E_PLAYERPOS: break;
-
- case E_PLAYERMOVELOOK: HandleMoveLookConfirm(reinterpret_cast<cPacket_PlayerMoveLook *>(a_Packet)); break;
-
- default:
- {
- HandleUnexpectedPacket(a_Packet);
- break;
- }
- } // switch (PacketType)
- break;
- } // case csConfirmingPos
-
- case csPlaying:
- {
- switch (a_Packet->m_PacketID)
- {
- case E_CREATIVE_INVENTORY_ACTION: HandleCreativeInventory(reinterpret_cast<cPacket_CreativeInventoryAction *>(a_Packet)); break;
- case E_PLAYERPOS: HandlePlayerPos (reinterpret_cast<cPacket_PlayerPosition *> (a_Packet)); break;
- case E_BLOCK_DIG: HandleBlockDig (reinterpret_cast<cPacket_BlockDig *> (a_Packet)); break;
- case E_BLOCK_PLACE: HandleBlockPlace (reinterpret_cast<cPacket_BlockPlace *> (a_Packet)); break;
- case E_PICKUP_SPAWN: HandlePickupSpawn (reinterpret_cast<cPacket_PickupSpawn *> (a_Packet)); break;
- case E_CHAT: HandleChat (reinterpret_cast<cPacket_Chat *> (a_Packet)); break;
- case E_PLAYERLOOK: HandlePlayerLook (reinterpret_cast<cPacket_PlayerLook *> (a_Packet)); break;
- case E_PLAYERMOVELOOK: HandlePlayerMoveLook (reinterpret_cast<cPacket_PlayerMoveLook *> (a_Packet)); break;
- case E_ANIMATION: HandleAnimation (reinterpret_cast<cPacket_ArmAnim *> (a_Packet)); break;
- case E_ITEM_SWITCH: HandleItemSwitch (reinterpret_cast<cPacket_ItemSwitch *> (a_Packet)); break;
- case E_WINDOW_CLOSE: HandleWindowClose (reinterpret_cast<cPacket_WindowClose *> (a_Packet)); break;
- case E_WINDOW_CLICK: HandleWindowClick (reinterpret_cast<cPacket_WindowClick *> (a_Packet)); break;
- case E_UPDATE_SIGN: HandleUpdateSign (reinterpret_cast<cPacket_UpdateSign *> (a_Packet)); break;
- case E_USE_ENTITY: HandleUseEntity (reinterpret_cast<cPacket_UseEntity *> (a_Packet)); break;
- case E_RESPAWN: HandleRespawn(); break;
- case E_DISCONNECT: HandleDisconnect (reinterpret_cast<cPacket_Disconnect *> (a_Packet)); break;
- case E_KEEP_ALIVE: HandleKeepAlive (reinterpret_cast<cPacket_KeepAlive *> (a_Packet)); break;
- } // switch (Packet type)
- break;
- } // case csPlaying
- } // switch (m_State)
-}
-
-
-
-
-
-void cClientHandle::HandlePing(void)
-{
- // Somebody tries to retrieve information about the server
- AString Reply;
- Printf(Reply, "%s%s%i%s%i",
- cRoot::Get()->GetDefaultWorld()->GetDescription().c_str(),
- cChatColor::Delimiter.c_str(),
- cRoot::Get()->GetDefaultWorld()->GetNumPlayers(),
- cChatColor::Delimiter.c_str(),
- cRoot::Get()->GetDefaultWorld()->GetMaxPlayers()
- );
- Kick(Reply.c_str());
-}
-
-
-
-
-
-void cClientHandle::HandleHandshake(cPacket_Handshake * a_Packet)
-{
- AStringVector UserData = StringSplit( a_Packet->m_Username, ";" ); // "FakeTruth;localhost:25565"
- if( UserData.size() == 0 )
- {
- Kick("Could not receive username");
- return;
- }
- m_Username = UserData[0];
-
- LOG("HANDSHAKE %s", m_Username.c_str());
-
- if (cRoot::Get()->GetDefaultWorld()->GetNumPlayers() >= cRoot::Get()->GetDefaultWorld()->GetMaxPlayers())
- {
- Kick("The server is currently full :(-- Try again later");
- return;
- }
- cPacket_Chat Connecting(m_Username + " is connecting.");
- cRoot::Get()->GetServer()->Broadcast(Connecting, this);
-
- cPacket_Handshake Handshake;
- Handshake.m_Username = cRoot::Get()->GetServer()->GetServerID();
- Send(Handshake);
- LOG("User \"%s\" was sent a handshake", m_Username.c_str());
-}
-
-
-
-
-
-void cClientHandle::HandleLogin(cPacket_Login * a_Packet)
-{
- LOG("LOGIN %s", m_Username.c_str());
- if (a_Packet->m_ProtocolVersion < m_ProtocolVersion)
- {
- Kick("Your client is outdated!");
- return;
- }
- else if (a_Packet->m_ProtocolVersion > m_ProtocolVersion)
- {
- Kick("Your client version is higher than the server!");
- return;
- }
- if (m_Username.compare(a_Packet->m_Username) != 0)
- {
- LOGWARNING("Login Username (\"%s\") does not match Handshake username (\"%s\") for client \"%s\")",
- a_Packet->m_Username.c_str(),
- m_Username.c_str(),
- m_Socket.GetIPString().c_str()
- );
- Kick("Hacked client"); // Don't tell them why we don't want them
- return;
- }
-
- if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_LOGIN, 1, a_Packet))
- {
- Destroy();
- return;
- }
-
- // Schedule for authentication; until then, let them wait (but do not block)
- m_State = csAuthenticating;
- cRoot::Get()->GetAuthenticator().Authenticate(GetUniqueID(), GetUsername(), cRoot::Get()->GetServer()->GetServerID());
-}
-
-
-
-
-
-void cClientHandle::HandleUnexpectedPacket(cPacket * a_Packet)
-{
- LOGWARNING(
- "Invalid packet in state %d: 0x%02x from client \"%s\", username \"%s\"",
- m_State,
- a_Packet->m_PacketID,
- m_Socket.GetIPString().c_str(),
- m_Username.c_str()
- );
- Kick("Hacked client"); // Don't tell them why we don't like them
-}
-
-
-
-
-
-void cClientHandle::HandleMoveLookConfirm(cPacket_PlayerMoveLook * a_Packet)
-{
- Vector3d ReceivedPosition = Vector3d(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
-
- // Test the distance between points with a small/large enough value instead of comparing directly. Floating point inaccuracies might screw stuff up
- double Dist = (ReceivedPosition - m_ConfirmPosition).SqrLength();
- if (Dist < 1.0)
- {
- // Test
- if (ReceivedPosition.Equals(m_ConfirmPosition))
- {
- LOGINFO("Exact position confirmed by client!");
- }
- m_State = csPlaying;
- }
- else
- {
- LOGWARNING("Player \"%s\" sent a weird position confirmation %.2f blocks away, retrying", m_Username.c_str(), Dist);
- m_ConfirmPosition = m_Player->GetPosition();
- Send(cPacket_PlayerMoveLook(m_Player));
- }
-}
-
-
-
-
-
-void cClientHandle::HandleCreativeInventory(cPacket_CreativeInventoryAction * a_Packet)
-{
- // This is for creative Inventory changes
- if (m_Player->GetGameMode() == 1)
- {
- m_Player->GetInventory().Clicked(a_Packet);
- }
- else
- {
- LOGWARNING("Got a CreativeInventoryAction packet from user \"%s\" while not in creative mode. Ignoring.", m_Username.c_str());
- }
-}
-
-
-
-
-
-void cClientHandle::HandlePlayerPos(cPacket_PlayerPosition * a_Packet)
-{
- // LOG("recv player pos: %0.2f %0.2f %0.2f", PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ);
- m_Player->MoveTo(Vector3d(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ));
- m_Player->SetStance(a_Packet->m_Stance);
- m_Player->SetTouchGround(a_Packet->m_bFlying);
-}
-
-
-
-
-
-void cClientHandle::HandleBlockDig(cPacket_BlockDig * a_Packet)
-{
- if (!CheckBlockInteractionsRate())
- {
- return;
- }
-
- LOGD("OnBlockDig: {%i, %i, %i} Dir: %i Stat: %i",
- a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ,
- a_Packet->m_Direction, a_Packet->m_Status
- );
-
- // Do we want plugins to disable tossing items? Probably no, so toss item before asking plugins for permission
- if (a_Packet->m_Status == 0x04) // Drop held item
- {
- m_Player->TossItem(false);
- return;
- }
-
- cWorld* World = m_Player->GetWorld();
- BLOCKTYPE OldBlock = World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
- NIBBLETYPE OldMeta = World->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
-
- if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_BLOCK_DIG, 4, a_Packet, m_Player, OldBlock, OldMeta))
- {
- // The plugin doesn't agree with the digging, replace the block on the client and quit:
- World->SendBlockTo(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, m_Player);
- return;
- }
-
- bool bBroken = (
- (a_Packet->m_Status == 0x02) ||
- (g_BlockOneHitDig[(int)OldBlock]) ||
- ((a_Packet->m_Status == 0x00) && (m_Player->GetGameMode() == 1))
- );
-
- if ((OldBlock == E_BLOCK_WOODEN_DOOR) && !bBroken)
- {
- cDoors::ChangeDoor(m_Player->GetWorld(), a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
- }
-
- cItems PickupItems;
- if (bBroken && !(m_Player->GetGameMode() == 1)) // broken
- {
- cBlockToPickup::ToPickup(OldBlock, OldMeta, m_Player->GetInventory().GetEquippedItem(), PickupItems);
-
- // Allow plugins to change the dropped objects:
- cRoot::Get()->GetPluginManager()->CallHookBlockToPickup(OldBlock, OldMeta, m_Player, m_Player->GetInventory().GetEquippedItem(), PickupItems);
- }
-
- int pX = a_Packet->m_PosX;
- unsigned char pY = a_Packet->m_PosY;
- int pZ = a_Packet->m_PosZ;
-
- AddDirection(pX, pY, pZ, a_Packet->m_Direction);
-
- char PossibleBlock = World->GetBlock(pX, pY, pZ);
-
- if (PossibleBlock == E_BLOCK_FIRE)
- {
- a_Packet->m_PosX = pX;
- a_Packet->m_PosY = pY;
- a_Packet->m_PosZ = pZ;
- bBroken = true;
- }
-
- if (!bBroken)
- {
- return;
- }
-
- if (!World->DigBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ))
- {
- return;
- }
-
- World->SpawnItemPickups(PickupItems, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
-
- switch (OldBlock)
- {
- case E_BLOCK_REDSTONE_TORCH_ON:
- case E_BLOCK_REDSTONE_TORCH_OFF:
- case E_BLOCK_REDSTONE_WIRE:
- {
- cRedstone Redstone(World);
- Redstone.ChangeRedstone(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, false);
- break;
- }
- }
-
- if ((OldBlock == E_BLOCK_PISTON) || (OldBlock == E_BLOCK_STICKY_PISTON))
- {
- int newX = a_Packet->m_PosX;
- int newY = a_Packet->m_PosY;
- int newZ = a_Packet->m_PosZ;
- AddPistonDir(newX, newY, newZ, OldMeta & ~(8), 1);
- if (World->GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION)
- {
- World->SetBlock(newX, newY, newZ, E_BLOCK_AIR, 0);
- }
- }
-
- if (cDoors::IsDoor(OldBlock))
- {
- // Special actions for destroyed door (Destroy second part)
- if (OldMeta & 8)
- {
- // Was upper part of door
- if (cDoors::IsDoor(World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY - 1, a_Packet->m_PosZ)))
- {
- World->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY - 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0);
- }
- }
- else
- {
- // Was lower part
- if (cDoors::IsDoor(World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ)))
- {
- World->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0);
- }
- }
- }
-
- m_Player->UseEquippedItem();
-}
-
-
-
-
-
-void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet)
-{
- if (!CheckBlockInteractionsRate())
- {
- return;
- }
-
- cItem & Equipped = m_Player->GetInventory().GetEquippedItem();
-
- if ((Equipped.m_ItemID != a_Packet->m_ItemType)) // Not valid
- {
- LOGWARN("Player %s tried to place a block that was not equipped (exp %d, got %d)",
- m_Username.c_str(), Equipped.m_ItemID, a_Packet->m_ItemType
- );
- // TODO: We should probably send the current world block to the client, so that it can immediately "let the user know" that they haven't placed the block
- return;
- }
-
- if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_BLOCK_PLACE, 2, a_Packet, m_Player))
- {
- if (a_Packet->m_Direction > -1)
- {
- AddDirection(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Direction);
- m_Player->GetWorld()->SendBlockTo(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, m_Player);
- }
- return;
- }
-
- //LOG("%i %i %i %i %i %i", a_Packet->m_Count, a_Packet->m_Direction, a_Packet->m_ItemType, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
-
- //printf("Place Dir:%i %i %i %i : %i\n", a_Packet->m_Direction, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_ItemType);
- // 'use' useable items instead of placing blocks
- bool bPlaceBlock = true;
- bool UpdateRedstone = false;
- bool AddedCurrent = false;
-
- if (a_Packet->m_Direction >= 0)
- {
- cWorld * World = m_Player->GetWorld();
- BLOCKTYPE BlockType = 0;
- NIBBLETYPE BlockMeta;
- World->GetBlockTypeMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, BlockType, BlockMeta);
- switch (BlockType)
- {
- case E_BLOCK_REDSTONE_REPEATER_ON:
- case E_BLOCK_REDSTONE_REPEATER_OFF:
- {
- // no need to update redstone current with a repeater
- // Find meta value of repeater and change it to one step more:
- World->FastSetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, BlockType, ((BlockMeta + 0x04) & 0x0f));
- bPlaceBlock = false;
- break;
- }
-
- case E_BLOCK_WORKBENCH:
- {
- bPlaceBlock = false;
- cWindow* Window = new cCraftingWindow(0, true);
- m_Player->OpenWindow(Window);
- break;
- }
-
- case E_BLOCK_FURNACE:
- case E_BLOCK_CHEST:
- {
- bPlaceBlock = false;
- m_Player->GetWorld()->UseBlockEntity(m_Player, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
- break;
- }
-
- case E_BLOCK_WOODEN_DOOR:
- {
- bPlaceBlock = false;
- cDoors::ChangeDoor(m_Player->GetWorld(), a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
- break;
- }
-
- default:
- {
- break;
- }
- } // switch (BlockID)
- } // if (Direction >= 0)
-
- // Some checks to see if it's a placeable item :P
- if (bPlaceBlock)
- {
- cItem Item;
- Item.m_ItemID = Equipped.m_ItemID;
- Item.m_ItemCount = 1;
- LOGD("Placing item of type %i at {%d, %d, %d}",
- (int)a_Packet->m_ItemType,
- a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ
- );
-
- if (m_Player->EatItem(Item.m_ItemID))
- {
- m_Player->GetInventory().RemoveItem(Item);
- return;
- }
-
- if (a_Packet->m_Direction < 0)
- {
- // clicked in air
- return;
- }
- bool isDoor = false;
-
- //TODO: Wrong Blocks!
- BLOCKTYPE ClickedBlock = m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
-
- if (ItemCategory::IsHoe(Item.m_ItemID))
- {
- if ((ClickedBlock == E_BLOCK_DIRT) || (ClickedBlock == E_BLOCK_GRASS))
- {
- m_Player->GetWorld()->FastSetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, E_BLOCK_FARMLAND, 0);
- }
- return;
- }
-
- NIBBLETYPE MetaData = (NIBBLETYPE)Equipped.m_ItemHealth; // This generally works for logs & planks, others will override
- bool LavaBucket = false;
- bool WaterBucket = false;
- bool bRemoveItem = true;
- bool bIgnoreCollision = false;
-
- if (ClickedBlock == E_BLOCK_STEP)
- {
- // Only make double slab if meta values are the same and if player clicked either on top or on bottom of the block (direction either 0 or 1)
- // TODO check if it works from beneath
- if (MetaData == ( m_Player->GetWorld()->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ) & 0x7) && a_Packet->m_Direction <= 1)
- //if (MetaData == m_Player->GetWorld()->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ) && a_Packet->m_Direction == 1)
- {
- a_Packet->m_ItemType = E_BLOCK_DOUBLE_STEP;
- if(a_Packet->m_Direction == 1)
- {
- a_Packet->m_PosY--;
- }
- else
- {
- a_Packet->m_PosY++;
- }
- bIgnoreCollision = true;
- }
- }
-
- // Special handling for special items:
- switch (a_Packet->m_ItemType)
- {
- case E_ITEM_BUCKET:
- {
- // TODO: Change this, it is just a small hack to get it working a little bit. seems like the Client sends the position from the first hitable block :s
- ClickedBlock = (int)m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ);
- LOG("Bucket Clicked BlockID: %d", ClickedBlock);
- switch (ClickedBlock)
- {
- case E_BLOCK_WATER:
- case E_BLOCK_STATIONARY_WATER:
- {
- WaterBucket = true;
- break;
- }
- case E_BLOCK_LAVA:
- case E_BLOCK_STATIONARY_LAVA:
- {
- LavaBucket = true;
- break;
- }
- }
- break;
- } // case E_ITEM_BUCKET
-
- case E_ITEM_LAVA_BUCKET:
- {
- if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item)))
- {
- a_Packet->m_ItemType = E_BLOCK_LAVA;
- if (m_Player->GetGameMode() == 1)
- {
- break; //No new Bucket for creative players
- }
-
- cItem NewItem;
- NewItem.m_ItemID = E_ITEM_BUCKET;
- NewItem.m_ItemCount = 1;
- m_Player->GetInventory().AddItem(NewItem);
- }
- break;
- } // case E_ITEM_LAVA_BUCKET
-
- case E_ITEM_WATER_BUCKET:
- {
- if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item)))
- {
- a_Packet->m_ItemType = E_BLOCK_WATER;
- if (m_Player->GetGameMode() == 1)
- {
- break; //No new Bucket for creative players
- }
- cItem NewItem;
- NewItem.m_ItemID = E_ITEM_BUCKET;
- NewItem.m_ItemCount = 1;
- m_Player->GetInventory().AddItem(NewItem);
- }
- break;
- }
-
- case E_BLOCK_TORCH:
- {
- MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction);
- break;
- }
-
- case E_BLOCK_REDSTONE_TORCH_OFF:
- {
- MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction);
- if (g_BlockTransparent[ (int)m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY+2, a_Packet->m_PosZ) ] == true)
- {
- //if block above is transparent
- //printf("transparent above me\n");
- }
- else
- {
- //printf("transparent not above me\n");
- }
- UpdateRedstone = true;
- AddedCurrent = false;
- break;
- }
-
- case E_BLOCK_REDSTONE_TORCH_ON:
- {
- MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction);
- UpdateRedstone = true;
- AddedCurrent = true;
- break;
- }
-
- case E_ITEM_REDSTONE_DUST:
- {
- MetaData = 0;
- a_Packet->m_ItemType = E_BLOCK_REDSTONE_WIRE;
- UpdateRedstone = true;
- AddedCurrent = false;
- break;
- }
-
- case E_ITEM_REDSTONE_REPEATER:
- {
- MetaData = cRedstone::RepeaterRotationToMetaData(m_Player->GetRotation());
- a_Packet->m_ItemType = E_BLOCK_REDSTONE_REPEATER_OFF;
- UpdateRedstone = true;
- AddedCurrent = false;
- break;
- }
-
- case E_BLOCK_PISTON:
- case E_BLOCK_STICKY_PISTON:
- {
- MetaData = cPiston::RotationPitchToMetaData(m_Player->GetRotation(), m_Player->GetPitch());
- UpdateRedstone = true;
- AddedCurrent = false;
- break;
- }
-
- case E_ITEM_IRON_DOOR:
- {
- a_Packet->m_ItemType = E_BLOCK_IRON_DOOR;
- MetaData = cDoors::RotationToMetaData(m_Player->GetRotation());
- isDoor = true;
- break;
- }
-
- case E_ITEM_WOODEN_DOOR:
- {
- a_Packet->m_ItemType = E_BLOCK_WOODEN_DOOR;
- MetaData = cDoors::RotationToMetaData(m_Player->GetRotation());
- isDoor = true;
- break;
- }
-
- case E_BLOCK_CHEST:
- case E_BLOCK_FURNACE:
- case E_BLOCK_DISPENSER:
- {
- MetaData = cPiston::RotationPitchToMetaData(m_Player->GetRotation(), 0); // Same orientation as pistons, just ignore pitch
- break;
- }
-
- case E_BLOCK_STEP:
- {
- MetaData += cStep::DirectionToMetaData( a_Packet->m_Direction );
- break;
- }
-
- case E_BLOCK_COBBLESTONE_STAIRS:
- case E_BLOCK_BRICK_STAIRS:
- case E_BLOCK_STONE_BRICK_STAIRS:
- case E_BLOCK_NETHER_BRICK_STAIRS:
- case E_BLOCK_WOODEN_STAIRS:
- {
- MetaData = cStairs::RotationToMetaData(m_Player->GetRotation(), a_Packet->m_Direction);
- break;
- }
- case E_BLOCK_LADDER:
- {
- MetaData = cLadder::DirectionToMetaData(a_Packet->m_Direction);
- break;
- }
- case E_ITEM_SIGN:
- {
- LOGD("Sign Dir: %i", a_Packet->m_Direction);
- if (a_Packet->m_Direction == 1)
- {
- LOGD("Player Rotation: %f", m_Player->GetRotation());
- MetaData = cSign::RotationToMetaData(m_Player->GetRotation());
- LOGD("Sign rotation %i", MetaData);
- a_Packet->m_ItemType = E_BLOCK_SIGN_POST;
- }
- else
- {
- MetaData = cSign::DirectionToMetaData(a_Packet->m_Direction);
- a_Packet->m_ItemType = E_BLOCK_WALLSIGN;
- }
- break;
- }
-
- case E_ITEM_FLINT_AND_STEEL:
- {
- a_Packet->m_ItemType = E_ITEM_FIRE;
- m_Player->UseEquippedItem();
- bRemoveItem = false;
- break;
- }
- case E_ITEM_SEEDS:
- {
- if (ClickedBlock != E_BLOCK_FARMLAND)
- {
- return;
- }
- a_Packet->m_ItemType = E_BLOCK_CROPS;
- break;
- }
- case E_ITEM_MELON_SEEDS:
- {
- if (ClickedBlock != E_BLOCK_FARMLAND)
- {
- return;
- }
- a_Packet->m_ItemType = E_BLOCK_MELON_STEM;
- break;
- }
- case E_ITEM_PUMPKIN_SEEDS:
- {
- if (ClickedBlock != E_BLOCK_FARMLAND)
- {
- return;
- }
- a_Packet->m_ItemType = E_BLOCK_PUMPKIN_STEM;
- break;
- }
- case E_ITEM_DYE:
- {
- // Handle bonemeal and dyes on sheep
- if (HandleDyes(a_Packet))
- {
- if (m_Player->GetGameMode() == eGameMode_Survival)
- {
- m_Player->GetInventory().RemoveItem(Item);
- }
- return;
- }
- break;
- }
- case E_ITEM_SUGARCANE:
- {
- a_Packet->m_ItemType = E_BLOCK_SUGARCANE;
- break;
- }
- default:
- {
- break;
- }
- } // switch (a_Packet->m_ItemType)
-
-
- if (LavaBucket)
- {
- if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item))) {
- cItem NewItem;
- NewItem.m_ItemID = E_ITEM_LAVA_BUCKET;
- NewItem.m_ItemCount = 1;
- m_Player->GetInventory().AddItem(NewItem);
- m_Player->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0);
- }
- }
- else if (WaterBucket)
- {
- if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item)))
- {
- cItem NewItem;
- NewItem.m_ItemID = E_ITEM_WATER_BUCKET;
- NewItem.m_ItemCount = 1;
- m_Player->GetInventory().AddItem(NewItem);
- m_Player->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0);
- }
- }
- else if (IsValidBlock(a_Packet->m_ItemType))
- {
- int X = a_Packet->m_PosX;
- int Y = a_Packet->m_PosY;
- int Z = a_Packet->m_PosZ;
- AddDirection(X, Y, Z, a_Packet->m_Direction);
-
- int PlaceBlock = m_Player->GetWorld()->GetBlock(X, Y, Z);
- if (
- (PlaceBlock != E_BLOCK_AIR)
- && (PlaceBlock != E_BLOCK_WATER)
- && (PlaceBlock != E_BLOCK_STATIONARY_WATER)
- && (PlaceBlock != E_BLOCK_LAVA)
- && (PlaceBlock != E_BLOCK_STATIONARY_LAVA)
- && !bIgnoreCollision
- )
- {
- //tried to place a block *into* another?
- return; // happens when you place a block aiming at side of block like torch or stem
- }
-
- // Check whether selected item is allowed to be placed on specific surface
- if (!m_Player->GetWorld()->IsPlacingItemLegal(a_Packet->m_ItemType, X, Y, Z))
- {
- // If we don't send the block, MC is happy placing cacti underwater:
- m_Player->GetWorld()->SendBlockTo(X, Y, Z, m_Player);
- return;
- }
-
- if (bRemoveItem)
- {
- if ((m_Player->GetGameMode() != 1) && !m_Player->GetInventory().RemoveItem(Item))
- {
- return;
- }
- }
-
-
- if (isDoor)
- {
- if ((m_Player->GetWorld()->GetBlock(X, Y + 1, Z) == E_BLOCK_AIR) || (m_Player->GetWorld()->GetBlock(X, Y + 1, Z) == E_BLOCK_AIR))
- {
- m_Player->GetWorld()->SetBlock(X, Y + 1, Z, (char)a_Packet->m_ItemType, MetaData + 8);
- m_Player->GetWorld()->SetBlock(X, Y, Z, (char)a_Packet->m_ItemType, MetaData);
- }
- }
- else
- {
- m_Player->GetWorld()->SetBlock(X, Y, Z, (char)a_Packet->m_ItemType, MetaData);
- }
-
- if (UpdateRedstone)
- {
- cRedstone Redstone(m_Player->GetWorld());
- Redstone.ChangeRedstone(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, AddedCurrent);
- }
- }
- }
-
- /*
- // FakeTruth's "magic stick of removal" :D
- // TODO: Turn this into a plugin
- if (m_Username.compare("FakeTruth") == 0)
- {
- if (a_Packet->m_ItemType == 280)
- {
- cRoot::Get()->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, 0, 0);
- }
- }
- */
-}
-
-
-
-
-
-void cClientHandle::HandlePickupSpawn(cPacket_PickupSpawn * a_Packet)
-{
- LOG("Received packet E_PICKUP_SPAWN");
-
- cItem DroppedItem;
- DroppedItem.m_ItemID = (ENUM_ITEM_ID)a_Packet->m_Item;
- DroppedItem.m_ItemCount = a_Packet->m_Count;
- DroppedItem.m_ItemHealth = 0x0; // TODO: Somehow figure out what item was dropped, and apply correct health
- if (m_Player->GetInventory().RemoveItem(DroppedItem))
- {
- cPickup * Pickup = new cPickup(a_Packet);
- Pickup->Initialize(m_Player->GetWorld());
- }
-}
-
-
-
-
-
-void cClientHandle::HandleChat(cPacket_Chat * a_Packet)
-{
- if (!cRoot::Get()->GetServer()->Command(*this, a_Packet->m_Message.c_str()))
- {
- a_Packet->m_Message.insert(0, "<" + m_Player->GetColor() + m_Username + cChatColor::White + "> ");
- cRoot::Get()->GetServer()->Broadcast(*a_Packet);
- }
-}
-
-
-
-
-
-void cClientHandle::HandlePlayerLook(cPacket_PlayerLook * a_Packet)
-{
- m_Player->SetRotation (a_Packet->m_Rotation);
- m_Player->SetPitch (a_Packet->m_Pitch);
- m_Player->SetTouchGround(a_Packet->m_bFlying);
- m_Player->WrapRotation();
-}
-
-
-
-
-
-void cClientHandle::HandlePlayerMoveLook(cPacket_PlayerMoveLook * a_Packet)
-{
- m_Player->MoveTo(Vector3d(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ));
- m_Player->SetStance (a_Packet->m_Stance);
- m_Player->SetTouchGround(a_Packet->m_bFlying);
- m_Player->SetRotation (a_Packet->m_Rotation);
- m_Player->SetPitch (a_Packet->m_Pitch);
- m_Player->WrapRotation();
-}
-
-
-
-
-
-void cClientHandle::HandleAnimation(cPacket_ArmAnim * a_Packet)
-{
- a_Packet->m_EntityID = m_Player->GetUniqueID();
- cRoot::Get()->GetServer()->Broadcast(*a_Packet, this);
-}
-
-
-
-
-
-void cClientHandle::HandleItemSwitch(cPacket_ItemSwitch * a_Packet)
-{
- m_Player->GetInventory().SetEquippedSlot(a_Packet->m_SlotNum);
-
- cPacket_EntityEquipment Equipment;
- Equipment.m_ItemID = (short)m_Player->GetInventory().GetEquippedItem().m_ItemID;
- Equipment.m_Slot = 0;
- Equipment.m_UniqueID = m_Player->GetUniqueID();
- cRoot::Get()->GetServer()->Broadcast(Equipment, this);
-}
-
-
-
-
-
-void cClientHandle::HandleWindowClose(cPacket_WindowClose * a_Packet)
-{
- m_Player->CloseWindow(a_Packet->m_Close);
-}
-
-
-
-
-
-void cClientHandle::HandleWindowClick(cPacket_WindowClick * a_Packet)
-{
- if (a_Packet->m_WindowID == 0)
- {
- m_Player->GetInventory().Clicked(a_Packet);
- return;
- }
-
- cWindow * Window = m_Player->GetWindow();
- if (Window == NULL)
- {
- LOGWARNING("Player \"%s\" clicked in a non-existent window. Ignoring", m_Username.c_str());
- return;
- }
-
- Window->Clicked(a_Packet, *m_Player);
-}
-
-
-
-
-
-void cClientHandle::HandleUpdateSign(cPacket_UpdateSign * a_Packet)
-{
- cWorld * World = m_Player->GetWorld();
- World->UpdateSign(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Line1, a_Packet->m_Line2, a_Packet->m_Line3, a_Packet->m_Line4);
-}
-
-
-
-
-
-void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet)
-{
- if (!a_Packet->m_bLeftClick)
- {
- return;
- }
-
- class cDamageEntity : public cEntityCallback
- {
- virtual bool Item(cEntity * a_Entity) override
- {
- if( a_Entity->IsA("cPawn") )
- {
- reinterpret_cast< cPawn* >( a_Entity )->TakeDamage(Damage, Instigator );
- }
- return true;
- }
- public:
- int Damage;
- cEntity * Instigator;
- } Callback;
-
- Callback.Damage = 1; // TODO: Find proper damage from current item equipped
- Callback.Instigator = m_Player;
-
- cWorld * World = m_Player->GetWorld();
- World->DoWithEntity( a_Packet->m_TargetID, Callback );
-}
-
-
-
-
-
-void cClientHandle::HandleRespawn(void)
-{
- m_Player->Respawn();
-}
-
-
-
-
-
-void cClientHandle::HandleDisconnect(cPacket_Disconnect * a_Packet)
-{
- LOG("Received d/c packet from \"%s\"", m_Username.c_str());
- if (!cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_DISCONNECT, 2, a_Packet->m_Reason.c_str(), m_Player))
- {
- cPacket_Chat DisconnectMessage(m_Username + " disconnected: " + a_Packet->m_Reason);
- cRoot::Get()->GetServer()->Broadcast(DisconnectMessage);
- }
- Destroy();
-}
-
-
-
-
-
-void cClientHandle::HandleKeepAlive(cPacket_KeepAlive * a_Packet)
-{
- if (a_Packet->m_KeepAliveID == m_PingID)
- {
- cTimer t1;
- m_Ping = (short)((t1.GetNowTime() - m_PingStartTime) / 2);
- }
-}
-
-
-
-
-
-bool cClientHandle::HandleDyes(cPacket_BlockPlace * a_Packet)
-{
- cItem & Equipped = m_Player->GetInventory().GetEquippedItem();
-
- // TODO: Handle coloring the sheep, too
-
- // Handle growing the plants:
- if (Equipped.m_ItemHealth == E_META_DYE_WHITE)
- {
- cWorld * World = m_Player->GetWorld();
- return World->GrowPlant(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, true);
- }
-
- return false;
-}
-
-
-
-
-
-bool cClientHandle::CheckBlockInteractionsRate(void)
-{
- ASSERT(m_Player != NULL);
- ASSERT(m_Player->GetWorld() != NULL);
- int LastActionCnt = m_Player->GetLastBlockActionCnt();
- if ((m_Player->GetWorld()->GetTime() - m_Player->GetLastBlockActionTime()) < 0.1)
- {
- // Limit the number of block interactions per tick
- m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time.
- m_Player->SetLastBlockActionCnt(LastActionCnt + 1);
- if (m_Player->GetLastBlockActionCnt() > MAXBLOCKCHANGEINTERACTIONS)
- {
- // Kick if more than MAXBLOCKCHANGEINTERACTIONS per tick
- LOGWARN("Player %s tried to interact with a block too quickly! (could indicate bot) Was Kicked.", m_Username.c_str());
- Kick("You're a baaaaaad boy!");
- return false;
- }
- }
- else
- {
- m_Player->SetLastBlockActionCnt(0); // Reset count
- m_Player->SetLastBlockActionTime(); // Player tried to interact with a block. Reset last block interation time.
- }
- return true;
-}
-
-
-
-
-
-void cClientHandle::Tick(float a_Dt)
-{
- (void)a_Dt;
- if (cWorld::GetTime() - m_TimeLastPacket > 30.f) // 30 seconds time-out
- {
- cPacket_Disconnect DC("Nooooo!! You timed out! D: Come back!");
- m_Socket.Send(&DC);
-
- // TODO: Cannot sleep in the tick thread!
- cSleep::MilliSleep(1000); // Give packet some time to be received
-
- Destroy();
- }
-
- cTimer t1;
- // Send ping packet
- if (m_LastPingTime + cClientHandle::PING_TIME_MS <= t1.GetNowTime())
- {
- m_PingID++;
- cPacket_KeepAlive Ping(m_PingID);
- m_PingStartTime = t1.GetNowTime();
- Send(Ping);
- m_LastPingTime = m_PingStartTime;
- }
-}
-
-
-
-
-
-void cClientHandle::Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority /* = E_PRIORITY_NORMAL */)
-{
- if (m_bKicking) return; // Don't add more packets if player is getting kicked anyway
-
- // If it is the packet spawning myself for myself, drop it silently:
- if (a_Packet.m_PacketID == E_NAMED_ENTITY_SPAWN)
- {
- if (((cPacket_NamedEntitySpawn &)a_Packet).m_UniqueID == m_Player->GetUniqueID())
- {
- return;
- }
- }
-
- // Filter out packets that don't belong to a csDownloadingWorld state:
- if (m_State == csDownloadingWorld)
- {
- switch (a_Packet.m_PacketID)
- {
- case E_PLAYERMOVELOOK:
- case E_KEEP_ALIVE:
- case E_PRE_CHUNK:
- case E_MAP_CHUNK:
- {
- // Allow
- break;
- }
- default: return;
- }
- }
-
- // Filter out map chunks that the client doesn't want anymore:
- if (a_Packet.m_PacketID == E_MAP_CHUNK)
- {
- // Check chunks being sent, erase them from m_ChunksToSend:
- int ChunkX = ((cPacket_MapChunk &)a_Packet).m_PosX;
- int ChunkZ = ((cPacket_MapChunk &)a_Packet).m_PosZ;
- bool Found = false;
- cCSLock Lock(m_CSChunkLists);
- for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end(); ++itr)
- {
- if ((itr->m_ChunkX == ChunkX) && (itr->m_ChunkZ == ChunkZ))
- {
- m_ChunksToSend.erase(itr);
- CheckIfWorldDownloaded();
- Found = true;
- break;
- }
- } // for itr - m_ChunksToSend[]
- if (!Found)
- {
- // This just sometimes happens. If you have a reliably replicatable situation for this, go ahead and fix it
- // It's not a big issue anyway, just means that some chunks may be compressed several times
- // LOGD("Refusing to send chunk [%d, %d] to client \"%s\" at [%d, %d].", ChunkX, ChunkZ, m_Username.c_str(), m_Player->GetChunkX(), m_Player->GetChunkZ());
- return;
- }
- }
-
- // Filter out pre chunks that the client doesn't want anymore:
- if ((a_Packet.m_PacketID == E_PRE_CHUNK) && ((cPacket_PreChunk &)a_Packet).m_bLoad)
- {
- int ChunkX = ((cPacket_PreChunk &)a_Packet).m_PosX;
- int ChunkZ = ((cPacket_PreChunk &)a_Packet).m_PosZ;
- bool Found = false;
- cCSLock Lock(m_CSChunkLists);
- for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end(); ++itr)
- {
- if ((itr->m_ChunkX == ChunkX) && (itr->m_ChunkZ == ChunkZ))
- {
- Found = true;
- break;
- }
- } // for itr - m_ChunksToSend[]
- if (!Found)
- {
- // This just sometimes happens. If you have a reliably replicatable situation for this, go ahead and fix it
- // It's not a big issue anyway, just means that some chunks may be compressed several times
- // LOGD("Refusing to send PREchunk [%d, %d] to client \"%s\" at [%d, %d].", ChunkX, ChunkZ, m_Username.c_str(), m_Player->GetChunkX(), m_Player->GetChunkZ());
- return;
- }
- }
-
- // Optimize away multiple queued RelativeEntityMoveLook packets:
- cCSLock Lock(m_CSPackets);
- if (a_Priority == E_PRIORITY_NORMAL)
- {
- if (a_Packet.m_PacketID == E_REL_ENT_MOVE_LOOK)
- {
- PacketList & Packets = m_PendingNrmSendPackets;
- const cPacket_RelativeEntityMoveLook & ThisPacketData = reinterpret_cast< const cPacket_RelativeEntityMoveLook &>(a_Packet);
- for (PacketList::iterator itr = Packets.begin(); itr != Packets.end(); ++itr)
- {
- bool bBreak = false;
- switch ((*itr)->m_PacketID)
- {
- case E_REL_ENT_MOVE_LOOK:
- {
- cPacket_RelativeEntityMoveLook * PacketData = reinterpret_cast< cPacket_RelativeEntityMoveLook *>(*itr);
- if (ThisPacketData.m_UniqueID == PacketData->m_UniqueID)
- {
- Packets.erase(itr);
- bBreak = true;
- delete PacketData;
- break;
- }
- break;
- } // case E_REL_END_MOVE_LOOK
- } // switch (*itr -> Packet type)
- if (bBreak)
- {
- break;
- }
- } // for itr - Packets[]
- } // if (E_REL_ENT_MOVE_LOOK
- m_PendingNrmSendPackets.push_back(a_Packet.Clone());
- }
- else if (a_Priority == E_PRIORITY_LOW)
- {
- m_PendingLowSendPackets.push_back(a_Packet.Clone());
- }
- Lock.Unlock();
-
- // Notify SocketThreads that we have something to write:
- cRoot::Get()->GetServer()->NotifyClientWrite(this);
-}
-
-
-
-
-
-void cClientHandle::CheckIfWorldDownloaded(void)
-{
- if (m_State != csDownloadingWorld)
- {
- return;
- }
- cCSLock Lock(m_CSChunkLists);
- if (m_ChunksToSend.empty())
- {
- SendConfirmPosition();
- }
-}
-
-
-
-
-
-void cClientHandle::SendConfirmPosition(void)
-{
- LOG("Spawning player \"%s\" at {%.2f, %.2f, %.2f}",
- m_Username.c_str(), m_Player->GetPosX(), m_Player->GetPosY(), m_Player->GetPosZ()
- );
-
- m_State = csConfirmingPos;
-
- if (!cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_PLAYER_JOIN, 1, m_Player))
- {
- // Broadcast that this player has joined the game! Yay~
- cPacket_Chat Joined(m_Username + " joined the game!");
- cRoot::Get()->GetServer()->Broadcast(Joined, this);
- }
-
- m_ConfirmPosition = m_Player->GetPosition();
- Send(cPacket_PlayerMoveLook(m_Player));
-}
-
-
-
-
-
-const AString & cClientHandle::GetUsername(void) const
-{
- return m_Username;
-}
-
-
-
-
-
-void cClientHandle::SetViewDistance(int a_ViewDistance)
-{
- if (a_ViewDistance < MIN_VIEW_DISTANCE)
- {
- a_ViewDistance = MIN_VIEW_DISTANCE;
- }
- if (a_ViewDistance > MAX_VIEW_DISTANCE)
- {
- a_ViewDistance = MAX_VIEW_DISTANCE;
- }
- m_ViewDistance = a_ViewDistance;
-
- // Need to re-stream chunks for the change to become apparent:
- StreamChunks();
-}
-
-
-
-
-
-bool cClientHandle::WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- cCSLock Lock(m_CSChunkLists);
- return (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)) != m_ChunksToSend.end());
-}
-
-
-
-
-
-void cClientHandle::AddWantedChunk(int a_ChunkX, int a_ChunkZ)
-{
- LOGD("Adding chunk [%d, %d] to wanted chunks for client %p", a_ChunkX, a_ChunkZ, this);
- cCSLock Lock(m_CSChunkLists);
- if (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ)) == m_ChunksToSend.end())
- {
- m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ));
- }
-}
-
-
-
-
-
-void cClientHandle::DataReceived(const char * a_Data, int a_Size)
-{
- // Data is received from the client
-
- m_ReceivedData.append(a_Data, a_Size);
-
- // Parse and handle all complete packets in m_ReceivedData:
- while (!m_ReceivedData.empty())
- {
- cPacket* pPacket = m_PacketMap[(unsigned char)m_ReceivedData[0]];
- if (pPacket == NULL)
- {
- LOGERROR("Unknown packet type 0x%02x from client \"%s\"", (unsigned char)m_ReceivedData[0], m_Username.c_str());
-
- AString Reason;
- Printf(Reason, "[C->S] Unknown PacketID: 0x%02x", (unsigned char)m_ReceivedData[0]);
- cPacket_Disconnect DC(Reason);
- m_Socket.Send(&DC);
- cSleep::MilliSleep(1000); // Give packet some time to be received
- Destroy();
- return;
- }
-
- int NumBytes = pPacket->Parse(m_ReceivedData.data() + 1, m_ReceivedData.size() - 1);
- if (NumBytes == PACKET_ERROR)
- {
- LOGERROR("Protocol error while parsing packet type 0x%02x; disconnecting client \"%s\"", (unsigned char)m_ReceivedData[0], m_Username.c_str());
- cPacket_Disconnect DC("Protocol error");
- m_Socket.Send(&DC);
- cSleep::MilliSleep(1000); // Give packet some time to be received
- Destroy();
- return;
- }
- else if (NumBytes == PACKET_INCOMPLETE)
- {
- // Not a complete packet
- break;
- }
- else
- {
- // Packet parsed successfully, add it to internal queue:
- HandlePacket(pPacket);
- // Erase the packet from the buffer:
- ASSERT(m_ReceivedData.size() > (size_t)NumBytes);
- m_ReceivedData.erase(0, NumBytes + 1);
- }
- } // while (!Received.empty())
-}
-
-
-
-
-
-void cClientHandle::GetOutgoingData(AString & a_Data)
-{
- // Data can be sent to client
-
- cCSLock Lock(m_CSPackets);
- if (m_PendingNrmSendPackets.size() + m_PendingLowSendPackets.size() > MAX_OUTGOING_PACKETS)
- {
- LOGERROR("ERROR: Too many packets in queue for player %s !!", m_Username.c_str());
- cPacket_Disconnect DC("Too many packets in queue.");
- m_Socket.Send(DC);
-
- // DEBUG: Dump all outstanding packets' types to the log:
- int Idx = 0;
- int ChunkX = m_Player->GetChunkX();
- int ChunkZ = m_Player->GetChunkZ();
- for (PacketList::const_iterator itr = m_PendingNrmSendPackets.begin(); itr != m_PendingNrmSendPackets.end(); ++itr)
- {
- switch ((*itr)->m_PacketID)
- {
- case E_MAP_CHUNK:
- {
- int x = ((cPacket_MapChunk *)(*itr))->m_PosX;
- int z = ((cPacket_MapChunk *)(*itr))->m_PosZ;
- bool IsWanted = (abs(x - ChunkX) <= m_ViewDistance) && (abs(z - ChunkZ) <= m_ViewDistance);
- LOG("Packet %4d: type %2x (MapChunk: %d, %d, %s)",
- Idx++, (*itr)->m_PacketID,
- x, z,
- IsWanted ? "wanted" : "unwanted"
- );
- break;
- }
-
- case E_PRE_CHUNK:
- {
- int x = ((cPacket_PreChunk *)(*itr))->m_PosX;
- int z = ((cPacket_PreChunk *)(*itr))->m_PosZ;
- bool IsWanted = (abs(x - ChunkX) <= m_ViewDistance) && (abs(z - ChunkZ) <= m_ViewDistance);
- bool Loading = ((cPacket_PreChunk *)(*itr))->m_bLoad;
- LOG("Packet %4d: type %2x (PreChunk: %d, %d, %s, %s)",
- Idx++, (*itr)->m_PacketID,
- x, z,
- Loading ? "loading" : "unloading",
- IsWanted ? "wanted" : "unwanted"
- );
- break;
- }
-
- case E_BLOCK_CHANGE:
- {
- int x = ((cPacket_BlockChange *)(*itr))->m_PosX;
- int z = ((cPacket_BlockChange *)(*itr))->m_PosZ;
- char ToBlock = ((cPacket_BlockChange *)(*itr))->m_BlockType;
- int y, cx, cz;
- cChunkDef::AbsoluteToRelative(x, y, z, cx, cz);
- bool IsWanted = (abs(cx - ChunkX) <= m_ViewDistance) && (abs(cz - ChunkZ) <= m_ViewDistance);
- LOG("Packet %4d: type %2x (BlockChange: [%d, %d], %s chunk; to block %d)",
- Idx++, (*itr)->m_PacketID,
- cx, cz,
- IsWanted ? "wanted" : "unwanted",
- ToBlock
- );
- break;
- }
-
- case E_MULTI_BLOCK:
- {
- int cx = ((cPacket_MultiBlock *)(*itr))->m_ChunkX;
- int cz = ((cPacket_MultiBlock *)(*itr))->m_ChunkZ;
- int NumBlocks = ((cPacket_MultiBlock *)(*itr))->m_NumBlocks;
- bool IsWanted = (abs(cx - ChunkX) <= m_ViewDistance) && (abs(cz - ChunkZ) <= m_ViewDistance);
- LOG("Packet %4d: type %2x (MultiBlock: [%d, %d], %s chunk, %d blocks)",
- Idx++, (*itr)->m_PacketID,
- cx, cz,
- IsWanted ? "wanted" : "unwanted",
- NumBlocks
- );
- break;
- }
-
- default:
- {
- LOG("Packet %4d: type %2x", Idx++, (*itr)->m_PacketID);
- break;
- }
- }
- }
-
- Lock.Unlock();
- Destroy();
- return;
- }
-
- if ((m_PendingNrmSendPackets.size() == 0) && (m_PendingLowSendPackets.size() == 0))
- {
- return;
- }
-
- if (m_PendingNrmSendPackets.size() > MAX_OUTGOING_PACKETS / 2)
- {
- LOGINFO("Suspiciously many pending packets: %i; client \"%s\", LastType: 0x%02x", m_PendingNrmSendPackets.size(), m_Username.c_str(), (*m_PendingNrmSendPackets.rbegin())->m_PacketID);
- }
-
- AString Data;
- Data.reserve(1100);
- // Serialize normal-priority packets up to 1000 bytes
- while (!m_PendingNrmSendPackets.empty() && (Data.size() < 1000))
- {
- m_PendingNrmSendPackets.front()->Serialize(Data);
- delete m_PendingNrmSendPackets.front();
- m_PendingNrmSendPackets.erase(m_PendingNrmSendPackets.begin());
- }
- // Serialize one low-priority packet:
- if (!m_PendingLowSendPackets.empty() && Data.empty())
- {
- m_PendingLowSendPackets.front()->Serialize(Data);
- delete m_PendingLowSendPackets.front();
- m_PendingLowSendPackets.erase(m_PendingLowSendPackets.begin());
- }
- Lock.Unlock();
-
- a_Data.append(Data);
-
- // Disconnect player after all packets have been sent
- if (m_bKicking && (m_PendingNrmSendPackets.size() + m_PendingLowSendPackets.size() == 0))
- {
- Destroy();
- }
-}
-
-
-
-
-
-void cClientHandle::SocketClosed(void)
-{
- // The socket has been closed for any reason
-
- // TODO
- /*
- self->Destroy();
- LOG("Client \"%s\" disconnected", GetLogName().c_str());
- */
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cClientHandle.h" +#include "cServer.h" +#include "cWorld.h" +#include "cPickup.h" +#include "cPluginManager.h" +#include "cPlayer.h" +#include "cInventory.h" +#include "cChestEntity.h" +#include "cSignEntity.h" +#include "cWindow.h" +#include "cCraftingWindow.h" +#include "cItem.h" +#include "cTorch.h" +#include "cStairs.h" +#include "cStep.h" +#include "cDoors.h" +#include "cLadder.h" +#include "cSign.h" +#include "cRedstone.h" +#include "cPiston.h" +#include "cBlockToPickup.h" +#include "cMonster.h" +#include "cChatColor.h" +#include "cSocket.h" +#include "cTimer.h" + +#include "cTracer.h" +#include "Vector3f.h" +#include "Vector3d.h" + +#include "cSleep.h" +#include "cRoot.h" + +#include "cBlockingTCPLink.h" +#include "cAuthenticator.h" +#include "MersenneTwister.h" + +#include "packets/cPacket_KeepAlive.h" +#include "packets/cPacket_Respawn.h" +#include "packets/cPacket_UpdateHealth.h" +#include "packets/cPacket_RelativeEntityMoveLook.h" +#include "packets/cPacket_Chat.h" +#include "packets/cPacket_Login.h" +#include "packets/cPacket_WindowClick.h" +#include "packets/cPacket_TimeUpdate.h" +#include "packets/cPacket_BlockDig.h" +#include "packets/cPacket_Handshake.h" +#include "packets/cPacket_ArmAnim.h" +#include "packets/cPacket_BlockPlace.h" +#include "packets/cPacket_Flying.h" +#include "packets/cPacket_Disconnect.h" +#include "packets/cPacket_PickupSpawn.h" +#include "packets/cPacket_ItemSwitch.h" +#include "packets/cPacket_EntityEquipment.h" +#include "packets/cPacket_CreativeInventoryAction.h" +#include "packets/cPacket_NewInvalidState.h" +#include "packets/cPacket_UseEntity.h" +#include "packets/cPacket_WindowClose.h" +#include "packets/cPacket_13.h" +#include "packets/cPacket_UpdateSign.h" +#include "packets/cPacket_Ping.h" +#include "packets/cPacket_NamedEntitySpawn.h" +#include "packets/cPacket_MapChunk.h" +#include "packets/cPacket_PreChunk.h" + +// DEBUG: +#include "packets/cPacket_BlockChange.h" +#include "packets/cPacket_MultiBlock.h" + + + + + +#define AddPistonDir(x, y, z, dir, amount) switch (dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\ + case 2: (z)-=(amount); break; case 3: (z)+=(amount); break;\ + case 4: (x)-=(amount); break; case 5: (x)+=(amount); break; } + + + + + +/// If the number of queued outgoing packets reaches this, the client will be kicked +#define MAX_OUTGOING_PACKETS 2000 + + + + + +#define RECI_RAND_MAX (1.f/RAND_MAX) +inline int fRadRand(MTRand & r1, int a_BlockCoord) +{ + return a_BlockCoord * 32 + (int)(16 * ((float)r1.rand() * RECI_RAND_MAX) * 16 - 8); +} + + + + + +int cClientHandle::s_ClientCount = 0; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cClientHandle: + +cClientHandle::cClientHandle(const cSocket & a_Socket, int a_ViewDistance) + : m_ViewDistance(a_ViewDistance) + , m_ProtocolVersion(MCS_PROTOCOL_VERSION) + , m_Socket(a_Socket) + , m_bDestroyed(false) + , m_Player(NULL) + , m_bKicking(false) + , m_TimeLastPacket(cWorld::GetTime()) + , m_bKeepThreadGoing(true) + , m_Ping(1000) + , m_State(csConnected) + , m_LastStreamedChunkX(0x7fffffff) // bogus chunk coords to force streaming upon login + , m_LastStreamedChunkZ(0x7fffffff) + , m_UniqueID(0) +{ + s_ClientCount++; // Not protected by CS because clients are always constructed from the same thread + m_UniqueID = s_ClientCount; + + cTimer t1; + m_LastPingTime = t1.GetNowTime(); + + // All the packets that can be received from the client + for (int i = 0; i < ARRAYCOUNT(m_PacketMap); ++i) + { + m_PacketMap[i] = NULL; + } + m_PacketMap[E_KEEP_ALIVE] = new cPacket_KeepAlive; + m_PacketMap[E_HANDSHAKE] = new cPacket_Handshake; + m_PacketMap[E_LOGIN] = new cPacket_Login; + m_PacketMap[E_PLAYERPOS] = new cPacket_PlayerPosition; + m_PacketMap[E_PLAYERLOOK] = new cPacket_PlayerLook; + m_PacketMap[E_PLAYERMOVELOOK] = new cPacket_PlayerMoveLook; + m_PacketMap[E_PLAYER_ABILITIES] = new cPacket_PlayerAbilities; + m_PacketMap[E_CHAT] = new cPacket_Chat; + m_PacketMap[E_ANIMATION] = new cPacket_ArmAnim; + m_PacketMap[E_FLYING] = new cPacket_Flying; + m_PacketMap[E_BLOCK_DIG] = new cPacket_BlockDig; + m_PacketMap[E_BLOCK_PLACE] = new cPacket_BlockPlace; + m_PacketMap[E_DISCONNECT] = new cPacket_Disconnect; + m_PacketMap[E_ITEM_SWITCH] = new cPacket_ItemSwitch; + m_PacketMap[E_ENTITY_EQUIPMENT] = new cPacket_EntityEquipment; + m_PacketMap[E_CREATIVE_INVENTORY_ACTION] = new cPacket_CreativeInventoryAction; + m_PacketMap[E_NEW_INVALID_STATE] = new cPacket_NewInvalidState; + m_PacketMap[E_PICKUP_SPAWN] = new cPacket_PickupSpawn; + m_PacketMap[E_USE_ENTITY] = new cPacket_UseEntity; + m_PacketMap[E_WINDOW_CLOSE] = new cPacket_WindowClose; + m_PacketMap[E_WINDOW_CLICK] = new cPacket_WindowClick; + m_PacketMap[E_PACKET_13] = new cPacket_13; + m_PacketMap[E_UPDATE_SIGN] = new cPacket_UpdateSign; + m_PacketMap[E_RESPAWN] = new cPacket_Respawn; + m_PacketMap[E_PING] = new cPacket_Ping; + + LOG("New ClientHandle created at %p", this); +} + + + + + +cClientHandle::~cClientHandle() +{ + LOG("Deleting client \"%s\" at %p", GetUsername().c_str(), this); + + // Remove from cSocketThreads, we're not to be called anymore: + cRoot::Get()->GetServer()->ClientDestroying(this); + + { + cCSLock Lock(m_CSChunkLists); + m_LoadedChunks.clear(); + m_ChunksToSend.clear(); + } + + if (m_Player != NULL) + { + cWorld * World = m_Player->GetWorld(); + if (!m_Username.empty() && (World != NULL)) + { + // Send the Offline PlayerList packet: + AString NameColor = (m_Player ? m_Player->GetColor() : ""); + cPacket_PlayerListItem PlayerList(NameColor + GetUsername(), false, (short)9999); + World->Broadcast(PlayerList, this); + + // Send the Chat packet: + cPacket_Chat Left(m_Username + " left the game!"); + World->Broadcast(Left, this); + } + if (World != NULL) + { + World->RemovePlayer(m_Player); + } + } + + if (m_Socket.IsValid()) + { + cPacket_Disconnect Disconnect; + Disconnect.m_Reason = "Server shut down? Kthnxbai"; + m_Socket.Send(&Disconnect); + } + + if (m_Player != NULL) + { + m_Player->Destroy(); + m_Player = NULL; + } + for (int i = 0; i < ARRAYCOUNT(m_PacketMap); i++) + { + delete m_PacketMap[i]; + } + + // Queue all remaining outgoing packets to cSocketThreads: + { + cCSLock Lock(m_CSPackets); + for (PacketList::iterator itr = m_PendingNrmSendPackets.begin(); itr != m_PendingNrmSendPackets.end(); ++itr) + { + AString Data; + (*itr)->Serialize(Data); + cRoot::Get()->GetServer()->WriteToClient(&m_Socket, Data); + delete *itr; + } + m_PendingNrmSendPackets.clear(); + for (PacketList::iterator itr = m_PendingLowSendPackets.begin(); itr != m_PendingLowSendPackets.end(); ++itr) + { + AString Data; + (*itr)->Serialize(Data); + cRoot::Get()->GetServer()->WriteToClient(&m_Socket, Data); + delete *itr; + } + m_PendingLowSendPackets.clear(); + } + + // Queue the socket to close as soon as it sends all outgoing data: + cRoot::Get()->GetServer()->QueueClientClose(&m_Socket); + + // We need to remove the socket from SocketThreads because we own it and it gets destroyed after this destructor finishes + // TODO: The socket needs to stay alive, someone else has to own it + cRoot::Get()->GetServer()->RemoveClient(&m_Socket); + + LOG("ClientHandle at %p deleted", this); +} + + + + + +void cClientHandle::Destroy() +{ + // Setting m_bDestroyed was moved to the bottom of Destroy(), + // otherwise the destructor may be called within another thread before the client is removed from chunks + // http://forum.mc-server.org/showthread.php?tid=366 + + if ((m_Player != NULL) && (m_Player->GetWorld() != NULL)) + { + RemoveFromAllChunks(); + m_Player->GetWorld()->RemoveClientFromChunkSender(this); + } + + m_bDestroyed = true; +} + + + + + +void cClientHandle::Kick(const AString & a_Reason) +{ + if (m_State >= csAuthenticating) // Don't log pings + { + LOG("Kicking user \"%s\" for \"%s\"", m_Username.c_str(), a_Reason.c_str()); + } + Send(cPacket_Disconnect(a_Reason)); + m_bKicking = true; +} + + + + + +void cClientHandle::Authenticate(void) +{ + if (m_State != csAuthenticating) + { + return; + } + + ASSERT( m_Player == NULL ); + + // Spawn player (only serversided, so data is loaded) + m_Player = new cPlayer(this, GetUsername()); + + cWorld * World = cRoot::Get()->GetWorld(m_Player->GetLoadedWorldName()); + if (World == NULL) + { + World = cRoot::Get()->GetDefaultWorld(); + } + + m_Player->LoginSetGameMode (World->GetGameMode()); //set player's gamemode to server's gamemode at login. TODO: set to last player's gamemode at logout + + m_Player->SetIP (m_Socket.GetIPString()); + + cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_PLAYER_SPAWN, 1, m_Player); + + // Return a server login packet + cPacket_Login LoginResponse; + LoginResponse.m_ProtocolVersion = m_Player->GetUniqueID(); + //LoginResponse.m_Username = ""; + LoginResponse.m_ServerMode = m_Player->GetGameMode(); // set gamemode from player. + LoginResponse.m_Dimension = 0; + LoginResponse.m_MaxPlayers = (unsigned char)cRoot::Get()->GetDefaultWorld()->GetMaxPlayers(); + LoginResponse.m_Difficulty = 2; + Send(LoginResponse); + + // Send Weather if raining: + if ((World->GetWeather() == 1) || (World->GetWeather() == 2)) + { + cPacket_NewInvalidState RainPacket; + RainPacket.m_Reason = 1; //begin rain + Send(RainPacket); + } + + // Send time + Send(cPacket_TimeUpdate(World->GetWorldTime())); + + // Send inventory + m_Player->GetInventory().SendWholeInventory(this); + + // Send health + cPacket_UpdateHealth Health; + Health.m_Health = (short)m_Player->GetHealth(); + Health.m_Food = m_Player->GetFood(); + Health.m_Saturation = m_Player->GetFoodSaturation(); + Send(Health); + + m_Player->Initialize(World); + StreamChunks(); + m_State = csDownloadingWorld; +} + + + + + +void cClientHandle::StreamChunks(void) +{ + if (m_State < csAuthenticating) + { + return; + } + + ASSERT(m_Player != NULL); + + int ChunkPosX = FAST_FLOOR_DIV(m_Player->GetPosX(), cChunkDef::Width); + int ChunkPosZ = FAST_FLOOR_DIV(m_Player->GetPosZ(), cChunkDef::Width); + if ((ChunkPosX == m_LastStreamedChunkX) && (ChunkPosZ == m_LastStreamedChunkZ)) + { + // Already streamed for this position + return; + } + m_LastStreamedChunkX = ChunkPosX; + m_LastStreamedChunkZ = ChunkPosZ; + + LOGD("Streaming chunks centered on [%d, %d], view distance %d", ChunkPosX, ChunkPosZ, m_ViewDistance); + + cWorld * World = m_Player->GetWorld(); + ASSERT(World != NULL); + + // Remove all loaded chunks that are no longer in range; deferred to out-of-CS: + cChunkCoordsList RemoveChunks; + { + cCSLock Lock(m_CSChunkLists); + for (cChunkCoordsList::iterator itr = m_LoadedChunks.begin(); itr != m_LoadedChunks.end();) + { + int RelX = (*itr).m_ChunkX - ChunkPosX; + int RelZ = (*itr).m_ChunkZ - ChunkPosZ; + if ((RelX > m_ViewDistance) || (RelX < -m_ViewDistance) || (RelZ > m_ViewDistance) || (RelZ < -m_ViewDistance)) + { + RemoveChunks.push_back(*itr); + itr = m_LoadedChunks.erase(itr); + } + else + { + ++itr; + } + } // for itr - m_LoadedChunks[] + for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end();) + { + int RelX = (*itr).m_ChunkX - ChunkPosX; + int RelZ = (*itr).m_ChunkZ - ChunkPosZ; + if ((RelX > m_ViewDistance) || (RelX < -m_ViewDistance) || (RelZ > m_ViewDistance) || (RelZ < -m_ViewDistance)) + { + itr = m_ChunksToSend.erase(itr); + } + else + { + ++itr; + } + } // for itr - m_ChunksToSend[] + } + for (cChunkCoordsList::iterator itr = RemoveChunks.begin(); itr != RemoveChunks.end(); ++itr) + { + World->RemoveChunkClient(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ, this); + Send(cPacket_PreChunk(itr->m_ChunkX, itr->m_ChunkZ, false)); + } // for itr - RemoveChunks[] + + // Add all chunks that are in range and not yet in m_LoadedChunks: + // Queue these smartly - from the center out to the edge + for (int d = 0; d <= m_ViewDistance; ++d) // cycle through (square) distance, from nearest to furthest + { + // For each distance add chunks in a hollow square centered around current position: + for (int i = -d; i <= d; ++i) + { + StreamChunk(ChunkPosX + d, ZERO_CHUNK_Y, ChunkPosZ + i); + StreamChunk(ChunkPosX - d, ZERO_CHUNK_Y, ChunkPosZ + i); + } // for i + for (int i = -d + 1; i < d; ++i) + { + StreamChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ + d); + StreamChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ - d); + } // for i + } // for d + + // Touch chunks GENERATEDISTANCE ahead to let them generate: + for (int d = m_ViewDistance + 1; d <= m_ViewDistance + GENERATEDISTANCE; ++d) // cycle through (square) distance, from nearest to furthest + { + // For each distance touch chunks in a hollow square centered around current position: + for (int i = -d; i <= d; ++i) + { + World->TouchChunk(ChunkPosX + d, ZERO_CHUNK_Y, ChunkPosZ + i); + World->TouchChunk(ChunkPosX - d, ZERO_CHUNK_Y, ChunkPosZ + i); + } // for i + for (int i = -d + 1; i < d; ++i) + { + World->TouchChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ + d); + World->TouchChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ - d); + } // for i + } // for d +} + + + + +void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cWorld * World = m_Player->GetWorld(); + ASSERT(World != NULL); + + if (World->AddChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, this)) + { + { + cCSLock Lock(m_CSChunkLists); + m_LoadedChunks.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + } + World->SendChunkTo(a_ChunkX, a_ChunkY, a_ChunkZ, this); + } +} + + + + + +// Removes the client from all chunks. Used when switching worlds or destroying the player +void cClientHandle::RemoveFromAllChunks() +{ + cWorld * World = m_Player->GetWorld(); + if (World != NULL) + { + World->RemoveClientFromChunks(this); + } + + { + cCSLock Lock(m_CSChunkLists); + m_LoadedChunks.clear(); + m_ChunksToSend.clear(); + } +} + + + + + +void cClientHandle::HandlePacket(cPacket * a_Packet) +{ + m_TimeLastPacket = cWorld::GetTime(); + + // LOG("Recv packet 0x%02x from client \"%s\" (\"%s\")", a_Packet->m_PacketID, m_Socket.GetIPString().c_str(), m_Username.c_str()); + + if (m_bKicking) + { + return; + } + + switch (m_State) + { + case csConnected: + { + switch (a_Packet->m_PacketID) + { + case E_NEW_INVALID_STATE: // New/Invalid State packet received. I'm guessing the client only sends it when there's a problem with the bed? + { + LOGINFO("Got New Invalid State packet"); + break; + } + case E_PING: HandlePing (); break; + case E_HANDSHAKE: HandleHandshake(reinterpret_cast<cPacket_Handshake *>(a_Packet)); break; + case E_LOGIN: HandleLogin (reinterpret_cast<cPacket_Login *> (a_Packet)); break; + + // Ignored packets: + case E_PLAYERLOOK: + case E_CHAT: + case E_PLAYERMOVELOOK: + case E_PLAYERPOS: + case E_KEEP_ALIVE: break; + default: HandleUnexpectedPacket(a_Packet); break; + } // switch (PacketType) + break; + } // case csConnected + + case csAuthenticating: + { + // Waiting for external authentication, no packets are handled + switch (a_Packet->m_PacketID) + { + // Ignored packets: + case E_KEEP_ALIVE: + case E_CHAT: + case E_FLYING: + case E_PLAYERLOOK: + case E_PLAYERMOVELOOK: + case E_PLAYERPOS: break; + + default: HandleUnexpectedPacket(a_Packet); break; + } + break; + } + + case csDownloadingWorld: + { + // Waiting for chunks to stream to client, no packets are handled + switch (a_Packet->m_PacketID) + { + // Ignored packets: + case E_KEEP_ALIVE: + case E_CHAT: + case E_FLYING: + case E_PLAYERLOOK: + case E_PLAYERMOVELOOK: + case E_PLAYERPOS: break; + + default: HandleUnexpectedPacket(a_Packet); break; + } + break; + } + + case csConfirmingPos: + { + switch (a_Packet->m_PacketID) + { + // Ignored packets: + case E_KEEP_ALIVE: + case E_CHAT: + case E_FLYING: + case E_PLAYERLOOK: + case E_PLAYERPOS: break; + + case E_PLAYERMOVELOOK: HandleMoveLookConfirm(reinterpret_cast<cPacket_PlayerMoveLook *>(a_Packet)); break; + + default: + { + HandleUnexpectedPacket(a_Packet); + break; + } + } // switch (PacketType) + break; + } // case csConfirmingPos + + case csPlaying: + { + switch (a_Packet->m_PacketID) + { + case E_CREATIVE_INVENTORY_ACTION: HandleCreativeInventory(reinterpret_cast<cPacket_CreativeInventoryAction *>(a_Packet)); break; + case E_PLAYERPOS: HandlePlayerPos (reinterpret_cast<cPacket_PlayerPosition *> (a_Packet)); break; + case E_BLOCK_DIG: HandleBlockDig (reinterpret_cast<cPacket_BlockDig *> (a_Packet)); break; + case E_BLOCK_PLACE: HandleBlockPlace (reinterpret_cast<cPacket_BlockPlace *> (a_Packet)); break; + case E_PICKUP_SPAWN: HandlePickupSpawn (reinterpret_cast<cPacket_PickupSpawn *> (a_Packet)); break; + case E_CHAT: HandleChat (reinterpret_cast<cPacket_Chat *> (a_Packet)); break; + case E_PLAYERLOOK: HandlePlayerLook (reinterpret_cast<cPacket_PlayerLook *> (a_Packet)); break; + case E_PLAYERMOVELOOK: HandlePlayerMoveLook (reinterpret_cast<cPacket_PlayerMoveLook *> (a_Packet)); break; + case E_ANIMATION: HandleAnimation (reinterpret_cast<cPacket_ArmAnim *> (a_Packet)); break; + case E_ITEM_SWITCH: HandleItemSwitch (reinterpret_cast<cPacket_ItemSwitch *> (a_Packet)); break; + case E_WINDOW_CLOSE: HandleWindowClose (reinterpret_cast<cPacket_WindowClose *> (a_Packet)); break; + case E_WINDOW_CLICK: HandleWindowClick (reinterpret_cast<cPacket_WindowClick *> (a_Packet)); break; + case E_UPDATE_SIGN: HandleUpdateSign (reinterpret_cast<cPacket_UpdateSign *> (a_Packet)); break; + case E_USE_ENTITY: HandleUseEntity (reinterpret_cast<cPacket_UseEntity *> (a_Packet)); break; + case E_RESPAWN: HandleRespawn(); break; + case E_DISCONNECT: HandleDisconnect (reinterpret_cast<cPacket_Disconnect *> (a_Packet)); break; + case E_KEEP_ALIVE: HandleKeepAlive (reinterpret_cast<cPacket_KeepAlive *> (a_Packet)); break; + } // switch (Packet type) + break; + } // case csPlaying + } // switch (m_State) +} + + + + + +void cClientHandle::HandlePing(void) +{ + // Somebody tries to retrieve information about the server + AString Reply; + Printf(Reply, "%s%s%i%s%i", + cRoot::Get()->GetDefaultWorld()->GetDescription().c_str(), + cChatColor::Delimiter.c_str(), + cRoot::Get()->GetDefaultWorld()->GetNumPlayers(), + cChatColor::Delimiter.c_str(), + cRoot::Get()->GetDefaultWorld()->GetMaxPlayers() + ); + Kick(Reply.c_str()); +} + + + + + +void cClientHandle::HandleHandshake(cPacket_Handshake * a_Packet) +{ + AStringVector UserData = StringSplit( a_Packet->m_Username, ";" ); // "FakeTruth;localhost:25565" + if( UserData.size() == 0 ) + { + Kick("Could not receive username"); + return; + } + m_Username = UserData[0]; + + LOG("HANDSHAKE %s", m_Username.c_str()); + + if (cRoot::Get()->GetDefaultWorld()->GetNumPlayers() >= cRoot::Get()->GetDefaultWorld()->GetMaxPlayers()) + { + Kick("The server is currently full :(-- Try again later"); + return; + } + cPacket_Chat Connecting(m_Username + " is connecting."); + cRoot::Get()->GetServer()->Broadcast(Connecting, this); + + cPacket_Handshake Handshake; + Handshake.m_Username = cRoot::Get()->GetServer()->GetServerID(); + Send(Handshake); + LOG("User \"%s\" was sent a handshake", m_Username.c_str()); +} + + + + + +void cClientHandle::HandleLogin(cPacket_Login * a_Packet) +{ + LOG("LOGIN %s", m_Username.c_str()); + if (a_Packet->m_ProtocolVersion < m_ProtocolVersion) + { + Kick("Your client is outdated!"); + return; + } + else if (a_Packet->m_ProtocolVersion > m_ProtocolVersion) + { + Kick("Your client version is higher than the server!"); + return; + } + if (m_Username.compare(a_Packet->m_Username) != 0) + { + LOGWARNING("Login Username (\"%s\") does not match Handshake username (\"%s\") for client \"%s\")", + a_Packet->m_Username.c_str(), + m_Username.c_str(), + m_Socket.GetIPString().c_str() + ); + Kick("Hacked client"); // Don't tell them why we don't want them + return; + } + + if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_LOGIN, 1, a_Packet)) + { + Destroy(); + return; + } + + // Schedule for authentication; until then, let them wait (but do not block) + m_State = csAuthenticating; + cRoot::Get()->GetAuthenticator().Authenticate(GetUniqueID(), GetUsername(), cRoot::Get()->GetServer()->GetServerID()); +} + + + + + +void cClientHandle::HandleUnexpectedPacket(cPacket * a_Packet) +{ + LOGWARNING( + "Invalid packet in state %d: 0x%02x from client \"%s\", username \"%s\"", + m_State, + a_Packet->m_PacketID, + m_Socket.GetIPString().c_str(), + m_Username.c_str() + ); + Kick("Hacked client"); // Don't tell them why we don't like them +} + + + + + +void cClientHandle::HandleMoveLookConfirm(cPacket_PlayerMoveLook * a_Packet) +{ + Vector3d ReceivedPosition = Vector3d(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + + // Test the distance between points with a small/large enough value instead of comparing directly. Floating point inaccuracies might screw stuff up + double Dist = (ReceivedPosition - m_ConfirmPosition).SqrLength(); + if (Dist < 1.0) + { + // Test + if (ReceivedPosition.Equals(m_ConfirmPosition)) + { + LOGINFO("Exact position confirmed by client!"); + } + m_State = csPlaying; + } + else + { + LOGWARNING("Player \"%s\" sent a weird position confirmation %.2f blocks away, retrying", m_Username.c_str(), Dist); + m_ConfirmPosition = m_Player->GetPosition(); + Send(cPacket_PlayerMoveLook(m_Player)); + } +} + + + + + +void cClientHandle::HandleCreativeInventory(cPacket_CreativeInventoryAction * a_Packet) +{ + // This is for creative Inventory changes + if (m_Player->GetGameMode() == 1) + { + m_Player->GetInventory().Clicked(a_Packet); + } + else + { + LOGWARNING("Got a CreativeInventoryAction packet from user \"%s\" while not in creative mode. Ignoring.", m_Username.c_str()); + } +} + + + + + +void cClientHandle::HandlePlayerPos(cPacket_PlayerPosition * a_Packet) +{ + // LOG("recv player pos: %0.2f %0.2f %0.2f", PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ); + m_Player->MoveTo(Vector3d(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ)); + m_Player->SetStance(a_Packet->m_Stance); + m_Player->SetTouchGround(a_Packet->m_bFlying); +} + + + + + +void cClientHandle::HandleBlockDig(cPacket_BlockDig * a_Packet) +{ + if (!CheckBlockInteractionsRate()) + { + return; + } + + LOGD("OnBlockDig: {%i, %i, %i} Dir: %i Stat: %i", + a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, + a_Packet->m_Direction, a_Packet->m_Status + ); + + // Do we want plugins to disable tossing items? Probably no, so toss item before asking plugins for permission + if (a_Packet->m_Status == 0x04) // Drop held item + { + m_Player->TossItem(false); + return; + } + + cWorld* World = m_Player->GetWorld(); + BLOCKTYPE OldBlock = World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + NIBBLETYPE OldMeta = World->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + + if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_BLOCK_DIG, 4, a_Packet, m_Player, OldBlock, OldMeta)) + { + // The plugin doesn't agree with the digging, replace the block on the client and quit: + World->SendBlockTo(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, m_Player); + return; + } + + bool bBroken = ( + (a_Packet->m_Status == 0x02) || + (g_BlockOneHitDig[(int)OldBlock]) || + ((a_Packet->m_Status == 0x00) && (m_Player->GetGameMode() == 1)) + ); + + if ((OldBlock == E_BLOCK_WOODEN_DOOR) && !bBroken) + { + cDoors::ChangeDoor(m_Player->GetWorld(), a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + } + + cItems PickupItems; + if (bBroken && !(m_Player->GetGameMode() == 1)) // broken + { + cBlockToPickup::ToPickup(OldBlock, OldMeta, m_Player->GetInventory().GetEquippedItem(), PickupItems); + + // Allow plugins to change the dropped objects: + cRoot::Get()->GetPluginManager()->CallHookBlockToPickup(OldBlock, OldMeta, m_Player, m_Player->GetInventory().GetEquippedItem(), PickupItems); + } + + int pX = a_Packet->m_PosX; + unsigned char pY = a_Packet->m_PosY; + int pZ = a_Packet->m_PosZ; + + AddDirection(pX, pY, pZ, a_Packet->m_Direction); + + char PossibleBlock = World->GetBlock(pX, pY, pZ); + + if (PossibleBlock == E_BLOCK_FIRE) + { + a_Packet->m_PosX = pX; + a_Packet->m_PosY = pY; + a_Packet->m_PosZ = pZ; + bBroken = true; + } + + if (!bBroken) + { + return; + } + + if (!World->DigBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ)) + { + return; + } + + World->SpawnItemPickups(PickupItems, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + + switch (OldBlock) + { + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_REDSTONE_WIRE: + { + cRedstone Redstone(World); + Redstone.ChangeRedstone(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, false); + break; + } + } + + if ((OldBlock == E_BLOCK_PISTON) || (OldBlock == E_BLOCK_STICKY_PISTON)) + { + int newX = a_Packet->m_PosX; + int newY = a_Packet->m_PosY; + int newZ = a_Packet->m_PosZ; + AddPistonDir(newX, newY, newZ, OldMeta & ~(8), 1); + if (World->GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION) + { + World->SetBlock(newX, newY, newZ, E_BLOCK_AIR, 0); + } + } + + if (cDoors::IsDoor(OldBlock)) + { + // Special actions for destroyed door (Destroy second part) + if (OldMeta & 8) + { + // Was upper part of door + if (cDoors::IsDoor(World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY - 1, a_Packet->m_PosZ))) + { + World->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY - 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0); + } + } + else + { + // Was lower part + if (cDoors::IsDoor(World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ))) + { + World->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0); + } + } + } + + m_Player->UseEquippedItem(); +} + + + + + +void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet) +{ + if (!CheckBlockInteractionsRate()) + { + return; + } + + cItem & Equipped = m_Player->GetInventory().GetEquippedItem(); + + if ((Equipped.m_ItemID != a_Packet->m_ItemType)) // Not valid + { + LOGWARN("Player %s tried to place a block that was not equipped (exp %d, got %d)", + m_Username.c_str(), Equipped.m_ItemID, a_Packet->m_ItemType + ); + // TODO: We should probably send the current world block to the client, so that it can immediately "let the user know" that they haven't placed the block + return; + } + + if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_BLOCK_PLACE, 2, a_Packet, m_Player)) + { + if (a_Packet->m_Direction > -1) + { + AddDirection(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Direction); + m_Player->GetWorld()->SendBlockTo(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, m_Player); + } + return; + } + + //LOG("%i %i %i %i %i %i", a_Packet->m_Count, a_Packet->m_Direction, a_Packet->m_ItemType, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + + //printf("Place Dir:%i %i %i %i : %i\n", a_Packet->m_Direction, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_ItemType); + // 'use' useable items instead of placing blocks + bool bPlaceBlock = true; + bool UpdateRedstone = false; + bool AddedCurrent = false; + + if (a_Packet->m_Direction >= 0) + { + cWorld * World = m_Player->GetWorld(); + BLOCKTYPE BlockType = 0; + NIBBLETYPE BlockMeta; + World->GetBlockTypeMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, BlockType, BlockMeta); + switch (BlockType) + { + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_REDSTONE_REPEATER_OFF: + { + // no need to update redstone current with a repeater + // Find meta value of repeater and change it to one step more: + World->FastSetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, BlockType, ((BlockMeta + 0x04) & 0x0f)); + bPlaceBlock = false; + break; + } + + case E_BLOCK_WORKBENCH: + { + bPlaceBlock = false; + cWindow* Window = new cCraftingWindow(0, true); + m_Player->OpenWindow(Window); + break; + } + + case E_BLOCK_FURNACE: + case E_BLOCK_CHEST: + { + bPlaceBlock = false; + m_Player->GetWorld()->UseBlockEntity(m_Player, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + break; + } + + case E_BLOCK_WOODEN_DOOR: + { + bPlaceBlock = false; + cDoors::ChangeDoor(m_Player->GetWorld(), a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + break; + } + + default: + { + break; + } + } // switch (BlockID) + } // if (Direction >= 0) + + // Some checks to see if it's a placeable item :P + if (bPlaceBlock) + { + cItem Item; + Item.m_ItemID = Equipped.m_ItemID; + Item.m_ItemCount = 1; + LOGD("Placing item of type %i at {%d, %d, %d}", + (int)a_Packet->m_ItemType, + a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ + ); + + if (m_Player->EatItem(Item.m_ItemID)) + { + m_Player->GetInventory().RemoveItem(Item); + return; + } + + if (a_Packet->m_Direction < 0) + { + // clicked in air + return; + } + bool isDoor = false; + + //TODO: Wrong Blocks! + BLOCKTYPE ClickedBlock = m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + + if (ItemCategory::IsHoe(Item.m_ItemID)) + { + if ((ClickedBlock == E_BLOCK_DIRT) || (ClickedBlock == E_BLOCK_GRASS)) + { + m_Player->GetWorld()->FastSetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, E_BLOCK_FARMLAND, 0); + } + return; + } + + NIBBLETYPE MetaData = (NIBBLETYPE)Equipped.m_ItemHealth; // This generally works for logs & planks, others will override + bool LavaBucket = false; + bool WaterBucket = false; + bool bRemoveItem = true; + bool bIgnoreCollision = false; + + if (ClickedBlock == E_BLOCK_STEP) + { + // Only make double slab if meta values are the same and if player clicked either on top or on bottom of the block (direction either 0 or 1) + // TODO check if it works from beneath + if (MetaData == ( m_Player->GetWorld()->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ) & 0x7) && a_Packet->m_Direction <= 1) + //if (MetaData == m_Player->GetWorld()->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ) && a_Packet->m_Direction == 1) + { + a_Packet->m_ItemType = E_BLOCK_DOUBLE_STEP; + if(a_Packet->m_Direction == 1) + { + a_Packet->m_PosY--; + } + else + { + a_Packet->m_PosY++; + } + bIgnoreCollision = true; + } + } + + // Special handling for special items: + switch (a_Packet->m_ItemType) + { + case E_ITEM_BUCKET: + { + // TODO: Change this, it is just a small hack to get it working a little bit. seems like the Client sends the position from the first hitable block :s + ClickedBlock = (int)m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ); + LOG("Bucket Clicked BlockID: %d", ClickedBlock); + switch (ClickedBlock) + { + case E_BLOCK_WATER: + case E_BLOCK_STATIONARY_WATER: + { + WaterBucket = true; + break; + } + case E_BLOCK_LAVA: + case E_BLOCK_STATIONARY_LAVA: + { + LavaBucket = true; + break; + } + } + break; + } // case E_ITEM_BUCKET + + case E_ITEM_LAVA_BUCKET: + { + if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item))) + { + a_Packet->m_ItemType = E_BLOCK_LAVA; + if (m_Player->GetGameMode() == 1) + { + break; //No new Bucket for creative players + } + + cItem NewItem; + NewItem.m_ItemID = E_ITEM_BUCKET; + NewItem.m_ItemCount = 1; + m_Player->GetInventory().AddItem(NewItem); + } + break; + } // case E_ITEM_LAVA_BUCKET + + case E_ITEM_WATER_BUCKET: + { + if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item))) + { + a_Packet->m_ItemType = E_BLOCK_WATER; + if (m_Player->GetGameMode() == 1) + { + break; //No new Bucket for creative players + } + cItem NewItem; + NewItem.m_ItemID = E_ITEM_BUCKET; + NewItem.m_ItemCount = 1; + m_Player->GetInventory().AddItem(NewItem); + } + break; + } + + case E_BLOCK_TORCH: + { + MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction); + break; + } + + case E_BLOCK_REDSTONE_TORCH_OFF: + { + MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction); + if (g_BlockTransparent[ (int)m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY+2, a_Packet->m_PosZ) ] == true) + { + //if block above is transparent + //printf("transparent above me\n"); + } + else + { + //printf("transparent not above me\n"); + } + UpdateRedstone = true; + AddedCurrent = false; + break; + } + + case E_BLOCK_REDSTONE_TORCH_ON: + { + MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction); + UpdateRedstone = true; + AddedCurrent = true; + break; + } + + case E_ITEM_REDSTONE_DUST: + { + MetaData = 0; + a_Packet->m_ItemType = E_BLOCK_REDSTONE_WIRE; + UpdateRedstone = true; + AddedCurrent = false; + break; + } + + case E_ITEM_REDSTONE_REPEATER: + { + MetaData = cRedstone::RepeaterRotationToMetaData(m_Player->GetRotation()); + a_Packet->m_ItemType = E_BLOCK_REDSTONE_REPEATER_OFF; + UpdateRedstone = true; + AddedCurrent = false; + break; + } + + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + { + MetaData = cPiston::RotationPitchToMetaData(m_Player->GetRotation(), m_Player->GetPitch()); + UpdateRedstone = true; + AddedCurrent = false; + break; + } + + case E_ITEM_IRON_DOOR: + { + a_Packet->m_ItemType = E_BLOCK_IRON_DOOR; + MetaData = cDoors::RotationToMetaData(m_Player->GetRotation()); + isDoor = true; + break; + } + + case E_ITEM_WOODEN_DOOR: + { + a_Packet->m_ItemType = E_BLOCK_WOODEN_DOOR; + MetaData = cDoors::RotationToMetaData(m_Player->GetRotation()); + isDoor = true; + break; + } + + case E_BLOCK_CHEST: + case E_BLOCK_FURNACE: + case E_BLOCK_DISPENSER: + { + MetaData = cPiston::RotationPitchToMetaData(m_Player->GetRotation(), 0); // Same orientation as pistons, just ignore pitch + break; + } + + case E_BLOCK_STEP: + { + MetaData += cStep::DirectionToMetaData( a_Packet->m_Direction ); + break; + } + + case E_BLOCK_COBBLESTONE_STAIRS: + case E_BLOCK_BRICK_STAIRS: + case E_BLOCK_STONE_BRICK_STAIRS: + case E_BLOCK_NETHER_BRICK_STAIRS: + case E_BLOCK_WOODEN_STAIRS: + { + MetaData = cStairs::RotationToMetaData(m_Player->GetRotation(), a_Packet->m_Direction); + break; + } + case E_BLOCK_LADDER: + { + MetaData = cLadder::DirectionToMetaData(a_Packet->m_Direction); + break; + } + case E_ITEM_SIGN: + { + LOGD("Sign Dir: %i", a_Packet->m_Direction); + if (a_Packet->m_Direction == 1) + { + LOGD("Player Rotation: %f", m_Player->GetRotation()); + MetaData = cSign::RotationToMetaData(m_Player->GetRotation()); + LOGD("Sign rotation %i", MetaData); + a_Packet->m_ItemType = E_BLOCK_SIGN_POST; + } + else + { + MetaData = cSign::DirectionToMetaData(a_Packet->m_Direction); + a_Packet->m_ItemType = E_BLOCK_WALLSIGN; + } + break; + } + + case E_ITEM_FLINT_AND_STEEL: + { + a_Packet->m_ItemType = E_ITEM_FIRE; + m_Player->UseEquippedItem(); + bRemoveItem = false; + break; + } + case E_ITEM_SEEDS: + { + if (ClickedBlock != E_BLOCK_FARMLAND) + { + return; + } + a_Packet->m_ItemType = E_BLOCK_CROPS; + break; + } + case E_ITEM_MELON_SEEDS: + { + if (ClickedBlock != E_BLOCK_FARMLAND) + { + return; + } + a_Packet->m_ItemType = E_BLOCK_MELON_STEM; + break; + } + case E_ITEM_PUMPKIN_SEEDS: + { + if (ClickedBlock != E_BLOCK_FARMLAND) + { + return; + } + a_Packet->m_ItemType = E_BLOCK_PUMPKIN_STEM; + break; + } + case E_ITEM_DYE: + { + // Handle bonemeal and dyes on sheep + if (HandleDyes(a_Packet)) + { + if (m_Player->GetGameMode() == eGameMode_Survival) + { + m_Player->GetInventory().RemoveItem(Item); + } + return; + } + break; + } + case E_ITEM_SUGARCANE: + { + a_Packet->m_ItemType = E_BLOCK_SUGARCANE; + break; + } + default: + { + break; + } + } // switch (a_Packet->m_ItemType) + + + if (LavaBucket) + { + if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item))) { + cItem NewItem; + NewItem.m_ItemID = E_ITEM_LAVA_BUCKET; + NewItem.m_ItemCount = 1; + m_Player->GetInventory().AddItem(NewItem); + m_Player->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0); + } + } + else if (WaterBucket) + { + if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item))) + { + cItem NewItem; + NewItem.m_ItemID = E_ITEM_WATER_BUCKET; + NewItem.m_ItemCount = 1; + m_Player->GetInventory().AddItem(NewItem); + m_Player->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0); + } + } + else if (IsValidBlock(a_Packet->m_ItemType)) + { + int X = a_Packet->m_PosX; + int Y = a_Packet->m_PosY; + int Z = a_Packet->m_PosZ; + AddDirection(X, Y, Z, a_Packet->m_Direction); + + int PlaceBlock = m_Player->GetWorld()->GetBlock(X, Y, Z); + if ( + (PlaceBlock != E_BLOCK_AIR) + && (PlaceBlock != E_BLOCK_WATER) + && (PlaceBlock != E_BLOCK_STATIONARY_WATER) + && (PlaceBlock != E_BLOCK_LAVA) + && (PlaceBlock != E_BLOCK_STATIONARY_LAVA) + && !bIgnoreCollision + ) + { + //tried to place a block *into* another? + return; // happens when you place a block aiming at side of block like torch or stem + } + + // Check whether selected item is allowed to be placed on specific surface + if (!m_Player->GetWorld()->IsPlacingItemLegal(a_Packet->m_ItemType, X, Y, Z)) + { + // If we don't send the block, MC is happy placing cacti underwater: + m_Player->GetWorld()->SendBlockTo(X, Y, Z, m_Player); + return; + } + + if (bRemoveItem) + { + if ((m_Player->GetGameMode() != 1) && !m_Player->GetInventory().RemoveItem(Item)) + { + return; + } + } + + + if (isDoor) + { + if ((m_Player->GetWorld()->GetBlock(X, Y + 1, Z) == E_BLOCK_AIR) || (m_Player->GetWorld()->GetBlock(X, Y + 1, Z) == E_BLOCK_AIR)) + { + m_Player->GetWorld()->SetBlock(X, Y + 1, Z, (char)a_Packet->m_ItemType, MetaData + 8); + m_Player->GetWorld()->SetBlock(X, Y, Z, (char)a_Packet->m_ItemType, MetaData); + } + } + else + { + m_Player->GetWorld()->SetBlock(X, Y, Z, (char)a_Packet->m_ItemType, MetaData); + } + + if (UpdateRedstone) + { + cRedstone Redstone(m_Player->GetWorld()); + Redstone.ChangeRedstone(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, AddedCurrent); + } + } + } + + /* + // FakeTruth's "magic stick of removal" :D + // TODO: Turn this into a plugin + if (m_Username.compare("FakeTruth") == 0) + { + if (a_Packet->m_ItemType == 280) + { + cRoot::Get()->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, 0, 0); + } + } + */ +} + + + + + +void cClientHandle::HandlePickupSpawn(cPacket_PickupSpawn * a_Packet) +{ + LOG("Received packet E_PICKUP_SPAWN"); + + cItem DroppedItem; + DroppedItem.m_ItemID = (ENUM_ITEM_ID)a_Packet->m_Item; + DroppedItem.m_ItemCount = a_Packet->m_Count; + DroppedItem.m_ItemHealth = 0x0; // TODO: Somehow figure out what item was dropped, and apply correct health + if (m_Player->GetInventory().RemoveItem(DroppedItem)) + { + cPickup * Pickup = new cPickup(a_Packet); + Pickup->Initialize(m_Player->GetWorld()); + } +} + + + + + +void cClientHandle::HandleChat(cPacket_Chat * a_Packet) +{ + if (!cRoot::Get()->GetServer()->Command(*this, a_Packet->m_Message.c_str())) + { + a_Packet->m_Message.insert(0, "<" + m_Player->GetColor() + m_Username + cChatColor::White + "> "); + cRoot::Get()->GetServer()->Broadcast(*a_Packet); + } +} + + + + + +void cClientHandle::HandlePlayerLook(cPacket_PlayerLook * a_Packet) +{ + m_Player->SetRotation (a_Packet->m_Rotation); + m_Player->SetPitch (a_Packet->m_Pitch); + m_Player->SetTouchGround(a_Packet->m_bFlying); + m_Player->WrapRotation(); +} + + + + + +void cClientHandle::HandlePlayerMoveLook(cPacket_PlayerMoveLook * a_Packet) +{ + m_Player->MoveTo(Vector3d(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ)); + m_Player->SetStance (a_Packet->m_Stance); + m_Player->SetTouchGround(a_Packet->m_bFlying); + m_Player->SetRotation (a_Packet->m_Rotation); + m_Player->SetPitch (a_Packet->m_Pitch); + m_Player->WrapRotation(); +} + + + + + +void cClientHandle::HandleAnimation(cPacket_ArmAnim * a_Packet) +{ + a_Packet->m_EntityID = m_Player->GetUniqueID(); + cRoot::Get()->GetServer()->Broadcast(*a_Packet, this); +} + + + + + +void cClientHandle::HandleItemSwitch(cPacket_ItemSwitch * a_Packet) +{ + m_Player->GetInventory().SetEquippedSlot(a_Packet->m_SlotNum); + + cPacket_EntityEquipment Equipment; + Equipment.m_ItemID = (short)m_Player->GetInventory().GetEquippedItem().m_ItemID; + Equipment.m_Slot = 0; + Equipment.m_UniqueID = m_Player->GetUniqueID(); + cRoot::Get()->GetServer()->Broadcast(Equipment, this); +} + + + + + +void cClientHandle::HandleWindowClose(cPacket_WindowClose * a_Packet) +{ + m_Player->CloseWindow(a_Packet->m_Close); +} + + + + + +void cClientHandle::HandleWindowClick(cPacket_WindowClick * a_Packet) +{ + if (a_Packet->m_WindowID == 0) + { + m_Player->GetInventory().Clicked(a_Packet); + return; + } + + cWindow * Window = m_Player->GetWindow(); + if (Window == NULL) + { + LOGWARNING("Player \"%s\" clicked in a non-existent window. Ignoring", m_Username.c_str()); + return; + } + + Window->Clicked(a_Packet, *m_Player); +} + + + + + +void cClientHandle::HandleUpdateSign(cPacket_UpdateSign * a_Packet) +{ + cWorld * World = m_Player->GetWorld(); + World->UpdateSign(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Line1, a_Packet->m_Line2, a_Packet->m_Line3, a_Packet->m_Line4); +} + + + + + +void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet) +{ + if (!a_Packet->m_bLeftClick) + { + return; + } + + class cDamageEntity : public cEntityCallback + { + virtual bool Item(cEntity * a_Entity) override + { + if( a_Entity->IsA("cPawn") ) + { + reinterpret_cast< cPawn* >( a_Entity )->TakeDamage(Damage, Instigator ); + } + return true; + } + public: + int Damage; + cEntity * Instigator; + } Callback; + + Callback.Damage = 1; // TODO: Find proper damage from current item equipped + Callback.Instigator = m_Player; + + cWorld * World = m_Player->GetWorld(); + World->DoWithEntity( a_Packet->m_TargetID, Callback ); +} + + + + + +void cClientHandle::HandleRespawn(void) +{ + m_Player->Respawn(); +} + + + + + +void cClientHandle::HandleDisconnect(cPacket_Disconnect * a_Packet) +{ + LOG("Received d/c packet from \"%s\"", m_Username.c_str()); + if (!cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_DISCONNECT, 2, a_Packet->m_Reason.c_str(), m_Player)) + { + cPacket_Chat DisconnectMessage(m_Username + " disconnected: " + a_Packet->m_Reason); + cRoot::Get()->GetServer()->Broadcast(DisconnectMessage); + } + Destroy(); +} + + + + + +void cClientHandle::HandleKeepAlive(cPacket_KeepAlive * a_Packet) +{ + if (a_Packet->m_KeepAliveID == m_PingID) + { + cTimer t1; + m_Ping = (short)((t1.GetNowTime() - m_PingStartTime) / 2); + } +} + + + + + +bool cClientHandle::HandleDyes(cPacket_BlockPlace * a_Packet) +{ + cItem & Equipped = m_Player->GetInventory().GetEquippedItem(); + + // TODO: Handle coloring the sheep, too + + // Handle growing the plants: + if (Equipped.m_ItemHealth == E_META_DYE_WHITE) + { + cWorld * World = m_Player->GetWorld(); + return World->GrowPlant(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, true); + } + + return false; +} + + + + + +bool cClientHandle::CheckBlockInteractionsRate(void) +{ + ASSERT(m_Player != NULL); + ASSERT(m_Player->GetWorld() != NULL); + int LastActionCnt = m_Player->GetLastBlockActionCnt(); + if ((m_Player->GetWorld()->GetTime() - m_Player->GetLastBlockActionTime()) < 0.1) + { + // Limit the number of block interactions per tick + m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time. + m_Player->SetLastBlockActionCnt(LastActionCnt + 1); + if (m_Player->GetLastBlockActionCnt() > MAXBLOCKCHANGEINTERACTIONS) + { + // Kick if more than MAXBLOCKCHANGEINTERACTIONS per tick + LOGWARN("Player %s tried to interact with a block too quickly! (could indicate bot) Was Kicked.", m_Username.c_str()); + Kick("You're a baaaaaad boy!"); + return false; + } + } + else + { + m_Player->SetLastBlockActionCnt(0); // Reset count + m_Player->SetLastBlockActionTime(); // Player tried to interact with a block. Reset last block interation time. + } + return true; +} + + + + + +void cClientHandle::Tick(float a_Dt) +{ + (void)a_Dt; + if (cWorld::GetTime() - m_TimeLastPacket > 30.f) // 30 seconds time-out + { + cPacket_Disconnect DC("Nooooo!! You timed out! D: Come back!"); + m_Socket.Send(&DC); + + // TODO: Cannot sleep in the tick thread! + cSleep::MilliSleep(1000); // Give packet some time to be received + + Destroy(); + } + + cTimer t1; + // Send ping packet + if (m_LastPingTime + cClientHandle::PING_TIME_MS <= t1.GetNowTime()) + { + m_PingID++; + cPacket_KeepAlive Ping(m_PingID); + m_PingStartTime = t1.GetNowTime(); + Send(Ping); + m_LastPingTime = m_PingStartTime; + } +} + + + + + +void cClientHandle::Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority /* = E_PRIORITY_NORMAL */) +{ + if (m_bKicking) return; // Don't add more packets if player is getting kicked anyway + + // If it is the packet spawning myself for myself, drop it silently: + if (a_Packet.m_PacketID == E_NAMED_ENTITY_SPAWN) + { + if (((cPacket_NamedEntitySpawn &)a_Packet).m_UniqueID == m_Player->GetUniqueID()) + { + return; + } + } + + // Filter out packets that don't belong to a csDownloadingWorld state: + if (m_State == csDownloadingWorld) + { + switch (a_Packet.m_PacketID) + { + case E_PLAYERMOVELOOK: + case E_KEEP_ALIVE: + case E_PRE_CHUNK: + case E_MAP_CHUNK: + { + // Allow + break; + } + default: return; + } + } + + // Filter out map chunks that the client doesn't want anymore: + if (a_Packet.m_PacketID == E_MAP_CHUNK) + { + // Check chunks being sent, erase them from m_ChunksToSend: + int ChunkX = ((cPacket_MapChunk &)a_Packet).m_PosX; + int ChunkZ = ((cPacket_MapChunk &)a_Packet).m_PosZ; + bool Found = false; + cCSLock Lock(m_CSChunkLists); + for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end(); ++itr) + { + if ((itr->m_ChunkX == ChunkX) && (itr->m_ChunkZ == ChunkZ)) + { + m_ChunksToSend.erase(itr); + CheckIfWorldDownloaded(); + Found = true; + break; + } + } // for itr - m_ChunksToSend[] + if (!Found) + { + // This just sometimes happens. If you have a reliably replicatable situation for this, go ahead and fix it + // It's not a big issue anyway, just means that some chunks may be compressed several times + // LOGD("Refusing to send chunk [%d, %d] to client \"%s\" at [%d, %d].", ChunkX, ChunkZ, m_Username.c_str(), m_Player->GetChunkX(), m_Player->GetChunkZ()); + return; + } + } + + // Filter out pre chunks that the client doesn't want anymore: + if ((a_Packet.m_PacketID == E_PRE_CHUNK) && ((cPacket_PreChunk &)a_Packet).m_bLoad) + { + int ChunkX = ((cPacket_PreChunk &)a_Packet).m_PosX; + int ChunkZ = ((cPacket_PreChunk &)a_Packet).m_PosZ; + bool Found = false; + cCSLock Lock(m_CSChunkLists); + for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end(); ++itr) + { + if ((itr->m_ChunkX == ChunkX) && (itr->m_ChunkZ == ChunkZ)) + { + Found = true; + break; + } + } // for itr - m_ChunksToSend[] + if (!Found) + { + // This just sometimes happens. If you have a reliably replicatable situation for this, go ahead and fix it + // It's not a big issue anyway, just means that some chunks may be compressed several times + // LOGD("Refusing to send PREchunk [%d, %d] to client \"%s\" at [%d, %d].", ChunkX, ChunkZ, m_Username.c_str(), m_Player->GetChunkX(), m_Player->GetChunkZ()); + return; + } + } + + // Optimize away multiple queued RelativeEntityMoveLook packets: + cCSLock Lock(m_CSPackets); + if (a_Priority == E_PRIORITY_NORMAL) + { + if (a_Packet.m_PacketID == E_REL_ENT_MOVE_LOOK) + { + PacketList & Packets = m_PendingNrmSendPackets; + const cPacket_RelativeEntityMoveLook & ThisPacketData = reinterpret_cast< const cPacket_RelativeEntityMoveLook &>(a_Packet); + for (PacketList::iterator itr = Packets.begin(); itr != Packets.end(); ++itr) + { + bool bBreak = false; + switch ((*itr)->m_PacketID) + { + case E_REL_ENT_MOVE_LOOK: + { + cPacket_RelativeEntityMoveLook * PacketData = reinterpret_cast< cPacket_RelativeEntityMoveLook *>(*itr); + if (ThisPacketData.m_UniqueID == PacketData->m_UniqueID) + { + Packets.erase(itr); + bBreak = true; + delete PacketData; + break; + } + break; + } // case E_REL_END_MOVE_LOOK + } // switch (*itr -> Packet type) + if (bBreak) + { + break; + } + } // for itr - Packets[] + } // if (E_REL_ENT_MOVE_LOOK + m_PendingNrmSendPackets.push_back(a_Packet.Clone()); + } + else if (a_Priority == E_PRIORITY_LOW) + { + m_PendingLowSendPackets.push_back(a_Packet.Clone()); + } + Lock.Unlock(); + + // Notify SocketThreads that we have something to write: + cRoot::Get()->GetServer()->NotifyClientWrite(this); +} + + + + + +void cClientHandle::CheckIfWorldDownloaded(void) +{ + if (m_State != csDownloadingWorld) + { + return; + } + cCSLock Lock(m_CSChunkLists); + if (m_ChunksToSend.empty()) + { + SendConfirmPosition(); + } +} + + + + + +void cClientHandle::SendConfirmPosition(void) +{ + LOG("Spawning player \"%s\" at {%.2f, %.2f, %.2f}", + m_Username.c_str(), m_Player->GetPosX(), m_Player->GetPosY(), m_Player->GetPosZ() + ); + + m_State = csConfirmingPos; + + if (!cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_PLAYER_JOIN, 1, m_Player)) + { + // Broadcast that this player has joined the game! Yay~ + cPacket_Chat Joined(m_Username + " joined the game!"); + cRoot::Get()->GetServer()->Broadcast(Joined, this); + } + + m_ConfirmPosition = m_Player->GetPosition(); + Send(cPacket_PlayerMoveLook(m_Player)); +} + + + + + +const AString & cClientHandle::GetUsername(void) const +{ + return m_Username; +} + + + + + +void cClientHandle::SetViewDistance(int a_ViewDistance) +{ + if (a_ViewDistance < MIN_VIEW_DISTANCE) + { + a_ViewDistance = MIN_VIEW_DISTANCE; + } + if (a_ViewDistance > MAX_VIEW_DISTANCE) + { + a_ViewDistance = MAX_VIEW_DISTANCE; + } + m_ViewDistance = a_ViewDistance; + + // Need to re-stream chunks for the change to become apparent: + StreamChunks(); +} + + + + + +bool cClientHandle::WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSChunkLists); + return (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)) != m_ChunksToSend.end()); +} + + + + + +void cClientHandle::AddWantedChunk(int a_ChunkX, int a_ChunkZ) +{ + LOGD("Adding chunk [%d, %d] to wanted chunks for client %p", a_ChunkX, a_ChunkZ, this); + cCSLock Lock(m_CSChunkLists); + if (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ)) == m_ChunksToSend.end()) + { + m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ)); + } +} + + + + + +void cClientHandle::DataReceived(const char * a_Data, int a_Size) +{ + // Data is received from the client + + m_ReceivedData.append(a_Data, a_Size); + + // Parse and handle all complete packets in m_ReceivedData: + while (!m_ReceivedData.empty()) + { + cPacket* pPacket = m_PacketMap[(unsigned char)m_ReceivedData[0]]; + if (pPacket == NULL) + { + LOGERROR("Unknown packet type 0x%02x from client \"%s\"", (unsigned char)m_ReceivedData[0], m_Username.c_str()); + + AString Reason; + Printf(Reason, "[C->S] Unknown PacketID: 0x%02x", (unsigned char)m_ReceivedData[0]); + cPacket_Disconnect DC(Reason); + m_Socket.Send(&DC); + cSleep::MilliSleep(1000); // Give packet some time to be received + Destroy(); + return; + } + + int NumBytes = pPacket->Parse(m_ReceivedData.data() + 1, m_ReceivedData.size() - 1); + if (NumBytes == PACKET_ERROR) + { + LOGERROR("Protocol error while parsing packet type 0x%02x; disconnecting client \"%s\"", (unsigned char)m_ReceivedData[0], m_Username.c_str()); + cPacket_Disconnect DC("Protocol error"); + m_Socket.Send(&DC); + cSleep::MilliSleep(1000); // Give packet some time to be received + Destroy(); + return; + } + else if (NumBytes == PACKET_INCOMPLETE) + { + // Not a complete packet + break; + } + else + { + // Packet parsed successfully, add it to internal queue: + HandlePacket(pPacket); + // Erase the packet from the buffer: + ASSERT(m_ReceivedData.size() > (size_t)NumBytes); + m_ReceivedData.erase(0, NumBytes + 1); + } + } // while (!Received.empty()) +} + + + + + +void cClientHandle::GetOutgoingData(AString & a_Data) +{ + // Data can be sent to client + + cCSLock Lock(m_CSPackets); + if (m_PendingNrmSendPackets.size() + m_PendingLowSendPackets.size() > MAX_OUTGOING_PACKETS) + { + LOGERROR("ERROR: Too many packets in queue for player %s !!", m_Username.c_str()); + cPacket_Disconnect DC("Too many packets in queue."); + m_Socket.Send(DC); + + // DEBUG: Dump all outstanding packets' types to the log: + int Idx = 0; + int ChunkX = m_Player->GetChunkX(); + int ChunkZ = m_Player->GetChunkZ(); + for (PacketList::const_iterator itr = m_PendingNrmSendPackets.begin(); itr != m_PendingNrmSendPackets.end(); ++itr) + { + switch ((*itr)->m_PacketID) + { + case E_MAP_CHUNK: + { + int x = ((cPacket_MapChunk *)(*itr))->m_PosX; + int z = ((cPacket_MapChunk *)(*itr))->m_PosZ; + bool IsWanted = (abs(x - ChunkX) <= m_ViewDistance) && (abs(z - ChunkZ) <= m_ViewDistance); + LOG("Packet %4d: type %2x (MapChunk: %d, %d, %s)", + Idx++, (*itr)->m_PacketID, + x, z, + IsWanted ? "wanted" : "unwanted" + ); + break; + } + + case E_PRE_CHUNK: + { + int x = ((cPacket_PreChunk *)(*itr))->m_PosX; + int z = ((cPacket_PreChunk *)(*itr))->m_PosZ; + bool IsWanted = (abs(x - ChunkX) <= m_ViewDistance) && (abs(z - ChunkZ) <= m_ViewDistance); + bool Loading = ((cPacket_PreChunk *)(*itr))->m_bLoad; + LOG("Packet %4d: type %2x (PreChunk: %d, %d, %s, %s)", + Idx++, (*itr)->m_PacketID, + x, z, + Loading ? "loading" : "unloading", + IsWanted ? "wanted" : "unwanted" + ); + break; + } + + case E_BLOCK_CHANGE: + { + int x = ((cPacket_BlockChange *)(*itr))->m_PosX; + int z = ((cPacket_BlockChange *)(*itr))->m_PosZ; + char ToBlock = ((cPacket_BlockChange *)(*itr))->m_BlockType; + int y, cx, cz; + cChunkDef::AbsoluteToRelative(x, y, z, cx, cz); + bool IsWanted = (abs(cx - ChunkX) <= m_ViewDistance) && (abs(cz - ChunkZ) <= m_ViewDistance); + LOG("Packet %4d: type %2x (BlockChange: [%d, %d], %s chunk; to block %d)", + Idx++, (*itr)->m_PacketID, + cx, cz, + IsWanted ? "wanted" : "unwanted", + ToBlock + ); + break; + } + + case E_MULTI_BLOCK: + { + int cx = ((cPacket_MultiBlock *)(*itr))->m_ChunkX; + int cz = ((cPacket_MultiBlock *)(*itr))->m_ChunkZ; + int NumBlocks = ((cPacket_MultiBlock *)(*itr))->m_NumBlocks; + bool IsWanted = (abs(cx - ChunkX) <= m_ViewDistance) && (abs(cz - ChunkZ) <= m_ViewDistance); + LOG("Packet %4d: type %2x (MultiBlock: [%d, %d], %s chunk, %d blocks)", + Idx++, (*itr)->m_PacketID, + cx, cz, + IsWanted ? "wanted" : "unwanted", + NumBlocks + ); + break; + } + + default: + { + LOG("Packet %4d: type %2x", Idx++, (*itr)->m_PacketID); + break; + } + } + } + + Lock.Unlock(); + Destroy(); + return; + } + + if ((m_PendingNrmSendPackets.size() == 0) && (m_PendingLowSendPackets.size() == 0)) + { + return; + } + + if (m_PendingNrmSendPackets.size() > MAX_OUTGOING_PACKETS / 2) + { + LOGINFO("Suspiciously many pending packets: %i; client \"%s\", LastType: 0x%02x", m_PendingNrmSendPackets.size(), m_Username.c_str(), (*m_PendingNrmSendPackets.rbegin())->m_PacketID); + } + + AString Data; + Data.reserve(1100); + // Serialize normal-priority packets up to 1000 bytes + while (!m_PendingNrmSendPackets.empty() && (Data.size() < 1000)) + { + m_PendingNrmSendPackets.front()->Serialize(Data); + delete m_PendingNrmSendPackets.front(); + m_PendingNrmSendPackets.erase(m_PendingNrmSendPackets.begin()); + } + // Serialize one low-priority packet: + if (!m_PendingLowSendPackets.empty() && Data.empty()) + { + m_PendingLowSendPackets.front()->Serialize(Data); + delete m_PendingLowSendPackets.front(); + m_PendingLowSendPackets.erase(m_PendingLowSendPackets.begin()); + } + Lock.Unlock(); + + a_Data.append(Data); + + // Disconnect player after all packets have been sent + if (m_bKicking && (m_PendingNrmSendPackets.size() + m_PendingLowSendPackets.size() == 0)) + { + Destroy(); + } +} + + + + + +void cClientHandle::SocketClosed(void) +{ + // The socket has been closed for any reason + + // TODO + /* + self->Destroy(); + LOG("Client \"%s\" disconnected", GetLogName().c_str()); + */ +} + + + + diff --git a/source/cClientHandle.h b/source/cClientHandle.h index a2a12573a..790bcc5b2 100644 --- a/source/cClientHandle.h +++ b/source/cClientHandle.h @@ -1,239 +1,239 @@ -
-// cClientHandle.h
-
-// Interfaces to the cClientHandle class representing a client connected to this server. The client need not be a player yet
-
-
-
-
-
-#pragma once
-#ifndef CCLIENTHANDLE_H_INCLUDED
-#define CCLIENTHANDLE_H_INCLUDED
-
-#include "packets/cPacket.h"
-#include "Vector3d.h"
-#include "cSocketThreads.h"
-#include "ChunkDef.h"
-
-#include "packets/cPacket_KeepAlive.h"
-#include "packets/cPacket_Player.h"
-#include "packets/cPacket_Respawn.h"
-#include "packets/cPacket_RelativeEntityMoveLook.h"
-#include "packets/cPacket_Chat.h"
-#include "packets/cPacket_Login.h"
-#include "packets/cPacket_WindowClick.h"
-#include "packets/cPacket_TimeUpdate.h"
-#include "packets/cPacket_BlockDig.h"
-#include "packets/cPacket_Handshake.h"
-#include "packets/cPacket_ArmAnim.h"
-#include "packets/cPacket_BlockPlace.h"
-#include "packets/cPacket_Flying.h"
-#include "packets/cPacket_Disconnect.h"
-#include "packets/cPacket_PickupSpawn.h"
-#include "packets/cPacket_ItemSwitch.h"
-#include "packets/cPacket_EntityEquipment.h"
-#include "packets/cPacket_CreativeInventoryAction.h"
-#include "packets/cPacket_NewInvalidState.h"
-#include "packets/cPacket_UseEntity.h"
-#include "packets/cPacket_WindowClose.h"
-#include "packets/cPacket_UpdateSign.h"
-#include "packets/cPacket_Ping.h"
-
-
-
-
-
-#define MCS_PROTOCOL_VERSION 29 // Synchronize this with MCS_CLIENT_VERSION below!
-#define MCS_CLIENT_VERSION "1.2.4, 1.2.5"
-
-
-
-
-
-class cPlayer;
-class cRedstone;
-
-
-
-
-
-class cClientHandle : // tolua_export
- public cSocketThreads::cCallback
-{ // tolua_export
-public:
- enum ENUM_PRIORITY
- {
- E_PRIORITY_LOW,
- E_PRIORITY_NORMAL
- };
-
- static const int MAXBLOCKCHANGEINTERACTIONS = 20; // 5 didn't help, 10 still doesn't work in Creative, 20 seems to have done the trick
-
- static const int DEFAULT_VIEW_DISTANCE = 9; // The default ViewDistance (used when no value is set in Settings.ini)
- static const int MAX_VIEW_DISTANCE = 10;
- static const int MIN_VIEW_DISTANCE = 4;
-
- cClientHandle(const cSocket & a_Socket, int a_ViewDistance);
- ~cClientHandle();
-
- const cSocket & GetSocket(void) const {return m_Socket; }
- cSocket & GetSocket(void) {return m_Socket; }
-
- cPlayer* GetPlayer() { return m_Player; } // tolua_export
-
- void Kick(const AString & a_Reason); //tolua_export
- void Authenticate(void); // Called by cAuthenticator when the user passes authentication
-
- void StreamChunks(void);
-
- // Removes the client from all chunks. Used when switching worlds or destroying the player
- void RemoveFromAllChunks(void);
-
- inline bool IsLoggedIn(void) const { return m_State >= csAuthenticating; }
-
- void Tick(float a_Dt);
-
- bool IsDestroyed() { return m_bDestroyed; }
- void Destroy();
-
- bool IsPlaying(void) const {return (m_State == csPlaying); }
-
- void Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority = E_PRIORITY_NORMAL);
-
- const AString & GetUsername(void) const; //tolua_export
-
- inline short GetPing() const { return m_Ping; } //tolua_export
-
- void SetViewDistance(int a_ViewDistance); //tolua_export
- int GetViewDistance() { return m_ViewDistance; }//tolua_export
-
- int GetUniqueID() const { return m_UniqueID; } //tolua_export
-
- /// Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend)
- bool WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- /// Adds the chunk specified to the list of chunks wanted for sending (m_ChunksToSend)
- void AddWantedChunk(int a_ChunkX, int a_ChunkZ);
-
-private:
-
- int m_ViewDistance; // Number of chunks the player can see in each direction; 4 is the minimum ( http://wiki.vg/Protocol_FAQ#.E2.80.A6all_connecting_clients_spasm_and_jerk_uncontrollably.21 )
-
- static const int GENERATEDISTANCE = 2; // Server generates this many chunks AHEAD of player sight. 2 is the minimum, since foliage is generated 1 step behind chunk terrain generation
-
- int m_ProtocolVersion;
- AString m_Username;
- AString m_Password;
-
- AString m_ReceivedData; // Accumulator for the data received from the socket, waiting to be parsed; accessed from the cSocketThreads' thread only!
-
- cCriticalSection m_CSPackets;
- PacketList m_PendingNrmSendPackets;
- PacketList m_PendingLowSendPackets;
-
- cCriticalSection m_CSChunkLists;
- cChunkCoordsList m_LoadedChunks; // Chunks that the player belongs to
- cChunkCoordsList m_ChunksToSend; // Chunks that need to be sent to the player (queued because they weren't generated yet or there's not enough time to send them)
-
- cSocket m_Socket;
-
- cCriticalSection m_CriticalSection;
-
- Vector3d m_ConfirmPosition;
-
- cPacket * m_PacketMap[256];
-
- bool m_bDestroyed;
- cPlayer * m_Player;
- bool m_bKicking;
-
- // Chunk position when the last StreamChunks() was called; used to avoid re-streaming while in the same chunk
- int m_LastStreamedChunkX;
- int m_LastStreamedChunkZ;
-
- float m_TimeLastPacket;
-
- short m_Ping;
- int m_PingID;
- long long m_PingStartTime;
- long long m_LastPingTime;
- static const unsigned short PING_TIME_MS = 1000; //minecraft sends 1 per 20 ticks (1 second or every 1000 ms)
-
- enum eState
- {
- csConnected, // The client has just connected, waiting for their handshake / login
- csAuthenticating, // The client has logged in, waiting for external authentication
- csDownloadingWorld, // The client is waiting for chunks, we're waiting for the loader to provide and send them
- csConfirmingPos, // The client has been sent the position packet, waiting for them to repeat the position back
- csPlaying, // Normal gameplay
-
- // TODO: Add Kicking and Destroyed here as well
- } ;
-
- eState m_State;
-
- bool m_bKeepThreadGoing;
-
- void HandlePacket(cPacket * a_Packet);
-
- // Packets handled in csConnected:
- void HandlePing (void);
- void HandleHandshake (cPacket_Handshake * a_Packet);
- void HandleLogin (cPacket_Login * a_Packet);
- void HandleUnexpectedPacket(cPacket * a_Packet); // the default case -> kick
-
- // Packets handled while in csConfirmingPos:
- void HandleMoveLookConfirm(cPacket_PlayerMoveLook * a_Packet); // While !m_bPositionConfirmed
-
- // Packets handled while in csPlaying:
- void HandleCreativeInventory(cPacket_CreativeInventoryAction * a_Packet);
- void HandlePlayerPos (cPacket_PlayerPosition * a_Packet);
- void HandleBlockDig (cPacket_BlockDig * a_Packet);
- void HandleBlockPlace (cPacket_BlockPlace * a_Packet);
- void HandlePickupSpawn (cPacket_PickupSpawn * a_Packet);
- void HandleChat (cPacket_Chat * a_Packet);
- void HandlePlayerLook (cPacket_PlayerLook * a_Packet);
- void HandlePlayerMoveLook (cPacket_PlayerMoveLook * a_Packet); // While m_bPositionConfirmed (normal gameplay)
- void HandleAnimation (cPacket_ArmAnim * a_Packet);
- void HandleItemSwitch (cPacket_ItemSwitch * a_Packet);
- void HandleWindowClose (cPacket_WindowClose * a_Packet);
- void HandleWindowClick (cPacket_WindowClick * a_Packet);
- void HandleUpdateSign (cPacket_UpdateSign * a_Packet);
- void HandleUseEntity (cPacket_UseEntity * a_Packet);
- void HandleRespawn (void);
- void HandleDisconnect (cPacket_Disconnect * a_Packet);
- void HandleKeepAlive (cPacket_KeepAlive * a_Packet);
-
- /// Handles rclk with a dye; returns true if the dye is to be be consumed
- bool HandleDyes(cPacket_BlockPlace * a_Packet);
-
- /// Returns true if the rate block interactions is within a reasonable limit (bot protection)
- bool CheckBlockInteractionsRate(void);
-
- /// Checks whether all loaded chunks have been sent to the client; if so, sends the position to confirm
- void CheckIfWorldDownloaded(void);
-
- /// Sends the PlayerMoveLook packet that the client needs to reply to for the game to start
- void SendConfirmPosition(void);
-
- /// Adds a single chunk to be streamed to the client; used by StreamChunks()
- void StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- // cSocketThreads::cCallback overrides:
- virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client
- virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client
- virtual void SocketClosed (void) override; // The socket has been closed for any reason
-
- static int s_ClientCount;
- int m_UniqueID;
-}; // tolua_export
-
-
-
-
-#endif // CCLIENTHANDLE_H_INCLUDED
-
-
-
-
+ +// cClientHandle.h + +// Interfaces to the cClientHandle class representing a client connected to this server. The client need not be a player yet + + + + + +#pragma once +#ifndef CCLIENTHANDLE_H_INCLUDED +#define CCLIENTHANDLE_H_INCLUDED + +#include "packets/cPacket.h" +#include "Vector3d.h" +#include "cSocketThreads.h" +#include "ChunkDef.h" + +#include "packets/cPacket_KeepAlive.h" +#include "packets/cPacket_Player.h" +#include "packets/cPacket_Respawn.h" +#include "packets/cPacket_RelativeEntityMoveLook.h" +#include "packets/cPacket_Chat.h" +#include "packets/cPacket_Login.h" +#include "packets/cPacket_WindowClick.h" +#include "packets/cPacket_TimeUpdate.h" +#include "packets/cPacket_BlockDig.h" +#include "packets/cPacket_Handshake.h" +#include "packets/cPacket_ArmAnim.h" +#include "packets/cPacket_BlockPlace.h" +#include "packets/cPacket_Flying.h" +#include "packets/cPacket_Disconnect.h" +#include "packets/cPacket_PickupSpawn.h" +#include "packets/cPacket_ItemSwitch.h" +#include "packets/cPacket_EntityEquipment.h" +#include "packets/cPacket_CreativeInventoryAction.h" +#include "packets/cPacket_NewInvalidState.h" +#include "packets/cPacket_UseEntity.h" +#include "packets/cPacket_WindowClose.h" +#include "packets/cPacket_UpdateSign.h" +#include "packets/cPacket_Ping.h" + + + + + +#define MCS_PROTOCOL_VERSION 29 // Synchronize this with MCS_CLIENT_VERSION below! +#define MCS_CLIENT_VERSION "1.2.4, 1.2.5" + + + + + +class cPlayer; +class cRedstone; + + + + + +class cClientHandle : // tolua_export + public cSocketThreads::cCallback +{ // tolua_export +public: + enum ENUM_PRIORITY + { + E_PRIORITY_LOW, + E_PRIORITY_NORMAL + }; + + static const int MAXBLOCKCHANGEINTERACTIONS = 20; // 5 didn't help, 10 still doesn't work in Creative, 20 seems to have done the trick + + static const int DEFAULT_VIEW_DISTANCE = 9; // The default ViewDistance (used when no value is set in Settings.ini) + static const int MAX_VIEW_DISTANCE = 10; + static const int MIN_VIEW_DISTANCE = 4; + + cClientHandle(const cSocket & a_Socket, int a_ViewDistance); + ~cClientHandle(); + + const cSocket & GetSocket(void) const {return m_Socket; } + cSocket & GetSocket(void) {return m_Socket; } + + cPlayer* GetPlayer() { return m_Player; } // tolua_export + + void Kick(const AString & a_Reason); //tolua_export + void Authenticate(void); // Called by cAuthenticator when the user passes authentication + + void StreamChunks(void); + + // Removes the client from all chunks. Used when switching worlds or destroying the player + void RemoveFromAllChunks(void); + + inline bool IsLoggedIn(void) const { return m_State >= csAuthenticating; } + + void Tick(float a_Dt); + + bool IsDestroyed() { return m_bDestroyed; } + void Destroy(); + + bool IsPlaying(void) const {return (m_State == csPlaying); } + + void Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority = E_PRIORITY_NORMAL); + + const AString & GetUsername(void) const; //tolua_export + + inline short GetPing() const { return m_Ping; } //tolua_export + + void SetViewDistance(int a_ViewDistance); //tolua_export + int GetViewDistance() { return m_ViewDistance; }//tolua_export + + int GetUniqueID() const { return m_UniqueID; } //tolua_export + + /// Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend) + bool WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Adds the chunk specified to the list of chunks wanted for sending (m_ChunksToSend) + void AddWantedChunk(int a_ChunkX, int a_ChunkZ); + +private: + + int m_ViewDistance; // Number of chunks the player can see in each direction; 4 is the minimum ( http://wiki.vg/Protocol_FAQ#.E2.80.A6all_connecting_clients_spasm_and_jerk_uncontrollably.21 ) + + static const int GENERATEDISTANCE = 2; // Server generates this many chunks AHEAD of player sight. 2 is the minimum, since foliage is generated 1 step behind chunk terrain generation + + int m_ProtocolVersion; + AString m_Username; + AString m_Password; + + AString m_ReceivedData; // Accumulator for the data received from the socket, waiting to be parsed; accessed from the cSocketThreads' thread only! + + cCriticalSection m_CSPackets; + PacketList m_PendingNrmSendPackets; + PacketList m_PendingLowSendPackets; + + cCriticalSection m_CSChunkLists; + cChunkCoordsList m_LoadedChunks; // Chunks that the player belongs to + cChunkCoordsList m_ChunksToSend; // Chunks that need to be sent to the player (queued because they weren't generated yet or there's not enough time to send them) + + cSocket m_Socket; + + cCriticalSection m_CriticalSection; + + Vector3d m_ConfirmPosition; + + cPacket * m_PacketMap[256]; + + bool m_bDestroyed; + cPlayer * m_Player; + bool m_bKicking; + + // Chunk position when the last StreamChunks() was called; used to avoid re-streaming while in the same chunk + int m_LastStreamedChunkX; + int m_LastStreamedChunkZ; + + float m_TimeLastPacket; + + short m_Ping; + int m_PingID; + long long m_PingStartTime; + long long m_LastPingTime; + static const unsigned short PING_TIME_MS = 1000; //minecraft sends 1 per 20 ticks (1 second or every 1000 ms) + + enum eState + { + csConnected, // The client has just connected, waiting for their handshake / login + csAuthenticating, // The client has logged in, waiting for external authentication + csDownloadingWorld, // The client is waiting for chunks, we're waiting for the loader to provide and send them + csConfirmingPos, // The client has been sent the position packet, waiting for them to repeat the position back + csPlaying, // Normal gameplay + + // TODO: Add Kicking and Destroyed here as well + } ; + + eState m_State; + + bool m_bKeepThreadGoing; + + void HandlePacket(cPacket * a_Packet); + + // Packets handled in csConnected: + void HandlePing (void); + void HandleHandshake (cPacket_Handshake * a_Packet); + void HandleLogin (cPacket_Login * a_Packet); + void HandleUnexpectedPacket(cPacket * a_Packet); // the default case -> kick + + // Packets handled while in csConfirmingPos: + void HandleMoveLookConfirm(cPacket_PlayerMoveLook * a_Packet); // While !m_bPositionConfirmed + + // Packets handled while in csPlaying: + void HandleCreativeInventory(cPacket_CreativeInventoryAction * a_Packet); + void HandlePlayerPos (cPacket_PlayerPosition * a_Packet); + void HandleBlockDig (cPacket_BlockDig * a_Packet); + void HandleBlockPlace (cPacket_BlockPlace * a_Packet); + void HandlePickupSpawn (cPacket_PickupSpawn * a_Packet); + void HandleChat (cPacket_Chat * a_Packet); + void HandlePlayerLook (cPacket_PlayerLook * a_Packet); + void HandlePlayerMoveLook (cPacket_PlayerMoveLook * a_Packet); // While m_bPositionConfirmed (normal gameplay) + void HandleAnimation (cPacket_ArmAnim * a_Packet); + void HandleItemSwitch (cPacket_ItemSwitch * a_Packet); + void HandleWindowClose (cPacket_WindowClose * a_Packet); + void HandleWindowClick (cPacket_WindowClick * a_Packet); + void HandleUpdateSign (cPacket_UpdateSign * a_Packet); + void HandleUseEntity (cPacket_UseEntity * a_Packet); + void HandleRespawn (void); + void HandleDisconnect (cPacket_Disconnect * a_Packet); + void HandleKeepAlive (cPacket_KeepAlive * a_Packet); + + /// Handles rclk with a dye; returns true if the dye is to be be consumed + bool HandleDyes(cPacket_BlockPlace * a_Packet); + + /// Returns true if the rate block interactions is within a reasonable limit (bot protection) + bool CheckBlockInteractionsRate(void); + + /// Checks whether all loaded chunks have been sent to the client; if so, sends the position to confirm + void CheckIfWorldDownloaded(void); + + /// Sends the PlayerMoveLook packet that the client needs to reply to for the game to start + void SendConfirmPosition(void); + + /// Adds a single chunk to be streamed to the client; used by StreamChunks() + void StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + // cSocketThreads::cCallback overrides: + virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client + virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client + virtual void SocketClosed (void) override; // The socket has been closed for any reason + + static int s_ClientCount; + int m_UniqueID; +}; // tolua_export + + + + +#endif // CCLIENTHANDLE_H_INCLUDED + + + + diff --git a/source/cCow.cpp b/source/cCow.cpp index 18c78aeb1..c4f4ed523 100644 --- a/source/cCow.cpp +++ b/source/cCow.cpp @@ -1,56 +1,56 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cCow.h"
-
-
-
-
-
-// TODO: Milk Cow
-
-
-
-
-
-cCow::cCow()
-{
- m_MobType = 92;
- GetMonsterConfig("Cow");
-}
-
-
-
-
-
-cCow::~cCow()
-{
-}
-
-
-
-
-
-bool cCow::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cCow" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
-
-
-
-
-
-void cCow::KilledBy( cEntity* a_Killer )
-{
- cItems Drops;
- AddRandomDropItem(Drops, 0, 2, E_ITEM_LEATHER);
- AddRandomDropItem(Drops, 1, 3, (GetMetaData() == BURNING) ? E_ITEM_STEAK : E_ITEM_RAW_BEEF);
- m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
-
- cMonster::KilledBy( a_Killer );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cCow.h" + + + + + +// TODO: Milk Cow + + + + + +cCow::cCow() +{ + m_MobType = 92; + GetMonsterConfig("Cow"); +} + + + + + +cCow::~cCow() +{ +} + + + + + +bool cCow::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cCow" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cCow::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_LEATHER); + AddRandomDropItem(Drops, 1, 3, (GetMetaData() == BURNING) ? E_ITEM_STEAK : E_ITEM_RAW_BEEF); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cCraftingWindow.cpp b/source/cCraftingWindow.cpp index 570f1ed9a..9e6b565c6 100644 --- a/source/cCraftingWindow.cpp +++ b/source/cCraftingWindow.cpp @@ -1,131 +1,131 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cCraftingWindow.h"
-#include "cItem.h"
-#include "CraftingRecipes.h"
-#include "cPlayer.h"
-#include "cClientHandle.h"
-#include "cInventory.h"
-#include "cPickup.h"
-#include "cRoot.h"
-#include "cWorld.h"
-
-#include "packets/cPacket_WindowClick.h"
-#include "packets/cPacket_InventorySlot.h"
-
-
-
-
-
-cCraftingWindow::cCraftingWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible )
- : cWindow( a_Owner, a_bInventoryVisible )
-{
- SetWindowID( 1 );
- SetWindowType( cWindow::Workbench ); // Workbench
-
- cItem* Slots = new cItem[10];
- SetSlots( Slots, 10 );
-}
-
-
-
-
-
-void cCraftingWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player )
-{
- bool bDontCook = false;
- // Override for craft result slot
- if( a_ClickPacket->m_SlotNum == 0 )
- {
- LOG("In craft slot: %i x %i !!", GetSlot(0)->m_ItemID, GetSlot(0)->m_ItemCount );
- cItem* DraggingItem = GetDraggingItem( &a_Player );
- if( DraggingItem->m_ItemID <= 0 )
- {
- *DraggingItem = *GetSlot(0);
- GetSlot(0)->Empty();
- }
- else if( DraggingItem->Equals( *GetSlot(0) ) )
- {
- if( DraggingItem->m_ItemCount + GetSlot(0)->m_ItemCount <= 64 )
- {
- DraggingItem->m_ItemCount += GetSlot(0)->m_ItemCount;
- GetSlot(0)->Empty();
- }
- else
- {
- bDontCook = true;
- }
- }
- else
- {
- bDontCook = true;
- }
- LOG("Dragging Dish %i", DraggingItem->m_ItemCount );
- }
- else
- {
- cWindow::Clicked( a_ClickPacket, a_Player );
- }
-
- if ((a_ClickPacket->m_SlotNum >= 0) && (a_ClickPacket->m_SlotNum < 10))
- {
- cCraftingGrid Grid(GetSlots() + 1, 3, 3);
- cCraftingRecipe Recipe(Grid);
-
- cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe);
-
- if ((a_ClickPacket->m_SlotNum == 0) && !bDontCook)
- {
- // Consume the items from the crafting grid:
- Recipe.ConsumeIngredients(Grid);
-
- // Propagate grid back to m_Slots:
- Grid.CopyToItems(GetSlots() + 1);
-
- // Get the recipe for the new grid contents:
- cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe);
- }
- *GetSlot(0) = Recipe.GetResult();
- LOGD("%s cooked: %i x %i !!", a_Player.GetName().c_str(), GetSlot(0)->m_ItemID, GetSlot(0)->m_ItemCount );
- }
- SendWholeWindow( a_Player.GetClientHandle() );
- a_Player.GetInventory().SendWholeInventory( a_Player.GetClientHandle() );
-
- // Separate packet for result =/ Don't know why
- cPacket_InventorySlot Packet;
- Packet.m_WindowID = (char)GetWindowID();
- Packet.m_SlotNum = 0;
- Packet.m_ItemID = (short)GetSlot(0)->m_ItemID;
- Packet.m_ItemCount = GetSlot(0)->m_ItemCount;
- Packet.m_ItemUses = (char)GetSlot(0)->m_ItemHealth;
- a_Player.GetClientHandle()->Send( Packet );
-}
-
-
-
-
-
-void cCraftingWindow::Close(cPlayer & a_Player)
-{
- // Start from slot 1, don't drop what's in the result slot
- cItems Drops;
- for( int i = 1; i < GetNumSlots(); i++ )
- {
- cItem * Item = GetSlot(i);
- if (!Item->IsEmpty())
- {
- Drops.push_back(*Item);
- }
- Item->Empty();
- }
- float vX = 0, vY = 0, vZ = 0;
- EulerToVector( -a_Player.GetRotation(), a_Player.GetPitch(), vZ, vX, vY);
- vY = -vY*2 + 1.f;
- a_Player.GetWorld()->SpawnItemPickups(Drops, a_Player.GetPosX(), a_Player.GetPosY() + 1.6f, a_Player.GetPosZ(), vX * 2, vY * 2, vZ * 2);
- cWindow::Close(a_Player);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cCraftingWindow.h" +#include "cItem.h" +#include "CraftingRecipes.h" +#include "cPlayer.h" +#include "cClientHandle.h" +#include "cInventory.h" +#include "cPickup.h" +#include "cRoot.h" +#include "cWorld.h" + +#include "packets/cPacket_WindowClick.h" +#include "packets/cPacket_InventorySlot.h" + + + + + +cCraftingWindow::cCraftingWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible ) + : cWindow( a_Owner, a_bInventoryVisible ) +{ + SetWindowID( 1 ); + SetWindowType( cWindow::Workbench ); // Workbench + + cItem* Slots = new cItem[10]; + SetSlots( Slots, 10 ); +} + + + + + +void cCraftingWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ) +{ + bool bDontCook = false; + // Override for craft result slot + if( a_ClickPacket->m_SlotNum == 0 ) + { + LOG("In craft slot: %i x %i !!", GetSlot(0)->m_ItemID, GetSlot(0)->m_ItemCount ); + cItem* DraggingItem = GetDraggingItem( &a_Player ); + if( DraggingItem->m_ItemID <= 0 ) + { + *DraggingItem = *GetSlot(0); + GetSlot(0)->Empty(); + } + else if( DraggingItem->Equals( *GetSlot(0) ) ) + { + if( DraggingItem->m_ItemCount + GetSlot(0)->m_ItemCount <= 64 ) + { + DraggingItem->m_ItemCount += GetSlot(0)->m_ItemCount; + GetSlot(0)->Empty(); + } + else + { + bDontCook = true; + } + } + else + { + bDontCook = true; + } + LOG("Dragging Dish %i", DraggingItem->m_ItemCount ); + } + else + { + cWindow::Clicked( a_ClickPacket, a_Player ); + } + + if ((a_ClickPacket->m_SlotNum >= 0) && (a_ClickPacket->m_SlotNum < 10)) + { + cCraftingGrid Grid(GetSlots() + 1, 3, 3); + cCraftingRecipe Recipe(Grid); + + cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe); + + if ((a_ClickPacket->m_SlotNum == 0) && !bDontCook) + { + // Consume the items from the crafting grid: + Recipe.ConsumeIngredients(Grid); + + // Propagate grid back to m_Slots: + Grid.CopyToItems(GetSlots() + 1); + + // Get the recipe for the new grid contents: + cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe); + } + *GetSlot(0) = Recipe.GetResult(); + LOGD("%s cooked: %i x %i !!", a_Player.GetName().c_str(), GetSlot(0)->m_ItemID, GetSlot(0)->m_ItemCount ); + } + SendWholeWindow( a_Player.GetClientHandle() ); + a_Player.GetInventory().SendWholeInventory( a_Player.GetClientHandle() ); + + // Separate packet for result =/ Don't know why + cPacket_InventorySlot Packet; + Packet.m_WindowID = (char)GetWindowID(); + Packet.m_SlotNum = 0; + Packet.m_ItemID = (short)GetSlot(0)->m_ItemID; + Packet.m_ItemCount = GetSlot(0)->m_ItemCount; + Packet.m_ItemUses = (char)GetSlot(0)->m_ItemHealth; + a_Player.GetClientHandle()->Send( Packet ); +} + + + + + +void cCraftingWindow::Close(cPlayer & a_Player) +{ + // Start from slot 1, don't drop what's in the result slot + cItems Drops; + for( int i = 1; i < GetNumSlots(); i++ ) + { + cItem * Item = GetSlot(i); + if (!Item->IsEmpty()) + { + Drops.push_back(*Item); + } + Item->Empty(); + } + float vX = 0, vY = 0, vZ = 0; + EulerToVector( -a_Player.GetRotation(), a_Player.GetPitch(), vZ, vX, vY); + vY = -vY*2 + 1.f; + a_Player.GetWorld()->SpawnItemPickups(Drops, a_Player.GetPosX(), a_Player.GetPosY() + 1.6f, a_Player.GetPosZ(), vX * 2, vY * 2, vZ * 2); + cWindow::Close(a_Player); +} + + + + diff --git a/source/cCraftingWindow.h b/source/cCraftingWindow.h index df32bf74a..16fe3bb23 100644 --- a/source/cCraftingWindow.h +++ b/source/cCraftingWindow.h @@ -1,13 +1,13 @@ -#pragma once
-
-#include "cWindow.h"
-
-class cWindowOwner;
-class cCraftingWindow : public cWindow
-{
-public:
- cCraftingWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible );
-
- virtual void Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player );
- virtual void Close( cPlayer & a_Player );
+#pragma once + +#include "cWindow.h" + +class cWindowOwner; +class cCraftingWindow : public cWindow +{ +public: + cCraftingWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible ); + + virtual void Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ); + virtual void Close( cPlayer & a_Player ); };
\ No newline at end of file diff --git a/source/cCreativeInventory.cpp b/source/cCreativeInventory.cpp index 51f4a26ed..7083adeb7 100644 --- a/source/cCreativeInventory.cpp +++ b/source/cCreativeInventory.cpp @@ -1,38 +1,38 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cCreativeInventory.h"
-#include "cPlayer.h"
-#include "cClientHandle.h"
-#include "cWindow.h"
-#include "cItem.h"
-#include "cRoot.h"
-
-#include <json/json.h>
-
-#include "packets/cPacket_CreativeInventoryAction.h"
-#include "packets/cPacket_WholeInventory.h"
-#include "packets/cPacket_InventorySlot.h"
-
-cCreativeInventory::~cCreativeInventory()
-{
-}
-
-cCreativeInventory::cCreativeInventory(cPlayer* a_Owner)
- : cInventory(a_Owner)
-{
-
-}
-
-void cCreativeInventory::Clicked( cPacket* a_ClickPacket )
-{
- cPacket_CreativeInventoryAction* Packet = reinterpret_cast<cPacket_CreativeInventoryAction *>(a_ClickPacket);
- short Slot = Packet->m_Slot;
-
- cItem* SlotItem = &(this->m_Slots[Slot]);
-
- SlotItem->m_ItemID = (ENUM_ITEM_ID) Packet->m_ItemID;
- SlotItem->m_ItemHealth = Packet->m_Damage;
- SlotItem->m_ItemCount = Packet->m_Quantity;
-}
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cCreativeInventory.h" +#include "cPlayer.h" +#include "cClientHandle.h" +#include "cWindow.h" +#include "cItem.h" +#include "cRoot.h" + +#include <json/json.h> + +#include "packets/cPacket_CreativeInventoryAction.h" +#include "packets/cPacket_WholeInventory.h" +#include "packets/cPacket_InventorySlot.h" + +cCreativeInventory::~cCreativeInventory() +{ +} + +cCreativeInventory::cCreativeInventory(cPlayer* a_Owner) + : cInventory(a_Owner) +{ + +} + +void cCreativeInventory::Clicked( cPacket* a_ClickPacket ) +{ + cPacket_CreativeInventoryAction* Packet = reinterpret_cast<cPacket_CreativeInventoryAction *>(a_ClickPacket); + short Slot = Packet->m_Slot; + + cItem* SlotItem = &(this->m_Slots[Slot]); + + SlotItem->m_ItemID = (ENUM_ITEM_ID) Packet->m_ItemID; + SlotItem->m_ItemHealth = Packet->m_Damage; + SlotItem->m_ItemCount = Packet->m_Quantity; +} + diff --git a/source/cCreativeInventory.h b/source/cCreativeInventory.h index 996136a27..f38c02c6c 100644 --- a/source/cCreativeInventory.h +++ b/source/cCreativeInventory.h @@ -1,13 +1,13 @@ -#pragma once
-
-#include "cInventory.h"
-
-class cCreativeInventory //tolua_export
- : public cInventory
-{ //tolua_export
-public:
- cCreativeInventory(cPlayer* a_Owner);
- ~cCreativeInventory();
-
- virtual void Clicked( cPacket* a_ClickPacket );
-}; //tolua_export
+#pragma once + +#include "cInventory.h" + +class cCreativeInventory //tolua_export + : public cInventory +{ //tolua_export +public: + cCreativeInventory(cPlayer* a_Owner); + ~cCreativeInventory(); + + virtual void Clicked( cPacket* a_ClickPacket ); +}; //tolua_export diff --git a/source/cCreeper.cpp b/source/cCreeper.cpp index 34573a9bf..208d51845 100644 --- a/source/cCreeper.cpp +++ b/source/cCreeper.cpp @@ -1,52 +1,52 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cCreeper.h"
-
-
-
-
-
-cCreeper::cCreeper()
-{
- m_MobType = 50;
- GetMonsterConfig("Creeper");
-}
-
-
-
-
-
-cCreeper::~cCreeper()
-{
-}
-
-
-
-
-
-bool cCreeper::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cCreeper" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
-
-
-
-
-
-void cCreeper::KilledBy( cEntity* a_Killer )
-{
- cItems Drops;
- AddRandomDropItem(Drops, 0, 2, E_ITEM_GUNPOWDER);
-
- // TODO Check if killed by a skeleton, then drop random music disk
-
- m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
-
- cMonster::KilledBy( a_Killer );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cCreeper.h" + + + + + +cCreeper::cCreeper() +{ + m_MobType = 50; + GetMonsterConfig("Creeper"); +} + + + + + +cCreeper::~cCreeper() +{ +} + + + + + +bool cCreeper::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cCreeper" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cCreeper::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_GUNPOWDER); + + // TODO Check if killed by a skeleton, then drop random music disk + + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cCriticalSection.cpp b/source/cCriticalSection.cpp index f66e6b878..e8d719a45 100644 --- a/source/cCriticalSection.cpp +++ b/source/cCriticalSection.cpp @@ -1,157 +1,157 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cCriticalSection:
-
-cCriticalSection::cCriticalSection()
-{
-#ifdef _WIN32
- InitializeCriticalSection( &m_CriticalSection );
-#else
- m_Attributes = new pthread_mutexattr_t;
- pthread_mutexattr_init((pthread_mutexattr_t*)m_Attributes);
- pthread_mutexattr_settype((pthread_mutexattr_t*)m_Attributes, PTHREAD_MUTEX_RECURSIVE);
-
- m_CriticalSectionPtr = new pthread_mutex_t;
- if( pthread_mutex_init( (pthread_mutex_t*)m_CriticalSectionPtr, (pthread_mutexattr_t*)m_Attributes ) != 0 )
- {
- LOG("ERROR: Could not initialize Critical Section!");
- }
-#endif
-}
-
-
-
-
-
-cCriticalSection::~cCriticalSection()
-{
-#ifdef _WIN32
- DeleteCriticalSection( &m_CriticalSection );
-#else
- if( pthread_mutex_destroy( (pthread_mutex_t*)m_CriticalSectionPtr ) != 0 )
- {
- LOG("ERROR: Could not destroy Critical Section!");
- }
- delete (pthread_mutex_t*)m_CriticalSectionPtr;
- pthread_mutexattr_destroy( (pthread_mutexattr_t*)m_Attributes );
- delete (pthread_mutexattr_t*)m_Attributes;
-#endif
-}
-
-
-
-
-
-void cCriticalSection::Lock()
-{
-#ifdef _WIN32
- EnterCriticalSection( &m_CriticalSection );
-#else
- pthread_mutex_lock( (pthread_mutex_t*)m_CriticalSectionPtr );
-#endif
-}
-
-
-
-
-
-void cCriticalSection::Unlock()
-{
-#ifdef _WIN32
- LeaveCriticalSection( &m_CriticalSection );
-#else
- pthread_mutex_unlock( (pthread_mutex_t*)m_CriticalSectionPtr );
-#endif
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cCSLock
-
-cCSLock::cCSLock(cCriticalSection * a_CS)
- : m_CS(a_CS)
- , m_IsLocked(false)
-{
- Lock();
-}
-
-
-
-
-
-cCSLock::cCSLock(cCriticalSection & a_CS)
- : m_CS(&a_CS)
- , m_IsLocked(false)
-{
- Lock();
-}
-
-
-
-
-
-cCSLock::~cCSLock()
-{
- if (!m_IsLocked)
- {
- return;
- }
- Unlock();
-}
-
-
-
-
-
-void cCSLock::Lock(void)
-{
- ASSERT(!m_IsLocked);
- m_IsLocked = true;
- m_CS->Lock();
-}
-
-
-
-
-
-void cCSLock::Unlock(void)
-{
- ASSERT(m_IsLocked);
- m_IsLocked = false;
- m_CS->Unlock();
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cCSUnlock:
-
-cCSUnlock::cCSUnlock(cCSLock & a_Lock) :
- m_Lock(a_Lock)
-{
- m_Lock.Unlock();
-}
-
-
-
-
-
-cCSUnlock::~cCSUnlock()
-{
- m_Lock.Lock();
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCriticalSection: + +cCriticalSection::cCriticalSection() +{ +#ifdef _WIN32 + InitializeCriticalSection( &m_CriticalSection ); +#else + m_Attributes = new pthread_mutexattr_t; + pthread_mutexattr_init((pthread_mutexattr_t*)m_Attributes); + pthread_mutexattr_settype((pthread_mutexattr_t*)m_Attributes, PTHREAD_MUTEX_RECURSIVE); + + m_CriticalSectionPtr = new pthread_mutex_t; + if( pthread_mutex_init( (pthread_mutex_t*)m_CriticalSectionPtr, (pthread_mutexattr_t*)m_Attributes ) != 0 ) + { + LOG("ERROR: Could not initialize Critical Section!"); + } +#endif +} + + + + + +cCriticalSection::~cCriticalSection() +{ +#ifdef _WIN32 + DeleteCriticalSection( &m_CriticalSection ); +#else + if( pthread_mutex_destroy( (pthread_mutex_t*)m_CriticalSectionPtr ) != 0 ) + { + LOG("ERROR: Could not destroy Critical Section!"); + } + delete (pthread_mutex_t*)m_CriticalSectionPtr; + pthread_mutexattr_destroy( (pthread_mutexattr_t*)m_Attributes ); + delete (pthread_mutexattr_t*)m_Attributes; +#endif +} + + + + + +void cCriticalSection::Lock() +{ +#ifdef _WIN32 + EnterCriticalSection( &m_CriticalSection ); +#else + pthread_mutex_lock( (pthread_mutex_t*)m_CriticalSectionPtr ); +#endif +} + + + + + +void cCriticalSection::Unlock() +{ +#ifdef _WIN32 + LeaveCriticalSection( &m_CriticalSection ); +#else + pthread_mutex_unlock( (pthread_mutex_t*)m_CriticalSectionPtr ); +#endif +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCSLock + +cCSLock::cCSLock(cCriticalSection * a_CS) + : m_CS(a_CS) + , m_IsLocked(false) +{ + Lock(); +} + + + + + +cCSLock::cCSLock(cCriticalSection & a_CS) + : m_CS(&a_CS) + , m_IsLocked(false) +{ + Lock(); +} + + + + + +cCSLock::~cCSLock() +{ + if (!m_IsLocked) + { + return; + } + Unlock(); +} + + + + + +void cCSLock::Lock(void) +{ + ASSERT(!m_IsLocked); + m_IsLocked = true; + m_CS->Lock(); +} + + + + + +void cCSLock::Unlock(void) +{ + ASSERT(m_IsLocked); + m_IsLocked = false; + m_CS->Unlock(); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCSUnlock: + +cCSUnlock::cCSUnlock(cCSLock & a_Lock) : + m_Lock(a_Lock) +{ + m_Lock.Unlock(); +} + + + + + +cCSUnlock::~cCSUnlock() +{ + m_Lock.Lock(); +} + + + + diff --git a/source/cCriticalSection.h b/source/cCriticalSection.h index 0a149a95a..a8b475503 100644 --- a/source/cCriticalSection.h +++ b/source/cCriticalSection.h @@ -1,71 +1,71 @@ -
-#pragma once
-
-
-
-
-
-class cCriticalSection
-{
-public:
- cCriticalSection(void);
- ~cCriticalSection();
-
- void Lock(void);
- void Unlock(void);
-
-private:
-
- #ifdef _WIN32
- CRITICAL_SECTION m_CriticalSection;
- #else // _WIN32
- void* m_CriticalSectionPtr ALIGN_8; // Pointer to a CRITICAL_SECTION object
- void* m_Attributes ALIGN_8;
- #endif // else _WIN32
-} ALIGN_8;
-
-
-
-
-/// RAII for cCriticalSection - locks the CS on creation, unlocks on destruction
-class cCSLock
-{
- cCriticalSection * m_CS;
-
- // Unlike a cCriticalSection, this object should be used from a single thread, therefore access to m_IsLocked is not threadsafe
- // In Windows, it is an error to call cCriticalSection::Unlock() multiple times if the lock is not held,
- // therefore we need to check this value whether we are locked or not.
- bool m_IsLocked;
-
-public:
- cCSLock(cCriticalSection * a_CS);
- cCSLock(cCriticalSection & a_CS);
- ~cCSLock();
-
- // Temporarily unlock or re-lock:
- void Lock(void);
- void Unlock(void);
-
-private:
- DISALLOW_COPY_AND_ASSIGN(cCSLock);
-} ;
-
-
-
-
-
-/// Temporary RAII unlock for a cCSLock. Useful for unlock-wait-relock scenarios
-class cCSUnlock
-{
- cCSLock & m_Lock;
-public:
- cCSUnlock(cCSLock & a_Lock);
- ~cCSUnlock();
-
-private:
- DISALLOW_COPY_AND_ASSIGN(cCSUnlock);
-} ;
-
-
-
-
+ +#pragma once + + + + + +class cCriticalSection +{ +public: + cCriticalSection(void); + ~cCriticalSection(); + + void Lock(void); + void Unlock(void); + +private: + + #ifdef _WIN32 + CRITICAL_SECTION m_CriticalSection; + #else // _WIN32 + void* m_CriticalSectionPtr ALIGN_8; // Pointer to a CRITICAL_SECTION object + void* m_Attributes ALIGN_8; + #endif // else _WIN32 +} ALIGN_8; + + + + +/// RAII for cCriticalSection - locks the CS on creation, unlocks on destruction +class cCSLock +{ + cCriticalSection * m_CS; + + // Unlike a cCriticalSection, this object should be used from a single thread, therefore access to m_IsLocked is not threadsafe + // In Windows, it is an error to call cCriticalSection::Unlock() multiple times if the lock is not held, + // therefore we need to check this value whether we are locked or not. + bool m_IsLocked; + +public: + cCSLock(cCriticalSection * a_CS); + cCSLock(cCriticalSection & a_CS); + ~cCSLock(); + + // Temporarily unlock or re-lock: + void Lock(void); + void Unlock(void); + +private: + DISALLOW_COPY_AND_ASSIGN(cCSLock); +} ; + + + + + +/// Temporary RAII unlock for a cCSLock. Useful for unlock-wait-relock scenarios +class cCSUnlock +{ + cCSLock & m_Lock; +public: + cCSUnlock(cCSLock & a_Lock); + ~cCSUnlock(); + +private: + DISALLOW_COPY_AND_ASSIGN(cCSUnlock); +} ; + + + + diff --git a/source/cCuboid.cpp b/source/cCuboid.cpp index ecd457549..86600f6b6 100644 --- a/source/cCuboid.cpp +++ b/source/cCuboid.cpp @@ -1,19 +1,19 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cCuboid.h"
-
-
-
-
-
-void cCuboid::Sort()
-{
- if( p1.x > p2.x ) std::swap( p1.x, p2.x );
- if( p1.y > p2.y ) std::swap( p1.y, p2.y );
- if( p1.z > p2.z ) std::swap( p1.z, p2.z );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cCuboid.h" + + + + + +void cCuboid::Sort() +{ + if( p1.x > p2.x ) std::swap( p1.x, p2.x ); + if( p1.y > p2.y ) std::swap( p1.y, p2.y ); + if( p1.z > p2.z ) std::swap( p1.z, p2.z ); +} + + + + diff --git a/source/cCuboid.h b/source/cCuboid.h index 28e222e41..a07d665fc 100644 --- a/source/cCuboid.h +++ b/source/cCuboid.h @@ -1,40 +1,40 @@ -#pragma once
-
-#include "Vector3i.h"
-#include "Vector3d.h"
-
-class cCuboid //tolua_export
-{ //tolua_export
-public: //tolua_export
- cCuboid() {} //tolua_export
- cCuboid( const cCuboid & a_Cuboid ) : p1( a_Cuboid.p1 ), p2( a_Cuboid.p2 ) {} //tolua_export
- cCuboid( const Vector3i & a_p1, const Vector3i & a_p2 ) : p1( a_p1 ), p2( a_p2 ) {} //tolua_export
-
-
- Vector3i p1, p2; //tolua_export
-
- void Sort(); //tolua_export
-
- bool IsInside( const Vector3i & v ) const //tolua_export
- { //tolua_export
- if( v.x >= p1.x && v.x <= p2.x
- && v.y >= p1.y && v.y <= p2.y
- && v.z >= p1.z && v.z <= p2.z )
- {
- return true;
- }
- return false;
- } //tolua_export
-
- bool IsInside( const Vector3d & v ) const //tolua_export
- { //tolua_export
- if( v.x >= p1.x && v.x <= p2.x
- && v.y >= p1.y && v.y <= p2.y
- && v.z >= p1.z && v.z <= p2.z )
- {
- return true;
- }
- return false;
- } //tolua_export
-
+#pragma once + +#include "Vector3i.h" +#include "Vector3d.h" + +class cCuboid //tolua_export +{ //tolua_export +public: //tolua_export + cCuboid() {} //tolua_export + cCuboid( const cCuboid & a_Cuboid ) : p1( a_Cuboid.p1 ), p2( a_Cuboid.p2 ) {} //tolua_export + cCuboid( const Vector3i & a_p1, const Vector3i & a_p2 ) : p1( a_p1 ), p2( a_p2 ) {} //tolua_export + + + Vector3i p1, p2; //tolua_export + + void Sort(); //tolua_export + + bool IsInside( const Vector3i & v ) const //tolua_export + { //tolua_export + if( v.x >= p1.x && v.x <= p2.x + && v.y >= p1.y && v.y <= p2.y + && v.z >= p1.z && v.z <= p2.z ) + { + return true; + } + return false; + } //tolua_export + + bool IsInside( const Vector3d & v ) const //tolua_export + { //tolua_export + if( v.x >= p1.x && v.x <= p2.x + && v.y >= p1.y && v.y <= p2.y + && v.z >= p1.z && v.z <= p2.z ) + { + return true; + } + return false; + } //tolua_export + }; //tolua_export
\ No newline at end of file diff --git a/source/cDoors.h b/source/cDoors.h index dc326104b..212e90062 100644 --- a/source/cDoors.h +++ b/source/cDoors.h @@ -1,62 +1,62 @@ -#pragma once
-#include "cBlockToPickup.h"
-
-
-class cDoors //tolua_export
-{ //tolua_export
-public:
- static char RotationToMetaData( float a_Rotation ) //tolua_export
- { //tolua_export
- a_Rotation += 90 + 45; // So its not aligned with axis
- if( a_Rotation > 360.f ) a_Rotation -= 360.f;
- if( a_Rotation >= 0.f && a_Rotation < 90.f )
- return 0x0;
- else if( a_Rotation >= 180 && a_Rotation < 270 )
- return 0x2;
- else if( a_Rotation >= 90 && a_Rotation < 180 )
- return 0x1;
- else
- return 0x3;
- } //tolua_export
-
- static char ChangeStateMetaData( char a_MetaData ) //tolua_export
- { //tolua_export
-
- a_MetaData ^= 4; //XOR bit 2 aka 3. bit (Door open state)
-
- return a_MetaData;
- } //tolua_export
-
- static void ChangeDoor(cWorld *a_World, int a_X, int a_Y, int a_Z) //tolua_export
- { //tolua_export
- char OldMetaData = a_World->GetBlockMeta(a_X, a_Y, a_Z);
-
- a_World->SetBlockMeta(a_X, a_Y, a_Z, ChangeStateMetaData ( OldMetaData ) );
-
-
- if (OldMetaData & 8)
- { //current block is top of the door
- char BottomBlock = a_World->GetBlock(a_X, a_Y - 1, a_Z);
- char BottomMeta = a_World->GetBlockMeta(a_X, a_Y - 1, a_Z);
-
- if (IsDoor(BottomBlock) && !(BottomMeta & 8))
- {
- a_World->SetBlockMeta(a_X, a_Y - 1, a_Z, ChangeStateMetaData ( BottomMeta ) );
- }
- } else { //current block is bottom of the door
- char TopBlock = a_World->GetBlock(a_X, a_Y + 1, a_Z);
- char TopMeta = a_World->GetBlockMeta(a_X, a_Y + 1, a_Z);
-
- if (IsDoor(TopBlock) && (TopMeta & 8))
- {
- a_World->SetBlockMeta(a_X, a_Y + 1, a_Z, ChangeStateMetaData ( TopMeta ) );
- }
- }
- } //tolua_export
-
- inline static bool IsDoor(char a_Block)
- {
- return (a_Block == E_BLOCK_WOODEN_DOOR || a_Block == E_BLOCK_IRON_DOOR);
- }
-
+#pragma once +#include "cBlockToPickup.h" + + +class cDoors //tolua_export +{ //tolua_export +public: + static char RotationToMetaData( float a_Rotation ) //tolua_export + { //tolua_export + a_Rotation += 90 + 45; // So its not aligned with axis + if( a_Rotation > 360.f ) a_Rotation -= 360.f; + if( a_Rotation >= 0.f && a_Rotation < 90.f ) + return 0x0; + else if( a_Rotation >= 180 && a_Rotation < 270 ) + return 0x2; + else if( a_Rotation >= 90 && a_Rotation < 180 ) + return 0x1; + else + return 0x3; + } //tolua_export + + static char ChangeStateMetaData( char a_MetaData ) //tolua_export + { //tolua_export + + a_MetaData ^= 4; //XOR bit 2 aka 3. bit (Door open state) + + return a_MetaData; + } //tolua_export + + static void ChangeDoor(cWorld *a_World, int a_X, int a_Y, int a_Z) //tolua_export + { //tolua_export + char OldMetaData = a_World->GetBlockMeta(a_X, a_Y, a_Z); + + a_World->SetBlockMeta(a_X, a_Y, a_Z, ChangeStateMetaData ( OldMetaData ) ); + + + if (OldMetaData & 8) + { //current block is top of the door + char BottomBlock = a_World->GetBlock(a_X, a_Y - 1, a_Z); + char BottomMeta = a_World->GetBlockMeta(a_X, a_Y - 1, a_Z); + + if (IsDoor(BottomBlock) && !(BottomMeta & 8)) + { + a_World->SetBlockMeta(a_X, a_Y - 1, a_Z, ChangeStateMetaData ( BottomMeta ) ); + } + } else { //current block is bottom of the door + char TopBlock = a_World->GetBlock(a_X, a_Y + 1, a_Z); + char TopMeta = a_World->GetBlockMeta(a_X, a_Y + 1, a_Z); + + if (IsDoor(TopBlock) && (TopMeta & 8)) + { + a_World->SetBlockMeta(a_X, a_Y + 1, a_Z, ChangeStateMetaData ( TopMeta ) ); + } + } + } //tolua_export + + inline static bool IsDoor(char a_Block) + { + return (a_Block == E_BLOCK_WOODEN_DOOR || a_Block == E_BLOCK_IRON_DOOR); + } + }; //tolua_export
\ No newline at end of file diff --git a/source/cEnderman.cpp b/source/cEnderman.cpp index 8fbad6a39..61bdfe06b 100644 --- a/source/cEnderman.cpp +++ b/source/cEnderman.cpp @@ -1,63 +1,63 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cEnderman.h"
-
-
-
-
-
-cEnderman::cEnderman()
-{
- m_MobType = 58;
- GetMonsterConfig("Enderman");
-}
-
-
-
-
-
-cEnderman::~cEnderman()
-{
-}
-
-
-
-
-
-bool cEnderman::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cEnderman" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
-
-
-
-
-
-void cEnderman::Tick(float a_Dt)
-{
- cMonster::Tick(a_Dt);
-
- //TODO Same as stated in cSkeleton
- if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING) { //if daylight
- SetMetaData(BURNING); // BURN, BABY, BURN! >:D
- }
-}
-
-
-
-
-
-void cEnderman::KilledBy( cEntity* a_Killer )
-{
- cItems Drops;
- AddRandomDropItem(Drops, 0, 1, E_ITEM_ENDER_PEARL);
- m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
-
- cMonster::KilledBy( a_Killer );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cEnderman.h" + + + + + +cEnderman::cEnderman() +{ + m_MobType = 58; + GetMonsterConfig("Enderman"); +} + + + + + +cEnderman::~cEnderman() +{ +} + + + + + +bool cEnderman::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cEnderman" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cEnderman::Tick(float a_Dt) +{ + cMonster::Tick(a_Dt); + + //TODO Same as stated in cSkeleton + if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING) { //if daylight + SetMetaData(BURNING); // BURN, BABY, BURN! >:D + } +} + + + + + +void cEnderman::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 1, E_ITEM_ENDER_PEARL); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cEnderman.h b/source/cEnderman.h index 75b1b22a8..d147cc4e7 100644 --- a/source/cEnderman.h +++ b/source/cEnderman.h @@ -1,15 +1,15 @@ -#pragma once
-
-#include "cPassiveAggressiveMonster.h"
-
-class cEnderman : public cPassiveAggressiveMonster
-{
-public:
- cEnderman();
- ~cEnderman();
-
- virtual bool IsA( const char* a_EntityType );
-
- virtual void Tick(float a_Dt);
- virtual void KilledBy( cEntity* a_Killer );
-};
+#pragma once + +#include "cPassiveAggressiveMonster.h" + +class cEnderman : public cPassiveAggressiveMonster +{ +public: + cEnderman(); + ~cEnderman(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void Tick(float a_Dt); + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/cEntity.cpp b/source/cEntity.cpp index 40bef9cb9..3e0ed7190 100644 --- a/source/cEntity.cpp +++ b/source/cEntity.cpp @@ -1,382 +1,382 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cEntity.h"
-#include "cWorld.h"
-#include "cServer.h"
-#include "cRoot.h"
-#include "Vector3d.h"
-#include "Vector3f.h"
-#include "Matrix4f.h"
-#include "cReferenceManager.h"
-#include "cClientHandle.h"
-
-#include "packets/cPacket_DestroyEntity.h"
-
-
-
-
-
-int cEntity::m_EntityCount = 0;
-cCriticalSection cEntity::m_CSCount;
-
-
-
-
-
-cEntity::cEntity(const double & a_X, const double & a_Y, const double & a_Z)
- : m_UniqueID( 0 )
- , m_Referencers( new cReferenceManager( cReferenceManager::RFMNGR_REFERENCERS ) )
- , m_References( new cReferenceManager( cReferenceManager::RFMNGR_REFERENCES ) )
- , m_ChunkX( 0 )
- , m_ChunkY( 0 )
- , m_ChunkZ( 0 )
- , m_Pos( a_X, a_Y, a_Z )
- , m_bDirtyPosition( true )
- , m_bDirtyOrientation( true )
- , m_bDestroyed( false )
- , m_EntityType( eEntityType_Entity )
- , m_World( 0 )
- , m_bRemovedFromChunk( false )
-{
- cCSLock Lock(m_CSCount);
- m_EntityCount++;
- m_UniqueID = m_EntityCount;
-}
-
-
-
-
-
-cEntity::~cEntity()
-{
- LOG("Deleting entity %d at pos {%.2f, %.2f} ~ [%d, %d]; ptr %p",
- m_UniqueID,
- m_Pos.x, m_Pos.z,
- (int)(m_Pos.x / cChunkDef::Width), (int)(m_Pos.z / cChunkDef::Width),
- this
- );
-
- if( !m_bDestroyed || !m_bRemovedFromChunk )
- {
- LOGERROR("ERROR: Entity deallocated without being destroyed %i or unlinked %i", m_bDestroyed, m_bRemovedFromChunk );
- ASSERT(!"Entity deallocated without being destroyed or unlinked");
- }
- delete m_Referencers;
- delete m_References;
-}
-
-
-
-
-
-void cEntity::Initialize( cWorld* a_World )
-{
- m_World = a_World;
- m_World->AddEntity( this );
-
- MoveToCorrectChunk(true);
-}
-
-
-
-
-
-void cEntity::WrapRotation()
-{
- while (m_Rot.x > 180.f) m_Rot.x-=360.f; // Wrap it
- while (m_Rot.x < -180.f) m_Rot.x+=360.f;
- while (m_Rot.y > 180.f) m_Rot.y-=360.f;
- while (m_Rot.y < -180.f) m_Rot.y+=360.f;
-}
-
-
-
-
-
-void cEntity::MoveToCorrectChunk(bool a_bIgnoreOldChunk)
-{
- ASSERT(m_World != NULL); // Entity needs a world to move to a chunk
- if( !m_World ) return;
-
- int ChunkX = 0, ChunkY = 0, ChunkZ = 0;
- cWorld::BlockToChunk( (int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z, ChunkX, ChunkY, ChunkZ );
- if (!a_bIgnoreOldChunk && (m_ChunkX == ChunkX) && (m_ChunkY == ChunkY) && (m_ChunkZ == ChunkZ))
- {
- return;
- }
-
- class cMover :
- public cClientDiffCallback
- {
- virtual void Removed(cClientHandle * a_Client) override
- {
- if (m_IgnoreOldChunk)
- {
- return;
- }
- if (m_Destroy == NULL)
- {
- m_Destroy = new cPacket_DestroyEntity(m_Entity);
- }
- a_Client->Send(*m_Destroy);
- }
-
- virtual void Added(cClientHandle * a_Client) override
- {
- if (m_Spawn == NULL)
- {
- m_Spawn = m_Entity->GetSpawnPacket(); // Only create the packet when needed
- }
- if (m_Spawn != NULL)
- {
- a_Client->Send(*m_Spawn);
- }
- }
-
- cPacket * m_Destroy;
- cPacket * m_Spawn;
- bool m_IgnoreOldChunk;
- cEntity * m_Entity;
-
- public:
- cMover(cEntity * a_Entity, bool a_IgnoreOldChunk) :
- m_Destroy(NULL),
- m_Spawn(NULL),
- m_IgnoreOldChunk(a_IgnoreOldChunk),
- m_Entity(a_Entity)
- {}
-
- ~cMover()
- {
- delete m_Spawn;
- delete m_Destroy;
- }
- } Mover(this, a_bIgnoreOldChunk);
-
- m_World->CompareChunkClients(m_ChunkX, m_ChunkY, m_ChunkZ, ChunkX, ChunkY, ChunkZ, Mover);
- m_World->MoveEntityToChunk(this, ChunkX, ChunkY, ChunkZ);
-
- m_ChunkX = ChunkX;
- m_ChunkY = ChunkY;
- m_ChunkZ = ChunkZ;
-}
-
-
-
-
-
-void cEntity::Destroy()
-{
- if (m_bDestroyed)
- {
- return;
- }
- if (!m_bRemovedFromChunk)
- {
- RemoveFromChunk();
- }
-
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, cPacket_DestroyEntity(this));
-
- m_bDestroyed = true;
-
- Destroyed();
-}
-
-
-
-
-
-void cEntity::RemoveFromChunk(void)
-{
- if (m_World == NULL)
- {
- return;
- }
-
- m_World->RemoveEntityFromChunk(this, m_ChunkX, m_ChunkY, m_ChunkZ);
- m_bRemovedFromChunk = true;
-}
-
-
-
-
-
-void cEntity::SpawnOn(cClientHandle * a_Client)
-{
- std::auto_ptr<cPacket> SpawnPacket(GetSpawnPacket());
- if (SpawnPacket.get() == NULL)
- {
- return;
- }
-
- if (a_Client == NULL)
- {
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, *SpawnPacket.get(), NULL);
- }
- else
- {
- a_Client->Send(*(SpawnPacket.get()));
- }
-}
-
-
-
-
-
-CLASS_DEF_GETCLASS( cEntity );
-bool cEntity::IsA( const char* a_EntityType )
-{
- //LOG("IsA( cEntity ) : %s", a_EntityType);
- if( strcmp( a_EntityType, "cEntity" ) == 0 ) return true;
- return false;
-}
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////
-// Set orientations
-void cEntity::SetRot( const Vector3f & a_Rot )
-{
- m_Rot = a_Rot;
- m_bDirtyOrientation = true;
-}
-
-
-
-
-
-void cEntity::SetRotation( float a_Rotation )
-{
- m_Rot.x = a_Rotation;
- m_bDirtyOrientation = true;
-}
-
-
-
-
-
-void cEntity::SetPitch( float a_Pitch )
-{
- m_Rot.y = a_Pitch;
- m_bDirtyOrientation = true;
-}
-
-
-
-
-
-void cEntity::SetRoll( float a_Roll )
-{
- m_Rot.z = a_Roll;
- m_bDirtyOrientation = true;
-}
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////
-// Get look vector (this is NOT a rotation!)
-Vector3f cEntity::GetLookVector()
-{
- Matrix4f m;
- m.Init( Vector3f(), 0, m_Rot.x, -m_Rot.y );
- Vector3f Look = m.Transform( Vector3f(0, 0, 1) );
- LOG("Look: %0.1f %0.1f %0.1f", Look.x, Look.y, Look.z );
- return Look;
-}
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////
-// Set position
-void cEntity::SetPosition( const Vector3d & a_Pos )
-{
- m_Pos = a_Pos;
- MoveToCorrectChunk();
- m_bDirtyPosition = true;
-}
-
-
-
-
-
-void cEntity::SetPosition( const double & a_PosX, const double & a_PosY, const double & a_PosZ )
-{
- m_Pos.Set( a_PosX, a_PosY, a_PosZ );
- MoveToCorrectChunk();
- m_bDirtyPosition = true;
-}
-
-
-
-
-
-void cEntity::SetPosX( const double & a_PosX )
-{
- m_Pos.x = a_PosX;
- MoveToCorrectChunk();
- m_bDirtyPosition = true;
-}
-
-
-
-
-
-void cEntity::SetPosY( const double & a_PosY )
-{
- m_Pos.y = a_PosY;
- MoveToCorrectChunk();
- m_bDirtyPosition = true;
-}
-
-
-
-
-
-void cEntity::SetPosZ( const double & a_PosZ )
-{
- m_Pos.z = a_PosZ;
- MoveToCorrectChunk();
- m_bDirtyPosition = true;
-}
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////
-// Reference stuffs
-void cEntity::AddReference( cEntity*& a_EntityPtr )
-{
- m_References->AddReference( a_EntityPtr );
- a_EntityPtr->ReferencedBy( a_EntityPtr );
-}
-
-
-
-
-
-void cEntity::ReferencedBy( cEntity*& a_EntityPtr )
-{
- m_Referencers->AddReference( a_EntityPtr );
-}
-
-
-
-
-
-void cEntity::Dereference( cEntity*& a_EntityPtr )
-{
- m_Referencers->Dereference( a_EntityPtr );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cEntity.h" +#include "cWorld.h" +#include "cServer.h" +#include "cRoot.h" +#include "Vector3d.h" +#include "Vector3f.h" +#include "Matrix4f.h" +#include "cReferenceManager.h" +#include "cClientHandle.h" + +#include "packets/cPacket_DestroyEntity.h" + + + + + +int cEntity::m_EntityCount = 0; +cCriticalSection cEntity::m_CSCount; + + + + + +cEntity::cEntity(const double & a_X, const double & a_Y, const double & a_Z) + : m_UniqueID( 0 ) + , m_Referencers( new cReferenceManager( cReferenceManager::RFMNGR_REFERENCERS ) ) + , m_References( new cReferenceManager( cReferenceManager::RFMNGR_REFERENCES ) ) + , m_ChunkX( 0 ) + , m_ChunkY( 0 ) + , m_ChunkZ( 0 ) + , m_Pos( a_X, a_Y, a_Z ) + , m_bDirtyPosition( true ) + , m_bDirtyOrientation( true ) + , m_bDestroyed( false ) + , m_EntityType( eEntityType_Entity ) + , m_World( 0 ) + , m_bRemovedFromChunk( false ) +{ + cCSLock Lock(m_CSCount); + m_EntityCount++; + m_UniqueID = m_EntityCount; +} + + + + + +cEntity::~cEntity() +{ + LOG("Deleting entity %d at pos {%.2f, %.2f} ~ [%d, %d]; ptr %p", + m_UniqueID, + m_Pos.x, m_Pos.z, + (int)(m_Pos.x / cChunkDef::Width), (int)(m_Pos.z / cChunkDef::Width), + this + ); + + if( !m_bDestroyed || !m_bRemovedFromChunk ) + { + LOGERROR("ERROR: Entity deallocated without being destroyed %i or unlinked %i", m_bDestroyed, m_bRemovedFromChunk ); + ASSERT(!"Entity deallocated without being destroyed or unlinked"); + } + delete m_Referencers; + delete m_References; +} + + + + + +void cEntity::Initialize( cWorld* a_World ) +{ + m_World = a_World; + m_World->AddEntity( this ); + + MoveToCorrectChunk(true); +} + + + + + +void cEntity::WrapRotation() +{ + while (m_Rot.x > 180.f) m_Rot.x-=360.f; // Wrap it + while (m_Rot.x < -180.f) m_Rot.x+=360.f; + while (m_Rot.y > 180.f) m_Rot.y-=360.f; + while (m_Rot.y < -180.f) m_Rot.y+=360.f; +} + + + + + +void cEntity::MoveToCorrectChunk(bool a_bIgnoreOldChunk) +{ + ASSERT(m_World != NULL); // Entity needs a world to move to a chunk + if( !m_World ) return; + + int ChunkX = 0, ChunkY = 0, ChunkZ = 0; + cWorld::BlockToChunk( (int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z, ChunkX, ChunkY, ChunkZ ); + if (!a_bIgnoreOldChunk && (m_ChunkX == ChunkX) && (m_ChunkY == ChunkY) && (m_ChunkZ == ChunkZ)) + { + return; + } + + class cMover : + public cClientDiffCallback + { + virtual void Removed(cClientHandle * a_Client) override + { + if (m_IgnoreOldChunk) + { + return; + } + if (m_Destroy == NULL) + { + m_Destroy = new cPacket_DestroyEntity(m_Entity); + } + a_Client->Send(*m_Destroy); + } + + virtual void Added(cClientHandle * a_Client) override + { + if (m_Spawn == NULL) + { + m_Spawn = m_Entity->GetSpawnPacket(); // Only create the packet when needed + } + if (m_Spawn != NULL) + { + a_Client->Send(*m_Spawn); + } + } + + cPacket * m_Destroy; + cPacket * m_Spawn; + bool m_IgnoreOldChunk; + cEntity * m_Entity; + + public: + cMover(cEntity * a_Entity, bool a_IgnoreOldChunk) : + m_Destroy(NULL), + m_Spawn(NULL), + m_IgnoreOldChunk(a_IgnoreOldChunk), + m_Entity(a_Entity) + {} + + ~cMover() + { + delete m_Spawn; + delete m_Destroy; + } + } Mover(this, a_bIgnoreOldChunk); + + m_World->CompareChunkClients(m_ChunkX, m_ChunkY, m_ChunkZ, ChunkX, ChunkY, ChunkZ, Mover); + m_World->MoveEntityToChunk(this, ChunkX, ChunkY, ChunkZ); + + m_ChunkX = ChunkX; + m_ChunkY = ChunkY; + m_ChunkZ = ChunkZ; +} + + + + + +void cEntity::Destroy() +{ + if (m_bDestroyed) + { + return; + } + if (!m_bRemovedFromChunk) + { + RemoveFromChunk(); + } + + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, cPacket_DestroyEntity(this)); + + m_bDestroyed = true; + + Destroyed(); +} + + + + + +void cEntity::RemoveFromChunk(void) +{ + if (m_World == NULL) + { + return; + } + + m_World->RemoveEntityFromChunk(this, m_ChunkX, m_ChunkY, m_ChunkZ); + m_bRemovedFromChunk = true; +} + + + + + +void cEntity::SpawnOn(cClientHandle * a_Client) +{ + std::auto_ptr<cPacket> SpawnPacket(GetSpawnPacket()); + if (SpawnPacket.get() == NULL) + { + return; + } + + if (a_Client == NULL) + { + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, *SpawnPacket.get(), NULL); + } + else + { + a_Client->Send(*(SpawnPacket.get())); + } +} + + + + + +CLASS_DEF_GETCLASS( cEntity ); +bool cEntity::IsA( const char* a_EntityType ) +{ + //LOG("IsA( cEntity ) : %s", a_EntityType); + if( strcmp( a_EntityType, "cEntity" ) == 0 ) return true; + return false; +} + + + + + +////////////////////////////////////////////////////////////////////////// +// Set orientations +void cEntity::SetRot( const Vector3f & a_Rot ) +{ + m_Rot = a_Rot; + m_bDirtyOrientation = true; +} + + + + + +void cEntity::SetRotation( float a_Rotation ) +{ + m_Rot.x = a_Rotation; + m_bDirtyOrientation = true; +} + + + + + +void cEntity::SetPitch( float a_Pitch ) +{ + m_Rot.y = a_Pitch; + m_bDirtyOrientation = true; +} + + + + + +void cEntity::SetRoll( float a_Roll ) +{ + m_Rot.z = a_Roll; + m_bDirtyOrientation = true; +} + + + + + +////////////////////////////////////////////////////////////////////////// +// Get look vector (this is NOT a rotation!) +Vector3f cEntity::GetLookVector() +{ + Matrix4f m; + m.Init( Vector3f(), 0, m_Rot.x, -m_Rot.y ); + Vector3f Look = m.Transform( Vector3f(0, 0, 1) ); + LOG("Look: %0.1f %0.1f %0.1f", Look.x, Look.y, Look.z ); + return Look; +} + + + + + +////////////////////////////////////////////////////////////////////////// +// Set position +void cEntity::SetPosition( const Vector3d & a_Pos ) +{ + m_Pos = a_Pos; + MoveToCorrectChunk(); + m_bDirtyPosition = true; +} + + + + + +void cEntity::SetPosition( const double & a_PosX, const double & a_PosY, const double & a_PosZ ) +{ + m_Pos.Set( a_PosX, a_PosY, a_PosZ ); + MoveToCorrectChunk(); + m_bDirtyPosition = true; +} + + + + + +void cEntity::SetPosX( const double & a_PosX ) +{ + m_Pos.x = a_PosX; + MoveToCorrectChunk(); + m_bDirtyPosition = true; +} + + + + + +void cEntity::SetPosY( const double & a_PosY ) +{ + m_Pos.y = a_PosY; + MoveToCorrectChunk(); + m_bDirtyPosition = true; +} + + + + + +void cEntity::SetPosZ( const double & a_PosZ ) +{ + m_Pos.z = a_PosZ; + MoveToCorrectChunk(); + m_bDirtyPosition = true; +} + + + + + +////////////////////////////////////////////////////////////////////////// +// Reference stuffs +void cEntity::AddReference( cEntity*& a_EntityPtr ) +{ + m_References->AddReference( a_EntityPtr ); + a_EntityPtr->ReferencedBy( a_EntityPtr ); +} + + + + + +void cEntity::ReferencedBy( cEntity*& a_EntityPtr ) +{ + m_Referencers->AddReference( a_EntityPtr ); +} + + + + + +void cEntity::Dereference( cEntity*& a_EntityPtr ) +{ + m_Referencers->Dereference( a_EntityPtr ); +} + + + + diff --git a/source/cEntity.h b/source/cEntity.h index 34c878abd..d5614eb84 100644 --- a/source/cEntity.h +++ b/source/cEntity.h @@ -1,148 +1,148 @@ -
-#pragma once
-
-
-
-
-#include "Vector3d.h"
-#include "Vector3f.h"
-
-
-
-
-
-#define CLASS_PROT_ISA() virtual bool IsA( const char* a_EntityType );
-#define CLASS_PROT_GETCLASS() virtual const char* GetClass();
-
-/* Can't use this (yet) because of tolua */
-#define CLASS_PROTOTYPE() \
- CLASS_PROT_ISA(); \
- CLASS_PROT_GETCLASS();
-
-#define CLASS_DEF_ISA( classname, superclass ) \
- bool classname::IsA( const char* a_EntityType ) \
- { \
- if( strcmp( a_EntityType, #classname ) == 0 ) return true; \
- return superclass::IsA( a_EntityType ); \
- }
-
-#define CLASS_DEF_GETCLASS( classname ) \
- const char* classname::GetClass() \
- { \
- return #classname; \
- }
-
-#define CLASS_DEFINITION( classname, superclass ) \
- CLASS_DEF_ISA( classname, superclass ) \
- CLASS_DEF_GETCLASS( classname )
-
-
-
-
-
-class cWorld;
-class cReferenceManager;
-class cClientHandle;
-class cPacket;
-
-
-
-
-
-class cEntity //tolua_export
-{ //tolua_export
-public: //tolua_export
- cEntity(const double & a_X, const double & a_Y, const double & a_Z); //tolua_export
- virtual ~cEntity(); //tolua_export
-
- virtual void Initialize( cWorld* a_World ); //tolua_export
-
- enum eEntityType //tolua_export
- { //tolua_export
- eEntityType_Entity, //tolua_export
- eEntityType_Player, //tolua_export
- eEntityType_Pickup //tolua_export
- }; //tolua_export
-
- virtual unsigned int GetEntityType() { return m_EntityType; } //tolua_export
- virtual bool IsA( const char* a_EntityType ); //tolua_export
- virtual const char* GetClass(); //tolua_export
-
- cWorld * GetWorld(void) const { return m_World; } //tolua_export
-
- const Vector3d & GetPosition(void) const {return m_Pos; } //tolua_export
- const double & GetPosX (void) const {return m_Pos.x; } //tolua_export
- const double & GetPosY (void) const {return m_Pos.y; } //tolua_export
- const double & GetPosZ (void) const {return m_Pos.z; } //tolua_export
- const Vector3f & GetRot (void) const {return m_Rot; } //tolua_export
- float GetRotation(void) const {return m_Rot.x; } //tolua_export
- float GetPitch (void) const {return m_Rot.y; } //tolua_export
- float GetRoll (void) const {return m_Rot.z; } //tolua_export
- Vector3f GetLookVector(); //tolua_export
-
- int GetChunkX(void) const {return m_ChunkX; } //tolua_export
- int GetChunkY(void) const {return m_ChunkY; } //tolua_export
- int GetChunkZ(void) const {return m_ChunkZ; } //tolua_export
-
- void SetPosX( const double & a_PosX ); //tolua_export
- void SetPosY( const double & a_PosY ); //tolua_export
- void SetPosZ( const double & a_PosZ ); //tolua_export
- void SetPosition( const double & a_PosX, const double & a_PosY, const double & a_PosZ );//tolua_export
- void SetPosition( const Vector3d & a_Pos ); //tolua_export
- void SetRot( const Vector3f & a_Rot ); //tolua_export
- void SetRotation( float a_Rotation ); //tolua_export
- void SetPitch( float a_Pitch ); //tolua_export
- void SetRoll( float a_Roll ); //tolua_export
-
- inline int GetUniqueID(void) const { return m_UniqueID; } //tolua_export
- inline bool IsDestroyed(void) const { return m_bDestroyed; } //tolua_export
-
- void Destroy(); //tolua_export
- void RemoveFromChunk(void); // for internal use in cChunk
-
- virtual void Tick(float a_Dt) = 0; //tolua_export
-
- virtual cPacket * GetSpawnPacket(void) const {ASSERT(!"GetSpawnedPacket unimplemented!"); return NULL; }; // _X: Needs to be implemented due to Lua bindings
- void SpawnOn (cClientHandle * a_Client); // tolua_export
-
- void WrapRotation();
-
-protected:
- virtual void Destroyed() {} // Called after the entity has been destroyed
-
- void SetWorld( cWorld* a_World ) { m_World = a_World; }
- void MoveToCorrectChunk(bool a_bIgnoreOldChunk = false);
-
- friend class cReferenceManager;
- void AddReference( cEntity*& a_EntityPtr );
- void ReferencedBy( cEntity*& a_EntityPtr );
- void Dereference( cEntity*& a_EntityPtr );
-
- static cCriticalSection m_CSCount;
- static int m_EntityCount;
-
- int m_UniqueID;
-
- cReferenceManager* m_Referencers;
- cReferenceManager* m_References;
-
- int m_ChunkX, m_ChunkY, m_ChunkZ;
- Vector3d m_Pos;
- bool m_bDirtyPosition;
-
- Vector3f m_Rot;
- bool m_bDirtyOrientation;
-
- bool m_bDestroyed;
- bool m_bRemovedFromChunk;
-
- eEntityType m_EntityType;
-
- cWorld* m_World;
-}; //tolua_export
-
-typedef std::list<cEntity *> cEntityList;
-
-
-
-
+ +#pragma once + + + + +#include "Vector3d.h" +#include "Vector3f.h" + + + + + +#define CLASS_PROT_ISA() virtual bool IsA( const char* a_EntityType ); +#define CLASS_PROT_GETCLASS() virtual const char* GetClass(); + +/* Can't use this (yet) because of tolua */ +#define CLASS_PROTOTYPE() \ + CLASS_PROT_ISA(); \ + CLASS_PROT_GETCLASS(); + +#define CLASS_DEF_ISA( classname, superclass ) \ + bool classname::IsA( const char* a_EntityType ) \ + { \ + if( strcmp( a_EntityType, #classname ) == 0 ) return true; \ + return superclass::IsA( a_EntityType ); \ + } + +#define CLASS_DEF_GETCLASS( classname ) \ + const char* classname::GetClass() \ + { \ + return #classname; \ + } + +#define CLASS_DEFINITION( classname, superclass ) \ + CLASS_DEF_ISA( classname, superclass ) \ + CLASS_DEF_GETCLASS( classname ) + + + + + +class cWorld; +class cReferenceManager; +class cClientHandle; +class cPacket; + + + + + +class cEntity //tolua_export +{ //tolua_export +public: //tolua_export + cEntity(const double & a_X, const double & a_Y, const double & a_Z); //tolua_export + virtual ~cEntity(); //tolua_export + + virtual void Initialize( cWorld* a_World ); //tolua_export + + enum eEntityType //tolua_export + { //tolua_export + eEntityType_Entity, //tolua_export + eEntityType_Player, //tolua_export + eEntityType_Pickup //tolua_export + }; //tolua_export + + virtual unsigned int GetEntityType() { return m_EntityType; } //tolua_export + virtual bool IsA( const char* a_EntityType ); //tolua_export + virtual const char* GetClass(); //tolua_export + + cWorld * GetWorld(void) const { return m_World; } //tolua_export + + const Vector3d & GetPosition(void) const {return m_Pos; } //tolua_export + const double & GetPosX (void) const {return m_Pos.x; } //tolua_export + const double & GetPosY (void) const {return m_Pos.y; } //tolua_export + const double & GetPosZ (void) const {return m_Pos.z; } //tolua_export + const Vector3f & GetRot (void) const {return m_Rot; } //tolua_export + float GetRotation(void) const {return m_Rot.x; } //tolua_export + float GetPitch (void) const {return m_Rot.y; } //tolua_export + float GetRoll (void) const {return m_Rot.z; } //tolua_export + Vector3f GetLookVector(); //tolua_export + + int GetChunkX(void) const {return m_ChunkX; } //tolua_export + int GetChunkY(void) const {return m_ChunkY; } //tolua_export + int GetChunkZ(void) const {return m_ChunkZ; } //tolua_export + + void SetPosX( const double & a_PosX ); //tolua_export + void SetPosY( const double & a_PosY ); //tolua_export + void SetPosZ( const double & a_PosZ ); //tolua_export + void SetPosition( const double & a_PosX, const double & a_PosY, const double & a_PosZ );//tolua_export + void SetPosition( const Vector3d & a_Pos ); //tolua_export + void SetRot( const Vector3f & a_Rot ); //tolua_export + void SetRotation( float a_Rotation ); //tolua_export + void SetPitch( float a_Pitch ); //tolua_export + void SetRoll( float a_Roll ); //tolua_export + + inline int GetUniqueID(void) const { return m_UniqueID; } //tolua_export + inline bool IsDestroyed(void) const { return m_bDestroyed; } //tolua_export + + void Destroy(); //tolua_export + void RemoveFromChunk(void); // for internal use in cChunk + + virtual void Tick(float a_Dt) = 0; //tolua_export + + virtual cPacket * GetSpawnPacket(void) const {ASSERT(!"GetSpawnedPacket unimplemented!"); return NULL; }; // _X: Needs to be implemented due to Lua bindings + void SpawnOn (cClientHandle * a_Client); // tolua_export + + void WrapRotation(); + +protected: + virtual void Destroyed() {} // Called after the entity has been destroyed + + void SetWorld( cWorld* a_World ) { m_World = a_World; } + void MoveToCorrectChunk(bool a_bIgnoreOldChunk = false); + + friend class cReferenceManager; + void AddReference( cEntity*& a_EntityPtr ); + void ReferencedBy( cEntity*& a_EntityPtr ); + void Dereference( cEntity*& a_EntityPtr ); + + static cCriticalSection m_CSCount; + static int m_EntityCount; + + int m_UniqueID; + + cReferenceManager* m_Referencers; + cReferenceManager* m_References; + + int m_ChunkX, m_ChunkY, m_ChunkZ; + Vector3d m_Pos; + bool m_bDirtyPosition; + + Vector3f m_Rot; + bool m_bDirtyOrientation; + + bool m_bDestroyed; + bool m_bRemovedFromChunk; + + eEntityType m_EntityType; + + cWorld* m_World; +}; //tolua_export + +typedef std::list<cEntity *> cEntityList; + + + + diff --git a/source/cEvent.cpp b/source/cEvent.cpp index cc476400f..a94fa83bc 100644 --- a/source/cEvent.cpp +++ b/source/cEvent.cpp @@ -1,118 +1,118 @@ -
-// cEvent.cpp
-
-// Implements the cEvent object representing an OS-specific synchronization primitive that can be waited-for
-// Implemented as an Event on Win and as a 1-semaphore on *nix
-
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cEvent.h"
-
-
-
-
-
-cEvent::cEvent(void)
-{
-#ifdef _WIN32
- m_Event = CreateEvent( 0, FALSE, FALSE, 0 );
- if (m_Event == NULL)
- {
- LOGERROR("cEvent: cannot create event, GLE = %d. Aborting server.", GetLastError());
- abort();
- }
-#else // *nix
- m_bIsNamed = false;
- m_Event = new sem_t;
- if (sem_init(m_Event, 0, 0))
- {
- // This path is used by MacOS, because it doesn't support unnamed semaphores.
- delete m_Event;
- m_bIsNamed = true;
-
- AString EventName;
- Printf(EventName, "cEvent%p", this);
- m_Event = sem_open(EventName.c_str(), O_CREAT, 777, 0 );
- if (m_Event == SEM_FAILED)
- {
- LOGERROR("cEvent: Cannot create event, errno = %i. Aborting server.", errno);
- abort();
- }
- // Unlink the semaphore immediately - it will continue to function but will not pollute the namespace
- // We don't store the name, so can't call this in the destructor
- if (sem_unlink(EventName.c_str()) != 0)
- {
- LOGWARN("ERROR: Could not unlink cEvent. (%i)", errno);
- }
- }
-#endif // *nix
-}
-
-
-
-
-
-cEvent::~cEvent()
-{
-#ifdef _WIN32
- CloseHandle(m_Event);
-#else
- if (m_bIsNamed)
- {
- if (sem_close(m_Event) != 0)
- {
- LOGERROR("ERROR: Could not close cEvent. (%i)", errno);
- }
- }
- else
- {
- sem_destroy(m_Event);
- delete m_Event;
- }
-#endif
-}
-
-
-
-
-
-void cEvent::Wait(void)
-{
-#ifdef _WIN32
- DWORD res = WaitForSingleObject(m_Event, INFINITE);
- if (res != WAIT_OBJECT_0)
- {
- LOGWARN("cEvent: waiting for the event failed: %d, GLE = %d. Continuing, but server may be unstable.", res, GetLastError());
- }
-#else
- int res = sem_wait(m_Event);
- if (res != 0 )
- {
- LOGWARN("cEvent: waiting for the event failed: %i, errno = %i. Continuing, but server may be unstable.", res, errno);
- }
-#endif
-}
-
-
-
-
-
-void cEvent::Set(void)
-{
-#ifdef _WIN32
- if (!SetEvent(m_Event))
- {
- LOGWARN("cEvent: Could not set cEvent: GLE = %d", GetLastError());
- }
-#else
- int res = sem_post(m_Event);
- if (res != 0)
- {
- LOGWARN("cEvent: Could not set cEvent: %i, errno = %d", res, errno);
- }
-#endif
-}
-
-
-
-
+ +// cEvent.cpp + +// Implements the cEvent object representing an OS-specific synchronization primitive that can be waited-for +// Implemented as an Event on Win and as a 1-semaphore on *nix + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cEvent.h" + + + + + +cEvent::cEvent(void) +{ +#ifdef _WIN32 + m_Event = CreateEvent( 0, FALSE, FALSE, 0 ); + if (m_Event == NULL) + { + LOGERROR("cEvent: cannot create event, GLE = %d. Aborting server.", GetLastError()); + abort(); + } +#else // *nix + m_bIsNamed = false; + m_Event = new sem_t; + if (sem_init(m_Event, 0, 0)) + { + // This path is used by MacOS, because it doesn't support unnamed semaphores. + delete m_Event; + m_bIsNamed = true; + + AString EventName; + Printf(EventName, "cEvent%p", this); + m_Event = sem_open(EventName.c_str(), O_CREAT, 777, 0 ); + if (m_Event == SEM_FAILED) + { + LOGERROR("cEvent: Cannot create event, errno = %i. Aborting server.", errno); + abort(); + } + // Unlink the semaphore immediately - it will continue to function but will not pollute the namespace + // We don't store the name, so can't call this in the destructor + if (sem_unlink(EventName.c_str()) != 0) + { + LOGWARN("ERROR: Could not unlink cEvent. (%i)", errno); + } + } +#endif // *nix +} + + + + + +cEvent::~cEvent() +{ +#ifdef _WIN32 + CloseHandle(m_Event); +#else + if (m_bIsNamed) + { + if (sem_close(m_Event) != 0) + { + LOGERROR("ERROR: Could not close cEvent. (%i)", errno); + } + } + else + { + sem_destroy(m_Event); + delete m_Event; + } +#endif +} + + + + + +void cEvent::Wait(void) +{ +#ifdef _WIN32 + DWORD res = WaitForSingleObject(m_Event, INFINITE); + if (res != WAIT_OBJECT_0) + { + LOGWARN("cEvent: waiting for the event failed: %d, GLE = %d. Continuing, but server may be unstable.", res, GetLastError()); + } +#else + int res = sem_wait(m_Event); + if (res != 0 ) + { + LOGWARN("cEvent: waiting for the event failed: %i, errno = %i. Continuing, but server may be unstable.", res, errno); + } +#endif +} + + + + + +void cEvent::Set(void) +{ +#ifdef _WIN32 + if (!SetEvent(m_Event)) + { + LOGWARN("cEvent: Could not set cEvent: GLE = %d", GetLastError()); + } +#else + int res = sem_post(m_Event); + if (res != 0) + { + LOGWARN("cEvent: Could not set cEvent: %i, errno = %d", res, errno); + } +#endif +} + + + + diff --git a/source/cEvent.h b/source/cEvent.h index 11b9d7098..bc1505a11 100644 --- a/source/cEvent.h +++ b/source/cEvent.h @@ -1,47 +1,47 @@ -
-// cEvent.h
-
-// Interfaces to the cEvent object representing an OS-specific synchronization primitive that can be waited-for
-// Implemented as an Event on Win and as a 1-semaphore on *nix
-
-
-
-
-
-#pragma once
-#ifndef CEVENT_H_INCLUDED
-#define CEVENT_H_INCLUDED
-
-
-
-
-
-class cEvent
-{
-public:
- cEvent(void);
- ~cEvent();
-
- void Wait(void);
- void Set (void);
-
-private:
-
- #ifdef _WIN32
- HANDLE m_Event;
- #else
- sem_t * m_Event;
- bool m_bIsNamed;
- #endif
-} ;
-
-
-
-
-
-
-#endif // CEVENT_H_INCLUDED
-
-
-
-
+ +// cEvent.h + +// Interfaces to the cEvent object representing an OS-specific synchronization primitive that can be waited-for +// Implemented as an Event on Win and as a 1-semaphore on *nix + + + + + +#pragma once +#ifndef CEVENT_H_INCLUDED +#define CEVENT_H_INCLUDED + + + + + +class cEvent +{ +public: + cEvent(void); + ~cEvent(); + + void Wait(void); + void Set (void); + +private: + + #ifdef _WIN32 + HANDLE m_Event; + #else + sem_t * m_Event; + bool m_bIsNamed; + #endif +} ; + + + + + + +#endif // CEVENT_H_INCLUDED + + + + diff --git a/source/cFile.cpp b/source/cFile.cpp index cd61800e2..32de28fe0 100644 --- a/source/cFile.cpp +++ b/source/cFile.cpp @@ -1,271 +1,271 @@ -
-// cFile.cpp
-
-// Implements the cFile class providing an OS-independent abstraction of a file.
-
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cFile.h"
-
-
-
-
-
-
-/// Simple constructor - creates an unopened file object, use Open() to open / create a real file
-cFile::cFile(void) :
- #ifdef USE_STDIO_FILE
- m_File(NULL)
- #else
- m_File(INVALID_HANDLE_VALUE)
- #endif // USE_STDIO_FILE
-{
- // Nothing needed yet
-}
-
-
-
-
-
-/// Constructs and opens / creates the file specified, use IsOpen() to check for success
-cFile::cFile(const AString & iFileName, EMode iMode) :
- #ifdef USE_STDIO_FILE
- m_File(NULL)
- #else
- m_File(INVALID_HANDLE_VALUE)
- #endif // USE_STDIO_FILE
-{
- Open(iFileName, iMode);
-}
-
-
-
-
-
-/// Auto-closes the file, if open
-cFile::~cFile()
-{
- if (IsOpen())
- {
- Close();
- }
-}
-
-
-
-
-
-bool cFile::Open(const AString & iFileName, EMode iMode)
-{
- ASSERT(!IsOpen()); // You should close the file before opening another one
-
- if (IsOpen())
- {
- Close();
- }
-
- const char * Mode = NULL;
- switch (iMode)
- {
- case fmRead: Mode = "rb"; break;
- case fmWrite: Mode = "wb"; break;
- case fmReadWrite: Mode = "rb+"; break;
- default:
- {
- ASSERT(!"Unhandled file mode");
- return false;
- }
- }
- m_File = fopen(iFileName.c_str(), Mode);
- if ((m_File == NULL) && (iMode == fmReadWrite))
- {
- // Fix for MS not following C spec, opening "a" mode files for writing at the end only
- // The file open operation has been tried with "read update", fails if file not found
- // So now we know either the file doesn't exist or we don't have rights, no need to worry about file contents.
- // Simply re-open for read-writing, erasing existing contents:
- m_File = fopen(iFileName.c_str(), "wb+");
- }
- return (m_File != NULL);
-}
-
-
-
-
-
-void cFile::Close(void)
-{
- ASSERT(IsOpen()); // You should not close file objects that don't have an open file.
-
- if (!IsOpen())
- {
- return;
- }
-
- fclose(m_File);
- m_File = NULL;
-}
-
-
-
-
-
-bool cFile::IsOpen(void) const
-{
- return (m_File != NULL);
-}
-
-
-
-
-
-bool cFile::IsEOF(void) const
-{
- ASSERT(IsOpen());
-
- if (!IsOpen())
- {
- // Unopened files behave as at EOF
- return true;
- }
-
- return (feof(m_File) != 0);
-}
-
-
-
-
-
-/// Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open
-int cFile::Read (void * iBuffer, int iNumBytes)
-{
- ASSERT(IsOpen());
-
- if (!IsOpen())
- {
- return -1;
- }
-
- return fread(iBuffer, 1, iNumBytes, m_File); // fread() returns the portion of Count parameter actually read, so we need to send iNumBytes as Count
-}
-
-
-
-
-
-/// Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open
-int cFile::Write(const void * iBuffer, int iNumBytes)
-{
- ASSERT(IsOpen());
-
- if (!IsOpen())
- {
- return -1;
- }
-
- int res = fwrite(iBuffer, 1, iNumBytes, m_File); // fwrite() returns the portion of Count parameter actually written, so we need to send iNumBytes as Count
- return res;
-}
-
-
-
-
-
-/// Seeks to iPosition bytes from file start, returns old position or -1 for failure
-int cFile::Seek (int iPosition)
-{
- ASSERT(IsOpen());
-
- if (!IsOpen())
- {
- return -1;
- }
-
- if (fseek(m_File, iPosition, SEEK_SET) != 0)
- {
- return -1;
- }
- return ftell(m_File);
-}
-
-
-
-
-
-
-/// Returns the current position (bytes from file start)
-int cFile::Tell (void) const
-{
- ASSERT(IsOpen());
-
- if (!IsOpen())
- {
- return -1;
- }
-
- return ftell(m_File);
-}
-
-
-
-
-
-/// Returns the size of file, in bytes, or -1 for failure; asserts if not open
-int cFile::GetSize(void) const
-{
- ASSERT(IsOpen());
-
- if (!IsOpen())
- {
- return -1;
- }
-
- int CurPos = ftell(m_File);
- if (CurPos < 0)
- {
- return -1;
- }
- if (fseek(m_File, 0, SEEK_END) != 0)
- {
- return -1;
- }
- int res = ftell(m_File);
- if (fseek(m_File, CurPos, SEEK_SET) != 0)
- {
- return -1;
- }
- return res;
-}
-
-
-
-
-
-int cFile::ReadRestOfFile(AString & a_Contents)
-{
- ASSERT(IsOpen());
-
- if (!IsOpen())
- {
- return -1;
- }
-
- int DataSize = GetSize() - Tell();
-
- // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly
- a_Contents.assign(DataSize, '\0');
- return Read((void *)a_Contents.data(), DataSize);
-}
-
-
-
-
-
-bool cFile::Exists(const AString & a_FileName)
-{
- cFile test(a_FileName, fmRead);
- return test.IsOpen();
-}
-
-
-
-
+ +// cFile.cpp + +// Implements the cFile class providing an OS-independent abstraction of a file. + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cFile.h" + + + + + + +/// Simple constructor - creates an unopened file object, use Open() to open / create a real file +cFile::cFile(void) : + #ifdef USE_STDIO_FILE + m_File(NULL) + #else + m_File(INVALID_HANDLE_VALUE) + #endif // USE_STDIO_FILE +{ + // Nothing needed yet +} + + + + + +/// Constructs and opens / creates the file specified, use IsOpen() to check for success +cFile::cFile(const AString & iFileName, EMode iMode) : + #ifdef USE_STDIO_FILE + m_File(NULL) + #else + m_File(INVALID_HANDLE_VALUE) + #endif // USE_STDIO_FILE +{ + Open(iFileName, iMode); +} + + + + + +/// Auto-closes the file, if open +cFile::~cFile() +{ + if (IsOpen()) + { + Close(); + } +} + + + + + +bool cFile::Open(const AString & iFileName, EMode iMode) +{ + ASSERT(!IsOpen()); // You should close the file before opening another one + + if (IsOpen()) + { + Close(); + } + + const char * Mode = NULL; + switch (iMode) + { + case fmRead: Mode = "rb"; break; + case fmWrite: Mode = "wb"; break; + case fmReadWrite: Mode = "rb+"; break; + default: + { + ASSERT(!"Unhandled file mode"); + return false; + } + } + m_File = fopen(iFileName.c_str(), Mode); + if ((m_File == NULL) && (iMode == fmReadWrite)) + { + // Fix for MS not following C spec, opening "a" mode files for writing at the end only + // The file open operation has been tried with "read update", fails if file not found + // So now we know either the file doesn't exist or we don't have rights, no need to worry about file contents. + // Simply re-open for read-writing, erasing existing contents: + m_File = fopen(iFileName.c_str(), "wb+"); + } + return (m_File != NULL); +} + + + + + +void cFile::Close(void) +{ + ASSERT(IsOpen()); // You should not close file objects that don't have an open file. + + if (!IsOpen()) + { + return; + } + + fclose(m_File); + m_File = NULL; +} + + + + + +bool cFile::IsOpen(void) const +{ + return (m_File != NULL); +} + + + + + +bool cFile::IsEOF(void) const +{ + ASSERT(IsOpen()); + + if (!IsOpen()) + { + // Unopened files behave as at EOF + return true; + } + + return (feof(m_File) != 0); +} + + + + + +/// Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open +int cFile::Read (void * iBuffer, int iNumBytes) +{ + ASSERT(IsOpen()); + + if (!IsOpen()) + { + return -1; + } + + return fread(iBuffer, 1, iNumBytes, m_File); // fread() returns the portion of Count parameter actually read, so we need to send iNumBytes as Count +} + + + + + +/// Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open +int cFile::Write(const void * iBuffer, int iNumBytes) +{ + ASSERT(IsOpen()); + + if (!IsOpen()) + { + return -1; + } + + int res = fwrite(iBuffer, 1, iNumBytes, m_File); // fwrite() returns the portion of Count parameter actually written, so we need to send iNumBytes as Count + return res; +} + + + + + +/// Seeks to iPosition bytes from file start, returns old position or -1 for failure +int cFile::Seek (int iPosition) +{ + ASSERT(IsOpen()); + + if (!IsOpen()) + { + return -1; + } + + if (fseek(m_File, iPosition, SEEK_SET) != 0) + { + return -1; + } + return ftell(m_File); +} + + + + + + +/// Returns the current position (bytes from file start) +int cFile::Tell (void) const +{ + ASSERT(IsOpen()); + + if (!IsOpen()) + { + return -1; + } + + return ftell(m_File); +} + + + + + +/// Returns the size of file, in bytes, or -1 for failure; asserts if not open +int cFile::GetSize(void) const +{ + ASSERT(IsOpen()); + + if (!IsOpen()) + { + return -1; + } + + int CurPos = ftell(m_File); + if (CurPos < 0) + { + return -1; + } + if (fseek(m_File, 0, SEEK_END) != 0) + { + return -1; + } + int res = ftell(m_File); + if (fseek(m_File, CurPos, SEEK_SET) != 0) + { + return -1; + } + return res; +} + + + + + +int cFile::ReadRestOfFile(AString & a_Contents) +{ + ASSERT(IsOpen()); + + if (!IsOpen()) + { + return -1; + } + + int DataSize = GetSize() - Tell(); + + // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly + a_Contents.assign(DataSize, '\0'); + return Read((void *)a_Contents.data(), DataSize); +} + + + + + +bool cFile::Exists(const AString & a_FileName) +{ + cFile test(a_FileName, fmRead); + return test.IsOpen(); +} + + + + diff --git a/source/cFile.h b/source/cFile.h index 567c98219..373d69958 100644 --- a/source/cFile.h +++ b/source/cFile.h @@ -1,108 +1,108 @@ -
-// cFile.h
-
-// Interfaces to the cFile class providing an OS-independent abstraction of a file.
-
-/*
-The object is optimized towards binary reads.
-The object has no multithreading locks, don't use from multiple threads!
-Usage:
-1, Construct a cFile instance (no-param constructor)
-2, Open a file using Open(), check return value for success
-3, Read / write
-4, Destroy the instance
-
--- OR --
-
-1, Construct a cFile instance opening the file (filename-param constructor)
-2, Check if the file was opened using IsOpen()
-3, Read / write
-4, Destroy the instance
-*/
-
-
-
-
-
-#pragma once
-#ifndef CFILE_H_INCLUDED
-#define CFILE_H_INCLUDED
-
-
-
-
-
-#ifndef _WIN32
- #define USE_STDIO_FILE
-#endif // _WIN32
-
-// DEBUG:
-#define USE_STDIO_FILE
-
-
-
-
-
-class cFile
-{
-public:
- /// The mode in which to open the file
- enum EMode
- {
- fmRead, // Read-only. If the file doesn't exist, object will not be valid
- fmWrite, // Write-only. If the file already exists, it will be overwritten
- fmReadWrite, // Read/write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning
- } ;
-
- /// Simple constructor - creates an unopened file object, use Open() to open / create a real file
- cFile(void);
-
- /// Constructs and opens / creates the file specified, use IsOpen() to check for success
- cFile(const AString & iFileName, EMode iMode);
-
- /// Auto-closes the file, if open
- ~cFile();
-
- bool Open(const AString & iFileName, EMode iMode);
- void Close(void);
- bool IsOpen(void) const;
- bool IsEOF(void) const;
-
- /// Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open
- int Read (void * iBuffer, int iNumBytes);
-
- /// Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open
- int Write(const void * iBuffer, int iNumBytes);
-
- /// Seeks to iPosition bytes from file start, returns old position or -1 for failure; asserts if not open
- int Seek (int iPosition);
-
- /// Returns the current position (bytes from file start) or -1 for failure; asserts if not open
- int Tell (void) const;
-
- /// Returns the size of file, in bytes, or -1 for failure; asserts if not open
- int GetSize(void) const;
-
- /// Reads the file from current position till EOF into an AString; returns the number of bytes read or -1 for error
- int ReadRestOfFile(AString & a_Contents);
-
- /// Returns true if the file specified exists
- static bool Exists(const AString & a_FileName);
-
-private:
- #ifdef USE_STDIO_FILE
- FILE * m_File;
- #else
- HANDLE m_File;
- #endif
-} ;
-
-
-
-
-
-#endif // CFILE_H_INCLUDED
-
-
-
-
+ +// cFile.h + +// Interfaces to the cFile class providing an OS-independent abstraction of a file. + +/* +The object is optimized towards binary reads. +The object has no multithreading locks, don't use from multiple threads! +Usage: +1, Construct a cFile instance (no-param constructor) +2, Open a file using Open(), check return value for success +3, Read / write +4, Destroy the instance + +-- OR -- + +1, Construct a cFile instance opening the file (filename-param constructor) +2, Check if the file was opened using IsOpen() +3, Read / write +4, Destroy the instance +*/ + + + + + +#pragma once +#ifndef CFILE_H_INCLUDED +#define CFILE_H_INCLUDED + + + + + +#ifndef _WIN32 + #define USE_STDIO_FILE +#endif // _WIN32 + +// DEBUG: +#define USE_STDIO_FILE + + + + + +class cFile +{ +public: + /// The mode in which to open the file + enum EMode + { + fmRead, // Read-only. If the file doesn't exist, object will not be valid + fmWrite, // Write-only. If the file already exists, it will be overwritten + fmReadWrite, // Read/write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning + } ; + + /// Simple constructor - creates an unopened file object, use Open() to open / create a real file + cFile(void); + + /// Constructs and opens / creates the file specified, use IsOpen() to check for success + cFile(const AString & iFileName, EMode iMode); + + /// Auto-closes the file, if open + ~cFile(); + + bool Open(const AString & iFileName, EMode iMode); + void Close(void); + bool IsOpen(void) const; + bool IsEOF(void) const; + + /// Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open + int Read (void * iBuffer, int iNumBytes); + + /// Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open + int Write(const void * iBuffer, int iNumBytes); + + /// Seeks to iPosition bytes from file start, returns old position or -1 for failure; asserts if not open + int Seek (int iPosition); + + /// Returns the current position (bytes from file start) or -1 for failure; asserts if not open + int Tell (void) const; + + /// Returns the size of file, in bytes, or -1 for failure; asserts if not open + int GetSize(void) const; + + /// Reads the file from current position till EOF into an AString; returns the number of bytes read or -1 for error + int ReadRestOfFile(AString & a_Contents); + + /// Returns true if the file specified exists + static bool Exists(const AString & a_FileName); + +private: + #ifdef USE_STDIO_FILE + FILE * m_File; + #else + HANDLE m_File; + #endif +} ; + + + + + +#endif // CFILE_H_INCLUDED + + + + diff --git a/source/cFileFormatUpdater.cpp b/source/cFileFormatUpdater.cpp index b58239eb2..3991ede34 100644 --- a/source/cFileFormatUpdater.cpp +++ b/source/cFileFormatUpdater.cpp @@ -1,143 +1,143 @@ -
-#include "Globals.h"
-
-#include "cFileFormatUpdater.h"
-#include "Vector3d.h"
-#include "Vector3f.h"
-
-#include "cItem.h"
-#include <json/json.h>
-
-
-
-
-
-void cFileFormatUpdater::UpdateFileFormat()
-{
- UpdatePlayersOfWorld("world");
-}
-
-
-
-
-
-// Convert player .bin files to JSON
-void cFileFormatUpdater::UpdatePlayersOfWorld( const char* a_WorldName )
-{
- AString PlayerDir = AString( a_WorldName ) + "/player/";
-
- AStringList AllFiles = GetDirectoryContents( PlayerDir.c_str() );
- for (AStringList::iterator itr = AllFiles.begin(); itr != AllFiles.end(); ++itr )
- {
- AString & FileName = *itr;
- if (FileName.rfind(".bin") != AString::npos) // Get only the files ending in .bin
- {
- PlayerBINtoJSON( (PlayerDir + FileName).c_str() );
- }
- }
-}
-
-
-
-
-
-#define READ(File, Var) \
- if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \
- { \
- LOGERROR("ERROR READING \"%s\" FROM FILE \"%s\"", #Var, a_FileName); \
- return; \
- }
-
-// Converts player binary files to human readable JSON
-void cFileFormatUpdater::PlayerBINtoJSON( const char* a_FileName )
-{
- Vector3d PlayerPos;
- Vector3f PlayerRot;
- short PlayerHealth = 0;
-
- const unsigned int NumInventorySlots = 45; // At this time the player inventory has/had 45 slots
- cItem IventoryItems[ NumInventorySlots ];
-
- cFile f;
- if (!f.Open(a_FileName, cFile::fmRead))
- {
- return;
- }
-
- // First read player position, rotation and health
- READ(f, PlayerPos.x);
- READ(f, PlayerPos.y);
- READ(f, PlayerPos.z);
- READ(f, PlayerRot.x);
- READ(f, PlayerRot.y);
- READ(f, PlayerRot.z);
- READ(f, PlayerHealth);
-
-
- for(unsigned int i = 0; i < NumInventorySlots; i++)
- {
- cItem & Item = IventoryItems[i];
- READ(f, Item.m_ItemID);
- READ(f, Item.m_ItemCount);
- READ(f, Item.m_ItemHealth);
- }
- f.Close();
-
- // Loaded all the data, now create the JSON data
- Json::Value JSON_PlayerPosition;
- JSON_PlayerPosition.append( Json::Value( PlayerPos.x ) );
- JSON_PlayerPosition.append( Json::Value( PlayerPos.y ) );
- JSON_PlayerPosition.append( Json::Value( PlayerPos.z ) );
-
- Json::Value JSON_PlayerRotation;
- JSON_PlayerRotation.append( Json::Value( PlayerRot.x ) );
- JSON_PlayerRotation.append( Json::Value( PlayerRot.y ) );
- JSON_PlayerRotation.append( Json::Value( PlayerRot.z ) );
-
- Json::Value JSON_Inventory;
- for(unsigned int i = 0; i < NumInventorySlots; i++)
- {
- Json::Value JSON_Item;
- IventoryItems[i].GetJson( JSON_Item );
- JSON_Inventory.append( JSON_Item );
- }
-
- Json::Value root;
- root["position"] = JSON_PlayerPosition;
- root["rotation"] = JSON_PlayerRotation;
- root["inventory"] = JSON_Inventory;
- root["health"] = PlayerHealth;
-
- Json::StyledWriter writer;
- std::string JsonData = writer.write( root );
-
- // Get correct filename
- std::string FileName = a_FileName;
- std::string FileNameWithoutExt = FileName.substr(0, FileName.find_last_of(".") );
- std::string FileNameJson = FileNameWithoutExt + ".json";
-
- // Write to file
- if (!f.Open(FileNameJson.c_str(), cFile::fmWrite))
- {
- return;
- }
- if (f.Write(JsonData.c_str(), JsonData.size()) != JsonData.size())
- {
- LOGERROR("ERROR WRITING PLAYER JSON TO FILE \"%s\"", FileNameJson.c_str());
- return;
- }
- f.Close();
-
- // Delete old format file, only do this when conversion has succeeded
- if (std::remove(a_FileName) != 0)
- {
- LOGERROR("COULD NOT DELETE old format file \"%s\"", a_FileName);
- return;
- }
-
- LOGINFO("Successfully converted binary to Json \"%s\"", FileNameJson.c_str() );
-}
-
-
-
-
+ +#include "Globals.h" + +#include "cFileFormatUpdater.h" +#include "Vector3d.h" +#include "Vector3f.h" + +#include "cItem.h" +#include <json/json.h> + + + + + +void cFileFormatUpdater::UpdateFileFormat() +{ + UpdatePlayersOfWorld("world"); +} + + + + + +// Convert player .bin files to JSON +void cFileFormatUpdater::UpdatePlayersOfWorld( const char* a_WorldName ) +{ + AString PlayerDir = AString( a_WorldName ) + "/player/"; + + AStringList AllFiles = GetDirectoryContents( PlayerDir.c_str() ); + for (AStringList::iterator itr = AllFiles.begin(); itr != AllFiles.end(); ++itr ) + { + AString & FileName = *itr; + if (FileName.rfind(".bin") != AString::npos) // Get only the files ending in .bin + { + PlayerBINtoJSON( (PlayerDir + FileName).c_str() ); + } + } +} + + + + + +#define READ(File, Var) \ + if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("ERROR READING \"%s\" FROM FILE \"%s\"", #Var, a_FileName); \ + return; \ + } + +// Converts player binary files to human readable JSON +void cFileFormatUpdater::PlayerBINtoJSON( const char* a_FileName ) +{ + Vector3d PlayerPos; + Vector3f PlayerRot; + short PlayerHealth = 0; + + const unsigned int NumInventorySlots = 45; // At this time the player inventory has/had 45 slots + cItem IventoryItems[ NumInventorySlots ]; + + cFile f; + if (!f.Open(a_FileName, cFile::fmRead)) + { + return; + } + + // First read player position, rotation and health + READ(f, PlayerPos.x); + READ(f, PlayerPos.y); + READ(f, PlayerPos.z); + READ(f, PlayerRot.x); + READ(f, PlayerRot.y); + READ(f, PlayerRot.z); + READ(f, PlayerHealth); + + + for(unsigned int i = 0; i < NumInventorySlots; i++) + { + cItem & Item = IventoryItems[i]; + READ(f, Item.m_ItemID); + READ(f, Item.m_ItemCount); + READ(f, Item.m_ItemHealth); + } + f.Close(); + + // Loaded all the data, now create the JSON data + Json::Value JSON_PlayerPosition; + JSON_PlayerPosition.append( Json::Value( PlayerPos.x ) ); + JSON_PlayerPosition.append( Json::Value( PlayerPos.y ) ); + JSON_PlayerPosition.append( Json::Value( PlayerPos.z ) ); + + Json::Value JSON_PlayerRotation; + JSON_PlayerRotation.append( Json::Value( PlayerRot.x ) ); + JSON_PlayerRotation.append( Json::Value( PlayerRot.y ) ); + JSON_PlayerRotation.append( Json::Value( PlayerRot.z ) ); + + Json::Value JSON_Inventory; + for(unsigned int i = 0; i < NumInventorySlots; i++) + { + Json::Value JSON_Item; + IventoryItems[i].GetJson( JSON_Item ); + JSON_Inventory.append( JSON_Item ); + } + + Json::Value root; + root["position"] = JSON_PlayerPosition; + root["rotation"] = JSON_PlayerRotation; + root["inventory"] = JSON_Inventory; + root["health"] = PlayerHealth; + + Json::StyledWriter writer; + std::string JsonData = writer.write( root ); + + // Get correct filename + std::string FileName = a_FileName; + std::string FileNameWithoutExt = FileName.substr(0, FileName.find_last_of(".") ); + std::string FileNameJson = FileNameWithoutExt + ".json"; + + // Write to file + if (!f.Open(FileNameJson.c_str(), cFile::fmWrite)) + { + return; + } + if (f.Write(JsonData.c_str(), JsonData.size()) != JsonData.size()) + { + LOGERROR("ERROR WRITING PLAYER JSON TO FILE \"%s\"", FileNameJson.c_str()); + return; + } + f.Close(); + + // Delete old format file, only do this when conversion has succeeded + if (std::remove(a_FileName) != 0) + { + LOGERROR("COULD NOT DELETE old format file \"%s\"", a_FileName); + return; + } + + LOGINFO("Successfully converted binary to Json \"%s\"", FileNameJson.c_str() ); +} + + + + diff --git a/source/cFileFormatUpdater.h b/source/cFileFormatUpdater.h index fc6beed6e..91e2761fb 100644 --- a/source/cFileFormatUpdater.h +++ b/source/cFileFormatUpdater.h @@ -1,11 +1,11 @@ -#pragma once
-
-class cFileFormatUpdater
-{
-public:
- static void UpdateFileFormat();
-private:
- static void UpdatePlayersOfWorld( const char* a_WorldName );
-
- static void PlayerBINtoJSON( const char* a_FileName );
+#pragma once + +class cFileFormatUpdater +{ +public: + static void UpdateFileFormat(); +private: + static void UpdatePlayersOfWorld( const char* a_WorldName ); + + static void PlayerBINtoJSON( const char* a_FileName ); };
\ No newline at end of file diff --git a/source/cFireSimulator.cpp b/source/cFireSimulator.cpp index 0d6b59422..8b6710b74 100644 --- a/source/cFireSimulator.cpp +++ b/source/cFireSimulator.cpp @@ -1,132 +1,132 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cFireSimulator.h"
-#include "cWorld.h"
-#include "Vector3i.h"
-#include "BlockID.h"
-#include "Defines.h"
-
-cFireSimulator::cFireSimulator( cWorld* a_World )
- : cSimulator(a_World)
- , m_Blocks(new BlockList)
- , m_Buffer(new BlockList)
- , m_BurningBlocks(new BlockList)
-{
-
-}
-
-cFireSimulator::~cFireSimulator()
-{
- delete m_Buffer;
- delete m_Blocks;
- delete m_BurningBlocks;
-}
-
-void cFireSimulator::Simulate( float a_Dt )
-{
- m_Buffer->clear();
- std::swap( m_Blocks, m_Buffer );
-
- for( BlockList::iterator itr = m_Buffer->begin(); itr != m_Buffer->end(); ++itr )
- {
- Vector3i Pos = *itr;
-
- char BlockID = m_World->GetBlock(Pos.x, Pos.y, Pos.z);
-
- if(!IsAllowedBlock(BlockID)) //Check wheather the block is still burning
- continue;
-
- if(BurnBlockAround(Pos.x, Pos.y, Pos.z)) //Burn single block and if there was one -> next time again
- _AddBlock(Pos.x, Pos.y, Pos.z);
- else
- if(!IsForeverBurnable(m_World->GetBlock(Pos.x, Pos.y - 1, Pos.z)) && !FiresForever(BlockID))
- m_World->SetBlock(Pos.x, Pos.y, Pos.z, E_BLOCK_AIR, 0);
-
- }
-
-}
-
-
-bool cFireSimulator::IsAllowedBlock( char a_BlockID )
-{
- return a_BlockID == E_BLOCK_FIRE
- || IsBlockLava(a_BlockID);
-}
-
-void cFireSimulator::AddBlock(int a_X, int a_Y, int a_Z)
-{
- char BlockID = m_World->GetBlock(a_X, a_Y, a_Z);
- if(!IsAllowedBlock(BlockID)) //This should save very much time because it doesn´t have to iterate through all blocks
- return;
-
- //check for duplicates
- for( BlockList::iterator itr = m_Blocks->begin(); itr != m_Blocks->end(); ++itr )
- {
- Vector3i Pos = *itr;
- if( Pos.x == a_X && Pos.y == a_Y && Pos.z == a_Z )
- return;
- }
-
- _AddBlock(a_X, a_Y, a_Z);
-
-}
-
-void cFireSimulator::_AddBlock(int a_X, int a_Y, int a_Z)
-{
- m_Blocks->push_back( Vector3i(a_X, a_Y, a_Z) );
-
-}
-
-bool cFireSimulator::IsForeverBurnable( char a_BlockID )
-{
- return a_BlockID == E_BLOCK_BLOODSTONE;
-}
-
-bool cFireSimulator::IsBurnable( char a_BlockID )
-{
- return a_BlockID == E_BLOCK_PLANKS
- || a_BlockID == E_BLOCK_LEAVES
- || a_BlockID == E_BLOCK_LOG
- || a_BlockID == E_BLOCK_WHITE_CLOTH
- || a_BlockID == E_BLOCK_BOOKCASE
- || a_BlockID == E_BLOCK_FENCE
- || a_BlockID == E_BLOCK_TNT;
-}
-
-bool cFireSimulator::FiresForever( char a_BlockID )
-{
- return a_BlockID != E_BLOCK_FIRE;
-}
-
-bool cFireSimulator::BurnBlockAround(int a_X, int a_Y, int a_Z)
-{
- return BurnBlock(a_X + 1, a_Y, a_Z)
- || BurnBlock(a_X - 1, a_Y, a_Z)
- || BurnBlock(a_X, a_Y + 1, a_Z)
- || BurnBlock(a_X, a_Y - 1, a_Z)
- || BurnBlock(a_X, a_Y, a_Z + 1)
- || BurnBlock(a_X, a_Y, a_Z - 1);
-}
-
-bool cFireSimulator::BurnBlock(int a_X, int a_Y, int a_Z)
-{
- char BlockID = m_World->GetBlock(a_X, a_Y, a_Z);
- if(IsBurnable(BlockID))
- {
- m_World->SetBlock(a_X, a_Y, a_Z, E_BLOCK_FIRE, 0);
- return true;
- }
- if(IsForeverBurnable(BlockID))
- {
- char BlockAbove = m_World->GetBlock(a_X, a_Y + 1, a_Z);
- if(BlockAbove == E_BLOCK_AIR)
- {
- m_World->SetBlock(a_X, a_Y + 1, a_Z, E_BLOCK_FIRE, 0); //Doesn´t notify the simulator so it won´t go off
- return true;
- }
- return false;
- }
-
- return false;
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cFireSimulator.h" +#include "cWorld.h" +#include "Vector3i.h" +#include "BlockID.h" +#include "Defines.h" + +cFireSimulator::cFireSimulator( cWorld* a_World ) + : cSimulator(a_World) + , m_Blocks(new BlockList) + , m_Buffer(new BlockList) + , m_BurningBlocks(new BlockList) +{ + +} + +cFireSimulator::~cFireSimulator() +{ + delete m_Buffer; + delete m_Blocks; + delete m_BurningBlocks; +} + +void cFireSimulator::Simulate( float a_Dt ) +{ + m_Buffer->clear(); + std::swap( m_Blocks, m_Buffer ); + + for( BlockList::iterator itr = m_Buffer->begin(); itr != m_Buffer->end(); ++itr ) + { + Vector3i Pos = *itr; + + char BlockID = m_World->GetBlock(Pos.x, Pos.y, Pos.z); + + if(!IsAllowedBlock(BlockID)) //Check wheather the block is still burning + continue; + + if(BurnBlockAround(Pos.x, Pos.y, Pos.z)) //Burn single block and if there was one -> next time again + _AddBlock(Pos.x, Pos.y, Pos.z); + else + if(!IsForeverBurnable(m_World->GetBlock(Pos.x, Pos.y - 1, Pos.z)) && !FiresForever(BlockID)) + m_World->SetBlock(Pos.x, Pos.y, Pos.z, E_BLOCK_AIR, 0); + + } + +} + + +bool cFireSimulator::IsAllowedBlock( char a_BlockID ) +{ + return a_BlockID == E_BLOCK_FIRE + || IsBlockLava(a_BlockID); +} + +void cFireSimulator::AddBlock(int a_X, int a_Y, int a_Z) +{ + char BlockID = m_World->GetBlock(a_X, a_Y, a_Z); + if(!IsAllowedBlock(BlockID)) //This should save very much time because it doesn´t have to iterate through all blocks + return; + + //check for duplicates + for( BlockList::iterator itr = m_Blocks->begin(); itr != m_Blocks->end(); ++itr ) + { + Vector3i Pos = *itr; + if( Pos.x == a_X && Pos.y == a_Y && Pos.z == a_Z ) + return; + } + + _AddBlock(a_X, a_Y, a_Z); + +} + +void cFireSimulator::_AddBlock(int a_X, int a_Y, int a_Z) +{ + m_Blocks->push_back( Vector3i(a_X, a_Y, a_Z) ); + +} + +bool cFireSimulator::IsForeverBurnable( char a_BlockID ) +{ + return a_BlockID == E_BLOCK_BLOODSTONE; +} + +bool cFireSimulator::IsBurnable( char a_BlockID ) +{ + return a_BlockID == E_BLOCK_PLANKS + || a_BlockID == E_BLOCK_LEAVES + || a_BlockID == E_BLOCK_LOG + || a_BlockID == E_BLOCK_WHITE_CLOTH + || a_BlockID == E_BLOCK_BOOKCASE + || a_BlockID == E_BLOCK_FENCE + || a_BlockID == E_BLOCK_TNT; +} + +bool cFireSimulator::FiresForever( char a_BlockID ) +{ + return a_BlockID != E_BLOCK_FIRE; +} + +bool cFireSimulator::BurnBlockAround(int a_X, int a_Y, int a_Z) +{ + return BurnBlock(a_X + 1, a_Y, a_Z) + || BurnBlock(a_X - 1, a_Y, a_Z) + || BurnBlock(a_X, a_Y + 1, a_Z) + || BurnBlock(a_X, a_Y - 1, a_Z) + || BurnBlock(a_X, a_Y, a_Z + 1) + || BurnBlock(a_X, a_Y, a_Z - 1); +} + +bool cFireSimulator::BurnBlock(int a_X, int a_Y, int a_Z) +{ + char BlockID = m_World->GetBlock(a_X, a_Y, a_Z); + if(IsBurnable(BlockID)) + { + m_World->SetBlock(a_X, a_Y, a_Z, E_BLOCK_FIRE, 0); + return true; + } + if(IsForeverBurnable(BlockID)) + { + char BlockAbove = m_World->GetBlock(a_X, a_Y + 1, a_Z); + if(BlockAbove == E_BLOCK_AIR) + { + m_World->SetBlock(a_X, a_Y + 1, a_Z, E_BLOCK_FIRE, 0); //Doesn´t notify the simulator so it won´t go off + return true; + } + return false; + } + + return false; }
\ No newline at end of file diff --git a/source/cFireSimulator.h b/source/cFireSimulator.h index f66fb2019..5c6a3aeaa 100644 --- a/source/cFireSimulator.h +++ b/source/cFireSimulator.h @@ -1,47 +1,47 @@ -
-#pragma once
-
-#include "cSimulator.h"
-#include "cBlockEntity.h"
-
-
-
-
-
-class Vector3i;
-class cWorld;
-
-
-
-
-
-class cFireSimulator : public cSimulator
-{
-public:
- cFireSimulator( cWorld* a_World );
- ~cFireSimulator();
-
- virtual void Simulate( float a_Dt );
-
- virtual bool IsAllowedBlock( char a_BlockID );
-
- virtual bool IsBurnable( char a_BlockID );
- virtual bool IsForeverBurnable( char a_BlockID );
- virtual bool FiresForever( char a_BlockID );
-
-protected:
- virtual void AddBlock(int a_X, int a_Y, int a_Z);
- virtual void _AddBlock(int a_X, int a_Y, int a_Z);
- virtual bool BurnBlockAround(int a_X, int a_Y, int a_Z);
- virtual bool BurnBlock(int a_X, int a_Y, int a_Z);
-
- typedef std::list <Vector3i> BlockList;
- BlockList *m_Blocks;
- BlockList *m_Buffer;
-
- BlockList *m_BurningBlocks;
-};
-
-
-
-
+ +#pragma once + +#include "cSimulator.h" +#include "cBlockEntity.h" + + + + + +class Vector3i; +class cWorld; + + + + + +class cFireSimulator : public cSimulator +{ +public: + cFireSimulator( cWorld* a_World ); + ~cFireSimulator(); + + virtual void Simulate( float a_Dt ); + + virtual bool IsAllowedBlock( char a_BlockID ); + + virtual bool IsBurnable( char a_BlockID ); + virtual bool IsForeverBurnable( char a_BlockID ); + virtual bool FiresForever( char a_BlockID ); + +protected: + virtual void AddBlock(int a_X, int a_Y, int a_Z); + virtual void _AddBlock(int a_X, int a_Y, int a_Z); + virtual bool BurnBlockAround(int a_X, int a_Y, int a_Z); + virtual bool BurnBlock(int a_X, int a_Y, int a_Z); + + typedef std::list <Vector3i> BlockList; + BlockList *m_Blocks; + BlockList *m_Buffer; + + BlockList *m_BurningBlocks; +}; + + + + diff --git a/source/cFluidSimulator.cpp b/source/cFluidSimulator.cpp index 38bf55d77..1301caa8c 100644 --- a/source/cFluidSimulator.cpp +++ b/source/cFluidSimulator.cpp @@ -1,688 +1,688 @@ -#include "Globals.h"
-
-#include <set>
-#include <queue>
-
-#include "cFluidSimulator.h"
-#include "cWorld.h"
-#include "Vector3i.h"
-#include "BlockID.h"
-#include "Defines.h"
-#include "cItem.h"
-#include "cBlockToPickup.h"
-
-
-
-
-
-//#define DEBUG_FLUID
-#ifdef DEBUG_FLUID
-#define LOG_FLUID(...) LOGWARN( __VA_ARGS__ )
-#else
-#define LOG_FLUID(...)
-#endif
-
-
-
-
-
-class cFluidSimulator::FluidData
-{
-public:
- FluidData( cWorld* a_World, cFluidSimulator *a_Simulator )
- : m_ActiveFluid( new std::set < Vector3i >() )
- , m_Simulator (a_Simulator)
- , m_Buffer( new std::set< Vector3i >() )
- , m_World( a_World )
- {}
-
- ~FluidData()
- {
- delete m_Buffer;
- delete m_ActiveFluid;
- }
-
- void UpdateWave(Vector3i a_LeftCorner, Vector3i a_CurBlock)
- {
- Vector3i LevelPoints [] = {
- Vector3i( a_CurBlock.x-1, a_CurBlock.y, a_CurBlock.z ),
- Vector3i( a_CurBlock.x+1, a_CurBlock.y, a_CurBlock.z ),
- Vector3i( a_CurBlock.x, a_CurBlock.y, a_CurBlock.z-1 ),
- Vector3i( a_CurBlock.x, a_CurBlock.y, a_CurBlock.z+1 ),
- };
-
- for(int i=0; i<4; i++)
- {
- Vector3i cur = LevelPoints[i];
- switch(m_Relief[cur.x][cur.z])
- {
- case E_HOLE:
- {
- m_StartSide[cur.x][cur.z] = m_StartSide[a_CurBlock.x][a_CurBlock.z];
- m_CurResult|=m_StartSide[cur.x][cur.z];
- m_NearestHole = m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1;
- LOG_FLUID("Hole found: %d \t curResult: %d", int(m_StartSide[cur.x][cur.z]), int(m_CurResult) );
- LOG_FLUID("Coordinates: (%d, %d)", cur.x, cur.z);
- }break;
-
- case E_BLOCK:
- {}break;
-
- case E_PLAIN:
- {
- if (m_WayLength[cur.x][cur.z] > m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1)
- {
- m_WayLength[cur.x][cur.z] = m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1;
- m_StartSide[cur.x][cur.z] = m_StartSide[a_CurBlock.x][a_CurBlock.z];
- m_WaveQueue.push(cur);
- }
- else if(m_WayLength[cur.x][cur.z] == m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1)
- {
- m_StartSide[cur.x][cur.z] |= m_StartSide[a_CurBlock.x][a_CurBlock.z];
- }
- LOG_FLUID("Plain step: (%d, %d) from %d", cur.x, cur.z, m_StartSide[cur.x][cur.z]);
- }
- }
- }
- }
-
- std::vector< Vector3i > GetLowestPoints( int a_X, int a_Y, int a_Z )
- {
-
- std::vector< Vector3i > Points; //result
-
- Vector3i CornerGlobal(a_X - AREA_WIDTH/2, a_Y, a_Z - AREA_WIDTH/2);
-
- //TODO: rewrite without relief, get blocks directly in algorithm
- for(int x=0; x<AREA_WIDTH; x++)
- {
- for(int z=0; z<AREA_WIDTH; z++)
- {
- char UpperBlock = m_World->GetBlock( CornerGlobal.x + x, CornerGlobal.y, CornerGlobal.z + z );
- char DownBlock = m_World->GetBlock( CornerGlobal.x + x, CornerGlobal.y-1, CornerGlobal.z + z );
-
- if(m_Simulator->IsSolidBlock(UpperBlock)||(m_Simulator->IsStationaryBlock(UpperBlock)))
- {
- m_Relief[x][z] = E_BLOCK;
- }
- else if(m_Simulator->IsSolidBlock(DownBlock))
- {
- m_Relief[x][z] = E_PLAIN;
- }
- else
- {
- m_Relief[x][z] = E_HOLE;
- }
- m_WayLength[x][z] = 255;
- m_StartSide[x][z] = E_SIDE_NONE;
- }
- LOG_FLUID("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t", m_Relief[x][0], m_Relief[x][1], m_Relief[x][2], m_Relief[x][3], m_Relief[x][4], m_Relief[x][5], m_Relief[x][6], m_Relief[x][7], m_Relief[x][8], m_Relief[x][9], m_Relief[x][10]);
- }
-
- m_NearestHole = 5;
- m_CurResult = 0;
- while(!m_WaveQueue.empty()) m_WaveQueue.pop();
-
- int left = AREA_WIDTH/2 - 1;
- int right = AREA_WIDTH/2 + 1;
- int center = AREA_WIDTH/2;
-
- Vector3i r(right, 0, center); //right block
- Vector3i l(left, 0, center); //left block
- Vector3i f(center, 0, right); //front block
- Vector3i b(center, 0, left); //back block
- Vector3i c(center, 0, center); //center block
-
- m_WayLength[c.x][c.z] = 0;
-
- Vector3i Nearest[] = {r, l, f, b};
- unsigned char Sides[] = {E_SIDE_RIGHT, E_SIDE_LEFT, E_SIDE_FRONT, E_SIDE_BACK};
-
- for(int i=0; i<4; i++)
- {
- Vector3i cur = Nearest[i];
- switch(m_Relief[cur.x][cur.z])
- {
- case E_HOLE:
- {
- m_StartSide[cur.x][cur.z] = Sides[i];
- m_CurResult |= m_StartSide[cur.x][cur.z];
- m_NearestHole = 1;
- LOG_FLUID("Hole found: %d \t curResult: %d", int(Sides[i]), int(m_CurResult) );
- }break;
-
- case E_BLOCK:
- {}break;
-
- case E_PLAIN:
- {
- m_WaveQueue.push(cur);
- m_StartSide[cur.x][cur.z] = Sides[i];
- m_WayLength[cur.x][cur.z] = 1;
- LOG_FLUID("Plain found: %d", int(Sides[i]));
- }
- }
- }
-
- Vector3i curBlock;
-
- bool bContinue = !m_WaveQueue.empty();
-
- if(!m_WaveQueue.empty())
- {
- curBlock = m_WaveQueue.front();
- bContinue = (m_WayLength[curBlock.x][curBlock.z] < m_NearestHole);
- }
-
- while(bContinue)
- {
- LOG_FLUID("while iteration" );
- curBlock = m_WaveQueue.front();
- UpdateWave(CornerGlobal, curBlock);
- m_WaveQueue.pop();
-
- bContinue = ( (!m_WaveQueue.empty()) && (m_WayLength[m_WaveQueue.front().x][m_WaveQueue.front().z] < m_NearestHole) );
- }
-
-
-
- if(m_CurResult & E_SIDE_LEFT) Points.push_back(Vector3i( a_X-1, a_Y, a_Z ));
- if(m_CurResult & E_SIDE_RIGHT) Points.push_back(Vector3i( a_X+1, a_Y, a_Z ));
- if(m_CurResult & E_SIDE_FRONT) Points.push_back(Vector3i( a_X, a_Y, a_Z+1 ));
- if(m_CurResult & E_SIDE_BACK) Points.push_back(Vector3i( a_X, a_Y, a_Z-1 ));
-
- if(Points.empty())
- {
- Vector3i LevelPoints [] = {
- Vector3i( a_X-1, a_Y, a_Z ),
- Vector3i( a_X+1, a_Y, a_Z ),
- Vector3i( a_X, a_Y, a_Z-1 ),
- Vector3i( a_X, a_Y, a_Z+1 ),
- };
- for( int i = 0; i < 4; ++i )
- {
- char Block = m_World->GetBlock( LevelPoints[i].x, a_Y, LevelPoints[i].z );
- if( m_Simulator->IsPassableForFluid(Block) )
- Points.push_back( LevelPoints[i] );
- }
- }
-
- return Points;
- }
-
- std::set< Vector3i >* m_ActiveFluid;
- std::set< Vector3i >* m_Buffer;
- cWorld* m_World;
- cFluidSimulator *m_Simulator;
-
- const static int AREA_WIDTH = 11;
-
- const static unsigned char E_SIDE_RIGHT = 0x10;
- const static unsigned char E_SIDE_LEFT = 0x20;
- const static unsigned char E_SIDE_FRONT = 0x40;
- const static unsigned char E_SIDE_BACK = 0x80;
- const static unsigned char E_SIDE_NONE = 0x00;
-
- enum eRelief {E_HOLE = 0, E_PLAIN = 1, E_BLOCK = 2};
-
- eRelief m_Relief[AREA_WIDTH][AREA_WIDTH];
- unsigned char m_WayLength[AREA_WIDTH][AREA_WIDTH];
- unsigned char m_StartSide[AREA_WIDTH][AREA_WIDTH];
-
- std::queue<Vector3i> m_WaveQueue;
-
- int m_NearestHole;
- unsigned char m_CurResult;
-};
-
-
-
-
-
-cFluidSimulator::cFluidSimulator( cWorld* a_World )
- : cSimulator(a_World)
- , m_Data(0)
-{
- m_Data = new FluidData(a_World, this);
-}
-
-
-
-
-
-cFluidSimulator::~cFluidSimulator()
-{
- delete m_Data;
-}
-
-
-
-
-
-void cFluidSimulator::AddBlock( int a_X, int a_Y, int a_Z )
-{
- char BlockType = m_World->GetBlock(a_X, a_Y, a_Z);
- if (!IsAllowedBlock(BlockType)) //This should save very much time because it doesn´t have to iterate through all blocks
- {
- return;
- }
-
- std::set< Vector3i > & ActiveFluid = *m_Data->m_ActiveFluid;
- ActiveFluid.insert( Vector3i( a_X, a_Y, a_Z ) );
-}
-
-
-
-
-
-char cFluidSimulator::GetHighestLevelAround( int a_X, int a_Y, int a_Z )
-{
- char Max = m_MaxHeight + m_FlowReduction;
-
-#define __HIGHLEVEL_CHECK__( x, y, z ) \
- if( IsAllowedBlock( m_World->GetBlock( x, y, z ) ) ) \
- { \
- char Meta; \
- if( (Meta = m_World->GetBlockMeta( x, y, z ) ) < Max ) Max = Meta; \
- else if( Meta == m_MaxHeight + m_FlowReduction ) Max = 0; \
- if( Max == 0 ) return 0; \
- }
-
- __HIGHLEVEL_CHECK__( a_X-1, a_Y, a_Z );
- __HIGHLEVEL_CHECK__( a_X+1, a_Y, a_Z );
- __HIGHLEVEL_CHECK__( a_X, a_Y, a_Z-1 );
- __HIGHLEVEL_CHECK__( a_X, a_Y, a_Z+1 );
-
- return Max;
-}
-
-
-
-
-
-void cFluidSimulator::Simulate( float a_Dt )
-{
- m_Timer += a_Dt;
-
- if (m_Data->m_ActiveFluid->empty()) //Nothing to do if there is no active fluid ;) saves very little time ;D
- {
- return;
- }
-
- std::swap( m_Data->m_ActiveFluid, m_Data->m_Buffer ); // Swap so blocks can be added to empty ActiveFluid array
- m_Data->m_ActiveFluid->clear();
-
- std::set< Vector3i > & FluidBlocks = *m_Data->m_Buffer;
- for( std::set< Vector3i >::iterator itr = FluidBlocks.begin(); itr != FluidBlocks.end(); ++itr )
- {
- const Vector3i & pos = *itr;
-
- if(UniqueSituation(pos))
- {
- continue;
- }
-
- char BlockID = m_World->GetBlock( pos.x, pos.y, pos.z );
- if( IsAllowedBlock( BlockID ) ) // only care about own fluid
- {
- bool bIsFed = false;
- char Meta = m_World->GetBlockMeta( pos.x, pos.y, pos.z );
- char Feed = Meta;
- if( BlockID == m_StationaryFluidBlock) Meta = 0;
- if( Meta == 8 ) // Falling fluid
- {
- if( IsAllowedBlock( m_World->GetBlock(pos.x, pos.y+1, pos.z) ) ) // Block above is fluid
- {
- bIsFed = true;
- Meta = 0; // Make it a full block
- }
- }
- else if( Meta < m_FlowReduction ) // It's a full block, so it's always fed
- {
- bIsFed = true;
- }
- else
- {
- if( (Feed = GetHighestLevelAround( pos.x, pos.y, pos.z )) < Meta )
- bIsFed = true;
- }
-
-
- if( bIsFed )
- {
- char DownID = m_World->GetBlock( pos.x, pos.y-1, pos.z );
- bool bWashedAwayItem = CanWashAway( DownID );
- if( (IsPassableForFluid(DownID) || bWashedAwayItem) && !IsStationaryBlock(DownID) ) // free for fluid
- {
- if( bWashedAwayItem )
- {
- cItems Drops;
- cBlockToPickup::ToPickup(DownID, m_World->GetBlockMeta(pos.x, pos.y - 1, pos.z), E_ITEM_EMPTY, Drops);
- m_World->SpawnItemPickups(Drops, pos.x, pos.y - 1, pos.z);
- }
- if (pos.y > 0)
- {
- m_World->FastSetBlock( pos.x, pos.y-1, pos.z, m_FluidBlock, 8 ); // falling
- AddBlock( pos.x, pos.y-1, pos.z );
- ApplyUniqueToNearest(pos - Vector3i(0, 1, 0));
- }
- }
- if(IsSolidBlock(DownID)||( BlockID == m_StationaryFluidBlock)) // Not falling
- {
- if( Feed + m_FlowReduction < Meta )
- {
- m_World->FastSetBlock( pos.x, pos.y, pos.z, m_FluidBlock, Feed + m_FlowReduction );
- AddBlock( pos.x, pos.y, pos.z );
- ApplyUniqueToNearest(pos);
- }
- else if(( Meta < m_MaxHeight )||( BlockID == m_StationaryFluidBlock)) // max is the lowest, so it cannot spread
- {
- std::vector< Vector3i > Points = m_Data->GetLowestPoints( pos.x, pos.y, pos.z );
- for( std::vector< Vector3i >::iterator itr = Points.begin(); itr != Points.end(); ++itr )
- {
- Vector3i & p = *itr;
- char BlockID = m_World->GetBlock( p.x, p.y, p.z );
- bool bWashedAwayItem = CanWashAway( BlockID );
-
- if (!IsPassableForFluid(BlockID)) continue;
-
- if (!IsAllowedBlock(BlockID))
- {
- if (bWashedAwayItem)
- {
- cItems Drops;
- cBlockToPickup::ToPickup(DownID, m_World->GetBlockMeta(p.x, p.y, p.z), E_ITEM_EMPTY, Drops);
- m_World->SpawnItemPickups(Drops, p.x, p.y, p.z);
- }
-
- if( p.y == pos.y )
- {
- m_World->FastSetBlock(p.x, p.y, p.z, m_FluidBlock, Meta + m_FlowReduction);
- }
- else
- {
- m_World->FastSetBlock(p.x, p.y, p.z, m_FluidBlock, 8);
- }
- AddBlock( p.x, p.y, p.z );
- ApplyUniqueToNearest(p);
- }
- else // it's fluid
- {
- char PointMeta = m_World->GetBlockMeta( p.x, p.y, p.z );
- if( PointMeta > Meta + m_FlowReduction )
- {
- AddBlock( p.x, p.y, p.z );
- ApplyUniqueToNearest(p);
- }
- }
- }
- }
- }
- }
- else// not fed
- {
- m_World->FastSetBlock( pos.x, pos.y, pos.z, E_BLOCK_AIR, 0 );
- WakeUp( pos.x, pos.y, pos.z );
- }
- }
- }
-}
-
-
-
-
-
-bool cFluidSimulator::IsPassableForFluid(char a_BlockID)
-{
- return a_BlockID == E_BLOCK_AIR
- || a_BlockID == E_BLOCK_FIRE
- || IsAllowedBlock(a_BlockID)
- || CanWashAway(a_BlockID);
-}
-
-
-
-
-
-bool cFluidSimulator::IsStationaryBlock (char a_BlockID)
-{
- return a_BlockID == m_StationaryFluidBlock;
-}
-
-
-
-
-
-bool cFluidSimulator::CanWashAway( char a_BlockID )
-{
- switch( a_BlockID )
- {
- case E_BLOCK_YELLOW_FLOWER:
- case E_BLOCK_RED_ROSE:
- case E_BLOCK_RED_MUSHROOM:
- case E_BLOCK_BROWN_MUSHROOM:
- case E_BLOCK_CACTUS:
- return true;
- default:
- return false;
- };
-}
-
-
-
-
-
-bool cFluidSimulator::IsSolidBlock( char a_BlockID )
-{
- return !(a_BlockID == E_BLOCK_AIR
- || a_BlockID == E_BLOCK_FIRE
- || IsBlockLava(a_BlockID)
- || IsBlockWater(a_BlockID)
- || CanWashAway(a_BlockID));
-}
-
-
-
-
-
-//TODO Not working very well yet :s
-Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over)
-{
- char BlockID = m_World->GetBlock(a_X, a_Y, a_Z);
- if(!IsAllowedBlock(BlockID)) //No Fluid -> No Flowing direction :D
- return NONE;
-
-
- /*
- Disabled because of causing problems and beeing useless atm
- char BlockBelow = m_World->GetBlock(a_X, a_Y - 1, a_Z); //If there is nothing or fluid below it -> dominating flow is down :D
- if(BlockBelow == E_BLOCK_AIR || IsAllowedBlock(BlockBelow))
- return Y_MINUS;
- */
-
- char LowestPoint = m_World->GetBlockMeta(a_X, a_Y, a_Z); //Current Block Meta so only lower points will be counted
- int X = 0, Y = 0, Z = 0; //Lowest Pos will be stored here
-
- if(IsAllowedBlock(m_World->GetBlock(a_X, a_Y + 1, a_Z)) && a_Over) //check for upper block to flow because this also affects the flowing direction
- {
- return GetFlowingDirection(a_X, a_Y + 1, a_Z, false);
- }
-
- std::vector< Vector3i * > Points;
-
- Points.reserve(4); //Already allocate 4 places :D
-
- //add blocks around the checking pos
- Points.push_back(new Vector3i(a_X - 1, a_Y, a_Z));
- Points.push_back(new Vector3i(a_X + 1, a_Y, a_Z));
- Points.push_back(new Vector3i(a_X, a_Y, a_Z + 1));
- Points.push_back(new Vector3i(a_X, a_Y, a_Z - 1));
-
- for(std::vector<Vector3i *>::iterator it = Points.begin(); it < Points.end(); it++)
- {
- Vector3i *Pos = (*it);
- char BlockID = m_World->GetBlock(Pos->x, Pos->y, Pos->z);
- if(IsAllowedBlock(BlockID))
- {
- char Meta = m_World->GetBlockMeta(Pos->x, Pos->y, Pos->z);
-
- if(Meta > LowestPoint)
- {
- LowestPoint = Meta;
- X = Pos->x;
- Y = Pos->y;
- Z = Pos->z;
- }
- }else if(BlockID == E_BLOCK_AIR)
- {
- LowestPoint = 9; //This always dominates
- X = Pos->x;
- Y = Pos->y;
- Z = Pos->z;
-
- }
- delete Pos;
- }
-
- if(LowestPoint == m_World->GetBlockMeta(a_X, a_Y, a_Z))
- return NONE;
-
- if(a_X - X > 0)
- {
- return X_MINUS;
- }
-
- if(a_X - X < 0)
- {
- return X_PLUS;
- }
-
- if(a_Z - Z > 0)
- {
- return Z_MINUS;
- }
-
- if(a_Z - Z < 0)
- {
- return Z_PLUS;
- }
-
- return NONE;
-}
-
-
-
-
-
-bool cFluidSimulator::UniqueSituation(Vector3i a_Pos)
-{
- bool result = false;
-
- char BlockId = m_World->GetBlock( a_Pos.x, a_Pos.y, a_Pos.z );
- char Meta = m_World->GetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z );
-
- if(IsBlockWater(BlockId))
- {
-
- char UpperBlock = m_World->GetBlock( a_Pos.x, a_Pos.y + 1, a_Pos.z );
- if(IsBlockLava(UpperBlock))
- {
- m_World->SetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_STONE, 0);
- }
-
-
- if(BlockId != E_BLOCK_STATIONARY_WATER)
- {
- char DownBlockId = m_World->GetBlock( a_Pos.x, a_Pos.y-1, a_Pos.z );
- if(IsSolidBlock(DownBlockId))
- {
- Vector3i LevelPoints [] = {
- Vector3i( a_Pos.x-1, a_Pos.y, a_Pos.z ),
- Vector3i( a_Pos.x+1, a_Pos.y, a_Pos.z ),
- Vector3i( a_Pos.x, a_Pos.y, a_Pos.z-1 ),
- Vector3i( a_Pos.x, a_Pos.y, a_Pos.z+1 ),
- };
- int SourceBlocksCount = 0;
- for(int i=0; i<4; i++)
- {
- if (m_World->GetBlock(LevelPoints[i].x, LevelPoints[i].y, LevelPoints[i].z)==E_BLOCK_STATIONARY_WATER)
- {
- SourceBlocksCount++;
- }
- }
- if(SourceBlocksCount>=2)
- {
- m_World->SetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_STATIONARY_WATER, 0);
- }
- }
-
- }
- }
-
- if(IsBlockLava(BlockId))
- {
- bool bWater = false;
-
- char UpperBlock = m_World->GetBlock( a_Pos.x, a_Pos.y + 1, a_Pos.z );
- if (IsBlockWater(UpperBlock))
- {
- bWater = true;
- }
- else
- {
- Vector3i LevelPoints [] = {
- Vector3i( a_Pos.x-1, a_Pos.y, a_Pos.z ),
- Vector3i( a_Pos.x+1, a_Pos.y, a_Pos.z ),
- Vector3i( a_Pos.x, a_Pos.y, a_Pos.z-1 ),
- Vector3i( a_Pos.x, a_Pos.y, a_Pos.z+1 ),
- };
-
- for(int i=0; i<4; i++)
- {
- if (IsBlockWater(m_World->GetBlock(LevelPoints[i].x, LevelPoints[i].y, LevelPoints[i].z)))
- {
- bWater = true;
- }
- }
- }
-
-
- if(bWater)
- {
- if(BlockId == E_BLOCK_STATIONARY_LAVA)
- {
- m_World->SetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_OBSIDIAN, 0);
- }
- else if (Meta<m_MaxHeight)
- {
- m_World->SetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_COBBLESTONE, 0);
- }
- }
- }
-
- return result;
-}
-
-
-
-
-
-void cFluidSimulator::ApplyUniqueToNearest(Vector3i a_Pos)
-{
- Vector3i NearPoints [] = {
- Vector3i( a_Pos.x-1, a_Pos.y, a_Pos.z ),
- Vector3i( a_Pos.x+1, a_Pos.y, a_Pos.z ),
- Vector3i( a_Pos.x, a_Pos.y, a_Pos.z-1 ),
- Vector3i( a_Pos.x, a_Pos.y, a_Pos.z+1 ),
- Vector3i( a_Pos.x, a_Pos.y-1, a_Pos.z )
- };
-
- for(int i=0; i<5; i++)
- {
- UniqueSituation(NearPoints[i]);
- }
-}
-
-
-
-
+#include "Globals.h" + +#include <set> +#include <queue> + +#include "cFluidSimulator.h" +#include "cWorld.h" +#include "Vector3i.h" +#include "BlockID.h" +#include "Defines.h" +#include "cItem.h" +#include "cBlockToPickup.h" + + + + + +//#define DEBUG_FLUID +#ifdef DEBUG_FLUID +#define LOG_FLUID(...) LOGWARN( __VA_ARGS__ ) +#else +#define LOG_FLUID(...) +#endif + + + + + +class cFluidSimulator::FluidData +{ +public: + FluidData( cWorld* a_World, cFluidSimulator *a_Simulator ) + : m_ActiveFluid( new std::set < Vector3i >() ) + , m_Simulator (a_Simulator) + , m_Buffer( new std::set< Vector3i >() ) + , m_World( a_World ) + {} + + ~FluidData() + { + delete m_Buffer; + delete m_ActiveFluid; + } + + void UpdateWave(Vector3i a_LeftCorner, Vector3i a_CurBlock) + { + Vector3i LevelPoints [] = { + Vector3i( a_CurBlock.x-1, a_CurBlock.y, a_CurBlock.z ), + Vector3i( a_CurBlock.x+1, a_CurBlock.y, a_CurBlock.z ), + Vector3i( a_CurBlock.x, a_CurBlock.y, a_CurBlock.z-1 ), + Vector3i( a_CurBlock.x, a_CurBlock.y, a_CurBlock.z+1 ), + }; + + for(int i=0; i<4; i++) + { + Vector3i cur = LevelPoints[i]; + switch(m_Relief[cur.x][cur.z]) + { + case E_HOLE: + { + m_StartSide[cur.x][cur.z] = m_StartSide[a_CurBlock.x][a_CurBlock.z]; + m_CurResult|=m_StartSide[cur.x][cur.z]; + m_NearestHole = m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1; + LOG_FLUID("Hole found: %d \t curResult: %d", int(m_StartSide[cur.x][cur.z]), int(m_CurResult) ); + LOG_FLUID("Coordinates: (%d, %d)", cur.x, cur.z); + }break; + + case E_BLOCK: + {}break; + + case E_PLAIN: + { + if (m_WayLength[cur.x][cur.z] > m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1) + { + m_WayLength[cur.x][cur.z] = m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1; + m_StartSide[cur.x][cur.z] = m_StartSide[a_CurBlock.x][a_CurBlock.z]; + m_WaveQueue.push(cur); + } + else if(m_WayLength[cur.x][cur.z] == m_WayLength[a_CurBlock.x][a_CurBlock.z] + 1) + { + m_StartSide[cur.x][cur.z] |= m_StartSide[a_CurBlock.x][a_CurBlock.z]; + } + LOG_FLUID("Plain step: (%d, %d) from %d", cur.x, cur.z, m_StartSide[cur.x][cur.z]); + } + } + } + } + + std::vector< Vector3i > GetLowestPoints( int a_X, int a_Y, int a_Z ) + { + + std::vector< Vector3i > Points; //result + + Vector3i CornerGlobal(a_X - AREA_WIDTH/2, a_Y, a_Z - AREA_WIDTH/2); + + //TODO: rewrite without relief, get blocks directly in algorithm + for(int x=0; x<AREA_WIDTH; x++) + { + for(int z=0; z<AREA_WIDTH; z++) + { + char UpperBlock = m_World->GetBlock( CornerGlobal.x + x, CornerGlobal.y, CornerGlobal.z + z ); + char DownBlock = m_World->GetBlock( CornerGlobal.x + x, CornerGlobal.y-1, CornerGlobal.z + z ); + + if(m_Simulator->IsSolidBlock(UpperBlock)||(m_Simulator->IsStationaryBlock(UpperBlock))) + { + m_Relief[x][z] = E_BLOCK; + } + else if(m_Simulator->IsSolidBlock(DownBlock)) + { + m_Relief[x][z] = E_PLAIN; + } + else + { + m_Relief[x][z] = E_HOLE; + } + m_WayLength[x][z] = 255; + m_StartSide[x][z] = E_SIDE_NONE; + } + LOG_FLUID("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t", m_Relief[x][0], m_Relief[x][1], m_Relief[x][2], m_Relief[x][3], m_Relief[x][4], m_Relief[x][5], m_Relief[x][6], m_Relief[x][7], m_Relief[x][8], m_Relief[x][9], m_Relief[x][10]); + } + + m_NearestHole = 5; + m_CurResult = 0; + while(!m_WaveQueue.empty()) m_WaveQueue.pop(); + + int left = AREA_WIDTH/2 - 1; + int right = AREA_WIDTH/2 + 1; + int center = AREA_WIDTH/2; + + Vector3i r(right, 0, center); //right block + Vector3i l(left, 0, center); //left block + Vector3i f(center, 0, right); //front block + Vector3i b(center, 0, left); //back block + Vector3i c(center, 0, center); //center block + + m_WayLength[c.x][c.z] = 0; + + Vector3i Nearest[] = {r, l, f, b}; + unsigned char Sides[] = {E_SIDE_RIGHT, E_SIDE_LEFT, E_SIDE_FRONT, E_SIDE_BACK}; + + for(int i=0; i<4; i++) + { + Vector3i cur = Nearest[i]; + switch(m_Relief[cur.x][cur.z]) + { + case E_HOLE: + { + m_StartSide[cur.x][cur.z] = Sides[i]; + m_CurResult |= m_StartSide[cur.x][cur.z]; + m_NearestHole = 1; + LOG_FLUID("Hole found: %d \t curResult: %d", int(Sides[i]), int(m_CurResult) ); + }break; + + case E_BLOCK: + {}break; + + case E_PLAIN: + { + m_WaveQueue.push(cur); + m_StartSide[cur.x][cur.z] = Sides[i]; + m_WayLength[cur.x][cur.z] = 1; + LOG_FLUID("Plain found: %d", int(Sides[i])); + } + } + } + + Vector3i curBlock; + + bool bContinue = !m_WaveQueue.empty(); + + if(!m_WaveQueue.empty()) + { + curBlock = m_WaveQueue.front(); + bContinue = (m_WayLength[curBlock.x][curBlock.z] < m_NearestHole); + } + + while(bContinue) + { + LOG_FLUID("while iteration" ); + curBlock = m_WaveQueue.front(); + UpdateWave(CornerGlobal, curBlock); + m_WaveQueue.pop(); + + bContinue = ( (!m_WaveQueue.empty()) && (m_WayLength[m_WaveQueue.front().x][m_WaveQueue.front().z] < m_NearestHole) ); + } + + + + if(m_CurResult & E_SIDE_LEFT) Points.push_back(Vector3i( a_X-1, a_Y, a_Z )); + if(m_CurResult & E_SIDE_RIGHT) Points.push_back(Vector3i( a_X+1, a_Y, a_Z )); + if(m_CurResult & E_SIDE_FRONT) Points.push_back(Vector3i( a_X, a_Y, a_Z+1 )); + if(m_CurResult & E_SIDE_BACK) Points.push_back(Vector3i( a_X, a_Y, a_Z-1 )); + + if(Points.empty()) + { + Vector3i LevelPoints [] = { + Vector3i( a_X-1, a_Y, a_Z ), + Vector3i( a_X+1, a_Y, a_Z ), + Vector3i( a_X, a_Y, a_Z-1 ), + Vector3i( a_X, a_Y, a_Z+1 ), + }; + for( int i = 0; i < 4; ++i ) + { + char Block = m_World->GetBlock( LevelPoints[i].x, a_Y, LevelPoints[i].z ); + if( m_Simulator->IsPassableForFluid(Block) ) + Points.push_back( LevelPoints[i] ); + } + } + + return Points; + } + + std::set< Vector3i >* m_ActiveFluid; + std::set< Vector3i >* m_Buffer; + cWorld* m_World; + cFluidSimulator *m_Simulator; + + const static int AREA_WIDTH = 11; + + const static unsigned char E_SIDE_RIGHT = 0x10; + const static unsigned char E_SIDE_LEFT = 0x20; + const static unsigned char E_SIDE_FRONT = 0x40; + const static unsigned char E_SIDE_BACK = 0x80; + const static unsigned char E_SIDE_NONE = 0x00; + + enum eRelief {E_HOLE = 0, E_PLAIN = 1, E_BLOCK = 2}; + + eRelief m_Relief[AREA_WIDTH][AREA_WIDTH]; + unsigned char m_WayLength[AREA_WIDTH][AREA_WIDTH]; + unsigned char m_StartSide[AREA_WIDTH][AREA_WIDTH]; + + std::queue<Vector3i> m_WaveQueue; + + int m_NearestHole; + unsigned char m_CurResult; +}; + + + + + +cFluidSimulator::cFluidSimulator( cWorld* a_World ) + : cSimulator(a_World) + , m_Data(0) +{ + m_Data = new FluidData(a_World, this); +} + + + + + +cFluidSimulator::~cFluidSimulator() +{ + delete m_Data; +} + + + + + +void cFluidSimulator::AddBlock( int a_X, int a_Y, int a_Z ) +{ + char BlockType = m_World->GetBlock(a_X, a_Y, a_Z); + if (!IsAllowedBlock(BlockType)) //This should save very much time because it doesn´t have to iterate through all blocks + { + return; + } + + std::set< Vector3i > & ActiveFluid = *m_Data->m_ActiveFluid; + ActiveFluid.insert( Vector3i( a_X, a_Y, a_Z ) ); +} + + + + + +char cFluidSimulator::GetHighestLevelAround( int a_X, int a_Y, int a_Z ) +{ + char Max = m_MaxHeight + m_FlowReduction; + +#define __HIGHLEVEL_CHECK__( x, y, z ) \ + if( IsAllowedBlock( m_World->GetBlock( x, y, z ) ) ) \ + { \ + char Meta; \ + if( (Meta = m_World->GetBlockMeta( x, y, z ) ) < Max ) Max = Meta; \ + else if( Meta == m_MaxHeight + m_FlowReduction ) Max = 0; \ + if( Max == 0 ) return 0; \ + } + + __HIGHLEVEL_CHECK__( a_X-1, a_Y, a_Z ); + __HIGHLEVEL_CHECK__( a_X+1, a_Y, a_Z ); + __HIGHLEVEL_CHECK__( a_X, a_Y, a_Z-1 ); + __HIGHLEVEL_CHECK__( a_X, a_Y, a_Z+1 ); + + return Max; +} + + + + + +void cFluidSimulator::Simulate( float a_Dt ) +{ + m_Timer += a_Dt; + + if (m_Data->m_ActiveFluid->empty()) //Nothing to do if there is no active fluid ;) saves very little time ;D + { + return; + } + + std::swap( m_Data->m_ActiveFluid, m_Data->m_Buffer ); // Swap so blocks can be added to empty ActiveFluid array + m_Data->m_ActiveFluid->clear(); + + std::set< Vector3i > & FluidBlocks = *m_Data->m_Buffer; + for( std::set< Vector3i >::iterator itr = FluidBlocks.begin(); itr != FluidBlocks.end(); ++itr ) + { + const Vector3i & pos = *itr; + + if(UniqueSituation(pos)) + { + continue; + } + + char BlockID = m_World->GetBlock( pos.x, pos.y, pos.z ); + if( IsAllowedBlock( BlockID ) ) // only care about own fluid + { + bool bIsFed = false; + char Meta = m_World->GetBlockMeta( pos.x, pos.y, pos.z ); + char Feed = Meta; + if( BlockID == m_StationaryFluidBlock) Meta = 0; + if( Meta == 8 ) // Falling fluid + { + if( IsAllowedBlock( m_World->GetBlock(pos.x, pos.y+1, pos.z) ) ) // Block above is fluid + { + bIsFed = true; + Meta = 0; // Make it a full block + } + } + else if( Meta < m_FlowReduction ) // It's a full block, so it's always fed + { + bIsFed = true; + } + else + { + if( (Feed = GetHighestLevelAround( pos.x, pos.y, pos.z )) < Meta ) + bIsFed = true; + } + + + if( bIsFed ) + { + char DownID = m_World->GetBlock( pos.x, pos.y-1, pos.z ); + bool bWashedAwayItem = CanWashAway( DownID ); + if( (IsPassableForFluid(DownID) || bWashedAwayItem) && !IsStationaryBlock(DownID) ) // free for fluid + { + if( bWashedAwayItem ) + { + cItems Drops; + cBlockToPickup::ToPickup(DownID, m_World->GetBlockMeta(pos.x, pos.y - 1, pos.z), E_ITEM_EMPTY, Drops); + m_World->SpawnItemPickups(Drops, pos.x, pos.y - 1, pos.z); + } + if (pos.y > 0) + { + m_World->FastSetBlock( pos.x, pos.y-1, pos.z, m_FluidBlock, 8 ); // falling + AddBlock( pos.x, pos.y-1, pos.z ); + ApplyUniqueToNearest(pos - Vector3i(0, 1, 0)); + } + } + if(IsSolidBlock(DownID)||( BlockID == m_StationaryFluidBlock)) // Not falling + { + if( Feed + m_FlowReduction < Meta ) + { + m_World->FastSetBlock( pos.x, pos.y, pos.z, m_FluidBlock, Feed + m_FlowReduction ); + AddBlock( pos.x, pos.y, pos.z ); + ApplyUniqueToNearest(pos); + } + else if(( Meta < m_MaxHeight )||( BlockID == m_StationaryFluidBlock)) // max is the lowest, so it cannot spread + { + std::vector< Vector3i > Points = m_Data->GetLowestPoints( pos.x, pos.y, pos.z ); + for( std::vector< Vector3i >::iterator itr = Points.begin(); itr != Points.end(); ++itr ) + { + Vector3i & p = *itr; + char BlockID = m_World->GetBlock( p.x, p.y, p.z ); + bool bWashedAwayItem = CanWashAway( BlockID ); + + if (!IsPassableForFluid(BlockID)) continue; + + if (!IsAllowedBlock(BlockID)) + { + if (bWashedAwayItem) + { + cItems Drops; + cBlockToPickup::ToPickup(DownID, m_World->GetBlockMeta(p.x, p.y, p.z), E_ITEM_EMPTY, Drops); + m_World->SpawnItemPickups(Drops, p.x, p.y, p.z); + } + + if( p.y == pos.y ) + { + m_World->FastSetBlock(p.x, p.y, p.z, m_FluidBlock, Meta + m_FlowReduction); + } + else + { + m_World->FastSetBlock(p.x, p.y, p.z, m_FluidBlock, 8); + } + AddBlock( p.x, p.y, p.z ); + ApplyUniqueToNearest(p); + } + else // it's fluid + { + char PointMeta = m_World->GetBlockMeta( p.x, p.y, p.z ); + if( PointMeta > Meta + m_FlowReduction ) + { + AddBlock( p.x, p.y, p.z ); + ApplyUniqueToNearest(p); + } + } + } + } + } + } + else// not fed + { + m_World->FastSetBlock( pos.x, pos.y, pos.z, E_BLOCK_AIR, 0 ); + WakeUp( pos.x, pos.y, pos.z ); + } + } + } +} + + + + + +bool cFluidSimulator::IsPassableForFluid(char a_BlockID) +{ + return a_BlockID == E_BLOCK_AIR + || a_BlockID == E_BLOCK_FIRE + || IsAllowedBlock(a_BlockID) + || CanWashAway(a_BlockID); +} + + + + + +bool cFluidSimulator::IsStationaryBlock (char a_BlockID) +{ + return a_BlockID == m_StationaryFluidBlock; +} + + + + + +bool cFluidSimulator::CanWashAway( char a_BlockID ) +{ + switch( a_BlockID ) + { + case E_BLOCK_YELLOW_FLOWER: + case E_BLOCK_RED_ROSE: + case E_BLOCK_RED_MUSHROOM: + case E_BLOCK_BROWN_MUSHROOM: + case E_BLOCK_CACTUS: + return true; + default: + return false; + }; +} + + + + + +bool cFluidSimulator::IsSolidBlock( char a_BlockID ) +{ + return !(a_BlockID == E_BLOCK_AIR + || a_BlockID == E_BLOCK_FIRE + || IsBlockLava(a_BlockID) + || IsBlockWater(a_BlockID) + || CanWashAway(a_BlockID)); +} + + + + + +//TODO Not working very well yet :s +Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over) +{ + char BlockID = m_World->GetBlock(a_X, a_Y, a_Z); + if(!IsAllowedBlock(BlockID)) //No Fluid -> No Flowing direction :D + return NONE; + + + /* + Disabled because of causing problems and beeing useless atm + char BlockBelow = m_World->GetBlock(a_X, a_Y - 1, a_Z); //If there is nothing or fluid below it -> dominating flow is down :D + if(BlockBelow == E_BLOCK_AIR || IsAllowedBlock(BlockBelow)) + return Y_MINUS; + */ + + char LowestPoint = m_World->GetBlockMeta(a_X, a_Y, a_Z); //Current Block Meta so only lower points will be counted + int X = 0, Y = 0, Z = 0; //Lowest Pos will be stored here + + if(IsAllowedBlock(m_World->GetBlock(a_X, a_Y + 1, a_Z)) && a_Over) //check for upper block to flow because this also affects the flowing direction + { + return GetFlowingDirection(a_X, a_Y + 1, a_Z, false); + } + + std::vector< Vector3i * > Points; + + Points.reserve(4); //Already allocate 4 places :D + + //add blocks around the checking pos + Points.push_back(new Vector3i(a_X - 1, a_Y, a_Z)); + Points.push_back(new Vector3i(a_X + 1, a_Y, a_Z)); + Points.push_back(new Vector3i(a_X, a_Y, a_Z + 1)); + Points.push_back(new Vector3i(a_X, a_Y, a_Z - 1)); + + for(std::vector<Vector3i *>::iterator it = Points.begin(); it < Points.end(); it++) + { + Vector3i *Pos = (*it); + char BlockID = m_World->GetBlock(Pos->x, Pos->y, Pos->z); + if(IsAllowedBlock(BlockID)) + { + char Meta = m_World->GetBlockMeta(Pos->x, Pos->y, Pos->z); + + if(Meta > LowestPoint) + { + LowestPoint = Meta; + X = Pos->x; + Y = Pos->y; + Z = Pos->z; + } + }else if(BlockID == E_BLOCK_AIR) + { + LowestPoint = 9; //This always dominates + X = Pos->x; + Y = Pos->y; + Z = Pos->z; + + } + delete Pos; + } + + if(LowestPoint == m_World->GetBlockMeta(a_X, a_Y, a_Z)) + return NONE; + + if(a_X - X > 0) + { + return X_MINUS; + } + + if(a_X - X < 0) + { + return X_PLUS; + } + + if(a_Z - Z > 0) + { + return Z_MINUS; + } + + if(a_Z - Z < 0) + { + return Z_PLUS; + } + + return NONE; +} + + + + + +bool cFluidSimulator::UniqueSituation(Vector3i a_Pos) +{ + bool result = false; + + char BlockId = m_World->GetBlock( a_Pos.x, a_Pos.y, a_Pos.z ); + char Meta = m_World->GetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z ); + + if(IsBlockWater(BlockId)) + { + + char UpperBlock = m_World->GetBlock( a_Pos.x, a_Pos.y + 1, a_Pos.z ); + if(IsBlockLava(UpperBlock)) + { + m_World->SetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_STONE, 0); + } + + + if(BlockId != E_BLOCK_STATIONARY_WATER) + { + char DownBlockId = m_World->GetBlock( a_Pos.x, a_Pos.y-1, a_Pos.z ); + if(IsSolidBlock(DownBlockId)) + { + Vector3i LevelPoints [] = { + Vector3i( a_Pos.x-1, a_Pos.y, a_Pos.z ), + Vector3i( a_Pos.x+1, a_Pos.y, a_Pos.z ), + Vector3i( a_Pos.x, a_Pos.y, a_Pos.z-1 ), + Vector3i( a_Pos.x, a_Pos.y, a_Pos.z+1 ), + }; + int SourceBlocksCount = 0; + for(int i=0; i<4; i++) + { + if (m_World->GetBlock(LevelPoints[i].x, LevelPoints[i].y, LevelPoints[i].z)==E_BLOCK_STATIONARY_WATER) + { + SourceBlocksCount++; + } + } + if(SourceBlocksCount>=2) + { + m_World->SetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_STATIONARY_WATER, 0); + } + } + + } + } + + if(IsBlockLava(BlockId)) + { + bool bWater = false; + + char UpperBlock = m_World->GetBlock( a_Pos.x, a_Pos.y + 1, a_Pos.z ); + if (IsBlockWater(UpperBlock)) + { + bWater = true; + } + else + { + Vector3i LevelPoints [] = { + Vector3i( a_Pos.x-1, a_Pos.y, a_Pos.z ), + Vector3i( a_Pos.x+1, a_Pos.y, a_Pos.z ), + Vector3i( a_Pos.x, a_Pos.y, a_Pos.z-1 ), + Vector3i( a_Pos.x, a_Pos.y, a_Pos.z+1 ), + }; + + for(int i=0; i<4; i++) + { + if (IsBlockWater(m_World->GetBlock(LevelPoints[i].x, LevelPoints[i].y, LevelPoints[i].z))) + { + bWater = true; + } + } + } + + + if(bWater) + { + if(BlockId == E_BLOCK_STATIONARY_LAVA) + { + m_World->SetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_OBSIDIAN, 0); + } + else if (Meta<m_MaxHeight) + { + m_World->SetBlock(a_Pos.x, a_Pos.y, a_Pos.z, E_BLOCK_COBBLESTONE, 0); + } + } + } + + return result; +} + + + + + +void cFluidSimulator::ApplyUniqueToNearest(Vector3i a_Pos) +{ + Vector3i NearPoints [] = { + Vector3i( a_Pos.x-1, a_Pos.y, a_Pos.z ), + Vector3i( a_Pos.x+1, a_Pos.y, a_Pos.z ), + Vector3i( a_Pos.x, a_Pos.y, a_Pos.z-1 ), + Vector3i( a_Pos.x, a_Pos.y, a_Pos.z+1 ), + Vector3i( a_Pos.x, a_Pos.y-1, a_Pos.z ) + }; + + for(int i=0; i<5; i++) + { + UniqueSituation(NearPoints[i]); + } +} + + + + diff --git a/source/cFluidSimulator.h b/source/cFluidSimulator.h index afacea5f7..4557d3ef1 100644 --- a/source/cFluidSimulator.h +++ b/source/cFluidSimulator.h @@ -1,55 +1,55 @@ -#pragma once
-
-#include "cSimulator.h"
-#include "Vector3i.h"
-
-
-//TODO This definitly needs a better naming :D but how?
-enum Direction
-{
- X_PLUS,
- X_MINUS,
- Y_PLUS,
- Y_MINUS,
- Z_PLUS,
- Z_MINUS,
- NONE
-};
-
-class Vector3i;
-class cWorld;
-class cFluidSimulator : public cSimulator
-{
-public:
- cFluidSimulator( cWorld* a_World );
- ~cFluidSimulator();
-
- virtual void Simulate( float a_Dt );
-
- //Gets the flowing direction. if a_Over is true also the block over the current block affects the direction (standard)
- Direction GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over = true);
-
- virtual bool IsAllowedBlock( char a_BlockID ) = 0;
- virtual bool IsStationaryBlock( char a_BlockID);
- virtual bool IsPassableForFluid( char a_BlockID );
- bool CanWashAway( char a_BlockID );
- bool IsSolidBlock(char a_BlockID);
-protected:
- virtual void AddBlock( int a_X, int a_Y, int a_Z);
- char GetHighestLevelAround( int a_X, int a_Y, int a_Z );
-
- bool UniqueSituation(Vector3i a_Pos); //Applys special for this fluid rules like generation of water betwin sources, returns false if it is necessary to apply general rules
- void ApplyUniqueToNearest(Vector3i a_Pos);
-
- float m_Timer;
-
- class FluidData;
- FluidData* m_Data;
-
- //Customize
- char m_FluidBlock;
- char m_StationaryFluidBlock;
- char m_MaxHeight;
- char m_FlowReduction;
-
+#pragma once + +#include "cSimulator.h" +#include "Vector3i.h" + + +//TODO This definitly needs a better naming :D but how? +enum Direction +{ + X_PLUS, + X_MINUS, + Y_PLUS, + Y_MINUS, + Z_PLUS, + Z_MINUS, + NONE +}; + +class Vector3i; +class cWorld; +class cFluidSimulator : public cSimulator +{ +public: + cFluidSimulator( cWorld* a_World ); + ~cFluidSimulator(); + + virtual void Simulate( float a_Dt ); + + //Gets the flowing direction. if a_Over is true also the block over the current block affects the direction (standard) + Direction GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over = true); + + virtual bool IsAllowedBlock( char a_BlockID ) = 0; + virtual bool IsStationaryBlock( char a_BlockID); + virtual bool IsPassableForFluid( char a_BlockID ); + bool CanWashAway( char a_BlockID ); + bool IsSolidBlock(char a_BlockID); +protected: + virtual void AddBlock( int a_X, int a_Y, int a_Z); + char GetHighestLevelAround( int a_X, int a_Y, int a_Z ); + + bool UniqueSituation(Vector3i a_Pos); //Applys special for this fluid rules like generation of water betwin sources, returns false if it is necessary to apply general rules + void ApplyUniqueToNearest(Vector3i a_Pos); + + float m_Timer; + + class FluidData; + FluidData* m_Data; + + //Customize + char m_FluidBlock; + char m_StationaryFluidBlock; + char m_MaxHeight; + char m_FlowReduction; + };
\ No newline at end of file diff --git a/source/cFurnaceEntity.cpp b/source/cFurnaceEntity.cpp index 925682590..f127e05e8 100644 --- a/source/cFurnaceEntity.cpp +++ b/source/cFurnaceEntity.cpp @@ -1,401 +1,401 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cFurnaceEntity.h"
-#include "BlockID.h"
-#include "cItem.h"
-#include "cFurnaceWindow.h"
-#include "cPlayer.h"
-#include "cWorld.h"
-#include "cClientHandle.h"
-#include "cFurnaceRecipe.h"
-#include "cServer.h"
-#include "cPickup.h"
-#include "cRoot.h"
-
-#include "packets/cPacket_InventoryProgressBar.h"
-
-#include <json/json.h>
-
-
-
-
-
-cFurnaceEntity::cFurnaceEntity(int a_X, int a_Y, int a_Z, cWorld * a_World)
- : cBlockEntity( E_BLOCK_FURNACE, a_X, a_Y, a_Z, a_World )
- , m_Items( new cItem[3] )
- , m_CookingItem( 0 )
- , m_CookTime( 0 )
- , m_TimeCooked( 0 )
- , m_BurnTime( 0 )
- , m_TimeBurned( 0 )
-{
-}
-
-
-
-
-
-cFurnaceEntity::~cFurnaceEntity()
-{
- // Tell window its owner is destroyed
- if( GetWindow() )
- {
- GetWindow()->OwnerDestroyed();
- }
-
- // Clean up items
- if( m_Items )
- {
- delete [] m_Items;
- }
-}
-
-
-
-
-
-void cFurnaceEntity::Destroy()
-{
- // Drop items
- cItems Pickups;
- for( int i = 0; i < 3; i++)
- {
- if( !m_Items[i].IsEmpty() )
- {
- Pickups.push_back(m_Items[i]);
- m_Items[i].Empty();
- }
- }
- m_World->SpawnItemPickups(Pickups, m_PosX, m_PosY, m_PosZ);
-}
-
-
-
-
-
-void cFurnaceEntity::UsedBy( cPlayer * a_Player )
-{
- LOG("Used a furnace");
-
- if( !GetWindow() )
- {
- cWindow* Window = new cFurnaceWindow( this );
- Window->SetSlots( m_Items, 3 );
- Window->SetWindowTitle("UberFurnace");
- Window->GetOwner()->SetEntity(this);
- OpenWindow( Window );
- }
- if( GetWindow() )
- {
- if( a_Player->GetWindow() != GetWindow() )
- {
- a_Player->OpenWindow( GetWindow() );
-
- GetWindow()->SendWholeWindow( a_Player->GetClientHandle() );
- }
- }
-}
-
-
-
-
-
-bool cFurnaceEntity::Tick( float a_Dt )
-{
- /*
- // DEBUG:
- Int16 BurnTime = (Int16)(GetTimeToBurn() / 50.0);
- Int16 CookTime = (Int16)(GetTimeCooked() / 50.0);
- LOGD("Furnace: BurnTime %d, CookTime %d", BurnTime, CookTime);
- */
-
- if (m_BurnTime <= 0)
- {
- // There is no fuel and no flame, no need to tick at all
- return false;
- }
-
- // DEBUG: LOGD("Furnace: Left: %0.1f Burned: %0.1f Burn time: %0.1f", m_CookTime - m_TimeCooked, m_TimeBurned, m_BurnTime );
-
- if ((m_CookingItem != NULL) && ((m_TimeBurned < m_BurnTime) || (m_TimeCooked + a_Dt >= m_CookTime)))
- {
- if (m_CookingItem->Equals(m_Items[2]) || m_Items[2].IsEmpty())
- {
- m_TimeCooked += a_Dt;
- if ( m_TimeCooked >= m_CookTime )
- {
- m_Items[0].m_ItemCount--;
- if( m_Items[0].IsEmpty() ) m_Items[0].Empty();
-
- m_Items[2].m_ItemHealth = m_CookingItem->m_ItemHealth;
- m_Items[2].m_ItemID = m_CookingItem->m_ItemID;
- m_Items[2].m_ItemCount += m_CookingItem->m_ItemCount;
- delete m_CookingItem;
- m_CookingItem = NULL;
-
- cWindow * Window = GetWindow();
- if (Window != NULL)
- {
- Window->BroadcastWholeWindow();
- }
-
- m_TimeCooked -= m_CookTime;
- StartCooking();
- }
- cWindow * Window = GetWindow();
- if (Window != NULL)
- {
- cPacket_InventoryProgressBar Progress;
- Progress.m_ProgressBar = 0;
- Progress.m_WindowID = (char)Window->GetWindowID();
- Progress.m_Value = (short)( m_TimeCooked * (180.f / m_CookTime) );
- if (Progress.m_Value > 180) Progress.m_Value = 180;
- if (Progress.m_Value < 0) Progress.m_Value = 0;
- Window->Broadcast(Progress);
- }
- }
- }
-
- m_TimeBurned += a_Dt;
-
- cWindow * Window = GetWindow();
- if (m_TimeBurned >= m_BurnTime)
- {
- m_TimeBurned -= m_BurnTime;
- m_BurnTime = 0;
- if (StartCooking() && (Window != NULL))
- {
- Window->BroadcastWholeWindow();
- }
- }
- if (Window != NULL)
- {
- cPacket_InventoryProgressBar Progress;
- Progress.m_WindowID = (char)Window->GetWindowID();
- Progress.m_ProgressBar = 1;
-
- if (m_BurnTime > 0.f)
- {
- Progress.m_Value = 250 - (short)( m_TimeBurned * (250.f / m_BurnTime) );
- if (Progress.m_Value > 250) Progress.m_Value = 250;
- if (Progress.m_Value < 0) Progress.m_Value = 0;
- }
- else
- {
- Progress.m_Value = 0;
- }
- Window->Broadcast(Progress);
- }
- return ((m_CookingItem != NULL) || (m_TimeBurned < m_BurnTime)) && (m_BurnTime > 0.0); // Keep on ticking, if there's more to cook, or if it's cooking
-}
-
-
-
-
-
-bool cFurnaceEntity::StartCooking(void)
-{
- cFurnaceRecipe* FR = cRoot::Get()->GetFurnaceRecipe();
- float BurnTime = FR->GetBurnTime( m_Items[1] );
- if( (m_TimeBurned < m_BurnTime) || BurnTime > 0.f ) // burnable material
- {
- const cFurnaceRecipe::Recipe* R = FR->GetRecipeFrom( m_Items[0] );
- if( R ) // cook able ingredient
- {
- if( m_Items[2].Equals( *R->Out ) || m_Items[2].IsEmpty() )
- {
- // good to go
-
- if( m_TimeBurned >= m_BurnTime ) // burn new material
- {
- m_Items[1].m_ItemCount--;
- if( m_Items[1].m_ItemCount <= 0 ) m_Items[1].Empty();
- m_TimeBurned = 0;
- m_BurnTime = BurnTime;
- }
-
- if( !m_CookingItem ) // Only cook new item if not already cooking
- {
- m_CookingItem = new cItem( *R->Out ); // Resulting item
- m_TimeCooked = 0.f;
- m_CookTime = R->CookTime;
- }
- return true;
- }
- }
- }
- return false;
-}
-
-
-
-
-
-bool cFurnaceEntity::ContinueCooking(void)
-{
- cFurnaceRecipe * FR = cRoot::Get()->GetFurnaceRecipe();
- float BurnTime = FR->GetBurnTime( m_Items[1] );
- if( (m_TimeBurned < m_BurnTime) || BurnTime > 0.f ) // burnable material
- {
- const cFurnaceRecipe::Recipe * R = FR->GetRecipeFrom( m_Items[0] );
- if (R != NULL) // cook able ingredient
- {
- if (m_Items[2].Equals(*R->Out) || m_Items[2].IsEmpty())
- {
- // good to go
- if (m_CookingItem == NULL) // Only cook new item if not already cooking
- {
- m_CookingItem = new cItem( *R->Out ); // Resulting item
- }
- return true;
- }
- }
- }
- return false;
-}
-
-
-
-
-
-void cFurnaceEntity::ResetCookTimer()
-{
- delete m_CookingItem;
- m_CookingItem = NULL;
- m_TimeCooked = 0.f;
- m_CookTime = 0.f;
-}
-
-
-
-
-
-void cFurnaceEntity::SetSlot(int a_Slot, const cItem & a_Item)
-{
- if ((a_Slot < 0) || (a_Slot >= 3))
- {
- ASSERT(!"Furnace: slot number out of range");
- return;
- }
- m_Items[a_Slot] = a_Item;
-}
-
-
-
-
-
-#define READ(File, Var) \
- if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \
- { \
- LOGERROR("ERROR READING cFurnaceEntity %s FROM FILE (line %d)", #Var, __LINE__); \
- return false; \
- }
-
-bool cFurnaceEntity::LoadFromFile(cFile & f)
-{
- READ(f, m_PosX);
- READ(f, m_PosY);
- READ(f, m_PosZ);
-
- unsigned int NumSlots = 0;
- READ(f, NumSlots);
- m_Items = new cItem[ NumSlots ];
- for(unsigned int i = 0; i < NumSlots; i++)
- {
- cItem & Item = m_Items[i];
- READ(f, Item.m_ItemID);
- READ(f, Item.m_ItemCount);
- READ(f, Item.m_ItemHealth);
- }
- cItem CookingItem;
- READ(f, CookingItem.m_ItemID);
- READ(f, CookingItem.m_ItemCount);
- READ(f, CookingItem.m_ItemHealth);
- if (!CookingItem.IsEmpty())
- {
- m_CookingItem = new cItem(CookingItem);
- }
-
- READ(f, m_CookTime);
- READ(f, m_TimeCooked);
- READ(f, m_BurnTime);
- READ(f, m_TimeBurned);
-
- return true;
-}
-
-
-
-
-
-bool cFurnaceEntity::LoadFromJson( const Json::Value& a_Value )
-{
- m_PosX = a_Value.get("x", 0).asInt();
- m_PosY = a_Value.get("y", 0).asInt();
- m_PosZ = a_Value.get("z", 0).asInt();
-
- Json::Value AllSlots = a_Value.get("Slots", 0);
- int SlotIdx = 0;
- for( Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr )
- {
- m_Items[ SlotIdx ].FromJson( *itr );
- SlotIdx++;
- }
-
- // Get currently cooking item
- Json::Value JsonItem = a_Value.get("Cooking", Json::nullValue );
- if( !JsonItem.empty() )
- {
- cItem Item;
- Item.FromJson( JsonItem );
- if( !Item.IsEmpty() )
- {
- m_CookingItem = new cItem( Item );
- }
- }
-
- m_CookTime = (float)a_Value.get("CookTime", 0).asDouble();
- m_TimeCooked = (float)a_Value.get("TimeCooked", 0).asDouble();
- m_BurnTime = (float)a_Value.get("BurnTime", 0).asDouble();
- m_TimeBurned = (float)a_Value.get("TimeBurned", 0).asDouble();
-
- return true;
-}
-
-
-
-
-
-void cFurnaceEntity::SaveToJson( Json::Value& a_Value )
-{
- a_Value["x"] = m_PosX;
- a_Value["y"] = m_PosY;
- a_Value["z"] = m_PosZ;
-
- Json::Value AllSlots;
- for(unsigned int i = 0; i < 3; i++)
- {
- Json::Value Slot;
- m_Items[ i ].GetJson( Slot );
- AllSlots.append( Slot );
- }
- a_Value["Slots"] = AllSlots;
-
- // Currently cooking item
- if( m_CookingItem )
- {
- Json::Value JsonItem;
- m_CookingItem->GetJson( JsonItem );
- a_Value["Cooking"] = JsonItem;
- }
-
- a_Value["CookTime"] = m_CookTime;
- a_Value["TimeCooked"] = m_TimeCooked;
- a_Value["BurnTime"] = m_BurnTime;
- a_Value["TimeBurned"] = m_TimeBurned;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cFurnaceEntity.h" +#include "BlockID.h" +#include "cItem.h" +#include "cFurnaceWindow.h" +#include "cPlayer.h" +#include "cWorld.h" +#include "cClientHandle.h" +#include "cFurnaceRecipe.h" +#include "cServer.h" +#include "cPickup.h" +#include "cRoot.h" + +#include "packets/cPacket_InventoryProgressBar.h" + +#include <json/json.h> + + + + + +cFurnaceEntity::cFurnaceEntity(int a_X, int a_Y, int a_Z, cWorld * a_World) + : cBlockEntity( E_BLOCK_FURNACE, a_X, a_Y, a_Z, a_World ) + , m_Items( new cItem[3] ) + , m_CookingItem( 0 ) + , m_CookTime( 0 ) + , m_TimeCooked( 0 ) + , m_BurnTime( 0 ) + , m_TimeBurned( 0 ) +{ +} + + + + + +cFurnaceEntity::~cFurnaceEntity() +{ + // Tell window its owner is destroyed + if( GetWindow() ) + { + GetWindow()->OwnerDestroyed(); + } + + // Clean up items + if( m_Items ) + { + delete [] m_Items; + } +} + + + + + +void cFurnaceEntity::Destroy() +{ + // Drop items + cItems Pickups; + for( int i = 0; i < 3; i++) + { + if( !m_Items[i].IsEmpty() ) + { + Pickups.push_back(m_Items[i]); + m_Items[i].Empty(); + } + } + m_World->SpawnItemPickups(Pickups, m_PosX, m_PosY, m_PosZ); +} + + + + + +void cFurnaceEntity::UsedBy( cPlayer * a_Player ) +{ + LOG("Used a furnace"); + + if( !GetWindow() ) + { + cWindow* Window = new cFurnaceWindow( this ); + Window->SetSlots( m_Items, 3 ); + Window->SetWindowTitle("UberFurnace"); + Window->GetOwner()->SetEntity(this); + OpenWindow( Window ); + } + if( GetWindow() ) + { + if( a_Player->GetWindow() != GetWindow() ) + { + a_Player->OpenWindow( GetWindow() ); + + GetWindow()->SendWholeWindow( a_Player->GetClientHandle() ); + } + } +} + + + + + +bool cFurnaceEntity::Tick( float a_Dt ) +{ + /* + // DEBUG: + Int16 BurnTime = (Int16)(GetTimeToBurn() / 50.0); + Int16 CookTime = (Int16)(GetTimeCooked() / 50.0); + LOGD("Furnace: BurnTime %d, CookTime %d", BurnTime, CookTime); + */ + + if (m_BurnTime <= 0) + { + // There is no fuel and no flame, no need to tick at all + return false; + } + + // DEBUG: LOGD("Furnace: Left: %0.1f Burned: %0.1f Burn time: %0.1f", m_CookTime - m_TimeCooked, m_TimeBurned, m_BurnTime ); + + if ((m_CookingItem != NULL) && ((m_TimeBurned < m_BurnTime) || (m_TimeCooked + a_Dt >= m_CookTime))) + { + if (m_CookingItem->Equals(m_Items[2]) || m_Items[2].IsEmpty()) + { + m_TimeCooked += a_Dt; + if ( m_TimeCooked >= m_CookTime ) + { + m_Items[0].m_ItemCount--; + if( m_Items[0].IsEmpty() ) m_Items[0].Empty(); + + m_Items[2].m_ItemHealth = m_CookingItem->m_ItemHealth; + m_Items[2].m_ItemID = m_CookingItem->m_ItemID; + m_Items[2].m_ItemCount += m_CookingItem->m_ItemCount; + delete m_CookingItem; + m_CookingItem = NULL; + + cWindow * Window = GetWindow(); + if (Window != NULL) + { + Window->BroadcastWholeWindow(); + } + + m_TimeCooked -= m_CookTime; + StartCooking(); + } + cWindow * Window = GetWindow(); + if (Window != NULL) + { + cPacket_InventoryProgressBar Progress; + Progress.m_ProgressBar = 0; + Progress.m_WindowID = (char)Window->GetWindowID(); + Progress.m_Value = (short)( m_TimeCooked * (180.f / m_CookTime) ); + if (Progress.m_Value > 180) Progress.m_Value = 180; + if (Progress.m_Value < 0) Progress.m_Value = 0; + Window->Broadcast(Progress); + } + } + } + + m_TimeBurned += a_Dt; + + cWindow * Window = GetWindow(); + if (m_TimeBurned >= m_BurnTime) + { + m_TimeBurned -= m_BurnTime; + m_BurnTime = 0; + if (StartCooking() && (Window != NULL)) + { + Window->BroadcastWholeWindow(); + } + } + if (Window != NULL) + { + cPacket_InventoryProgressBar Progress; + Progress.m_WindowID = (char)Window->GetWindowID(); + Progress.m_ProgressBar = 1; + + if (m_BurnTime > 0.f) + { + Progress.m_Value = 250 - (short)( m_TimeBurned * (250.f / m_BurnTime) ); + if (Progress.m_Value > 250) Progress.m_Value = 250; + if (Progress.m_Value < 0) Progress.m_Value = 0; + } + else + { + Progress.m_Value = 0; + } + Window->Broadcast(Progress); + } + return ((m_CookingItem != NULL) || (m_TimeBurned < m_BurnTime)) && (m_BurnTime > 0.0); // Keep on ticking, if there's more to cook, or if it's cooking +} + + + + + +bool cFurnaceEntity::StartCooking(void) +{ + cFurnaceRecipe* FR = cRoot::Get()->GetFurnaceRecipe(); + float BurnTime = FR->GetBurnTime( m_Items[1] ); + if( (m_TimeBurned < m_BurnTime) || BurnTime > 0.f ) // burnable material + { + const cFurnaceRecipe::Recipe* R = FR->GetRecipeFrom( m_Items[0] ); + if( R ) // cook able ingredient + { + if( m_Items[2].Equals( *R->Out ) || m_Items[2].IsEmpty() ) + { + // good to go + + if( m_TimeBurned >= m_BurnTime ) // burn new material + { + m_Items[1].m_ItemCount--; + if( m_Items[1].m_ItemCount <= 0 ) m_Items[1].Empty(); + m_TimeBurned = 0; + m_BurnTime = BurnTime; + } + + if( !m_CookingItem ) // Only cook new item if not already cooking + { + m_CookingItem = new cItem( *R->Out ); // Resulting item + m_TimeCooked = 0.f; + m_CookTime = R->CookTime; + } + return true; + } + } + } + return false; +} + + + + + +bool cFurnaceEntity::ContinueCooking(void) +{ + cFurnaceRecipe * FR = cRoot::Get()->GetFurnaceRecipe(); + float BurnTime = FR->GetBurnTime( m_Items[1] ); + if( (m_TimeBurned < m_BurnTime) || BurnTime > 0.f ) // burnable material + { + const cFurnaceRecipe::Recipe * R = FR->GetRecipeFrom( m_Items[0] ); + if (R != NULL) // cook able ingredient + { + if (m_Items[2].Equals(*R->Out) || m_Items[2].IsEmpty()) + { + // good to go + if (m_CookingItem == NULL) // Only cook new item if not already cooking + { + m_CookingItem = new cItem( *R->Out ); // Resulting item + } + return true; + } + } + } + return false; +} + + + + + +void cFurnaceEntity::ResetCookTimer() +{ + delete m_CookingItem; + m_CookingItem = NULL; + m_TimeCooked = 0.f; + m_CookTime = 0.f; +} + + + + + +void cFurnaceEntity::SetSlot(int a_Slot, const cItem & a_Item) +{ + if ((a_Slot < 0) || (a_Slot >= 3)) + { + ASSERT(!"Furnace: slot number out of range"); + return; + } + m_Items[a_Slot] = a_Item; +} + + + + + +#define READ(File, Var) \ + if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("ERROR READING cFurnaceEntity %s FROM FILE (line %d)", #Var, __LINE__); \ + return false; \ + } + +bool cFurnaceEntity::LoadFromFile(cFile & f) +{ + READ(f, m_PosX); + READ(f, m_PosY); + READ(f, m_PosZ); + + unsigned int NumSlots = 0; + READ(f, NumSlots); + m_Items = new cItem[ NumSlots ]; + for(unsigned int i = 0; i < NumSlots; i++) + { + cItem & Item = m_Items[i]; + READ(f, Item.m_ItemID); + READ(f, Item.m_ItemCount); + READ(f, Item.m_ItemHealth); + } + cItem CookingItem; + READ(f, CookingItem.m_ItemID); + READ(f, CookingItem.m_ItemCount); + READ(f, CookingItem.m_ItemHealth); + if (!CookingItem.IsEmpty()) + { + m_CookingItem = new cItem(CookingItem); + } + + READ(f, m_CookTime); + READ(f, m_TimeCooked); + READ(f, m_BurnTime); + READ(f, m_TimeBurned); + + return true; +} + + + + + +bool cFurnaceEntity::LoadFromJson( const Json::Value& a_Value ) +{ + m_PosX = a_Value.get("x", 0).asInt(); + m_PosY = a_Value.get("y", 0).asInt(); + m_PosZ = a_Value.get("z", 0).asInt(); + + Json::Value AllSlots = a_Value.get("Slots", 0); + int SlotIdx = 0; + for( Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr ) + { + m_Items[ SlotIdx ].FromJson( *itr ); + SlotIdx++; + } + + // Get currently cooking item + Json::Value JsonItem = a_Value.get("Cooking", Json::nullValue ); + if( !JsonItem.empty() ) + { + cItem Item; + Item.FromJson( JsonItem ); + if( !Item.IsEmpty() ) + { + m_CookingItem = new cItem( Item ); + } + } + + m_CookTime = (float)a_Value.get("CookTime", 0).asDouble(); + m_TimeCooked = (float)a_Value.get("TimeCooked", 0).asDouble(); + m_BurnTime = (float)a_Value.get("BurnTime", 0).asDouble(); + m_TimeBurned = (float)a_Value.get("TimeBurned", 0).asDouble(); + + return true; +} + + + + + +void cFurnaceEntity::SaveToJson( Json::Value& a_Value ) +{ + a_Value["x"] = m_PosX; + a_Value["y"] = m_PosY; + a_Value["z"] = m_PosZ; + + Json::Value AllSlots; + for(unsigned int i = 0; i < 3; i++) + { + Json::Value Slot; + m_Items[ i ].GetJson( Slot ); + AllSlots.append( Slot ); + } + a_Value["Slots"] = AllSlots; + + // Currently cooking item + if( m_CookingItem ) + { + Json::Value JsonItem; + m_CookingItem->GetJson( JsonItem ); + a_Value["Cooking"] = JsonItem; + } + + a_Value["CookTime"] = m_CookTime; + a_Value["TimeCooked"] = m_TimeCooked; + a_Value["BurnTime"] = m_BurnTime; + a_Value["TimeBurned"] = m_TimeBurned; +} + + + + diff --git a/source/cFurnaceEntity.h b/source/cFurnaceEntity.h index 253990000..7fc090bee 100644 --- a/source/cFurnaceEntity.h +++ b/source/cFurnaceEntity.h @@ -1,74 +1,74 @@ -
-#pragma once
-
-#include "cBlockEntity.h"
-#include "cWindowOwner.h"
-#include "FileDefine.h"
-#include "cItem.h"
-
-
-
-
-
-namespace Json
-{
- class Value;
-}
-
-class cClientHandle;
-class cServer;
-
-
-
-
-class cFurnaceEntity :
- public cBlockEntity,
- public cWindowOwner
-{
-public:
- cFurnaceEntity(int a_X, int a_Y, int a_Z, cWorld * a_World);
- virtual ~cFurnaceEntity();
- virtual void Destroy();
-
- bool LoadFromFile(cFile & a_File); // deprecated format
-
- bool LoadFromJson(const Json::Value& a_Value );
- virtual void SaveToJson(Json::Value& a_Value ) override;
-
- // Returns true if there's any change, forcing the chunk to go dirty.
- bool Tick( float a_Dt );
-
- virtual void UsedBy( cPlayer * a_Player ) override;
-
- bool StartCooking();
-
- /// Restarts cooking. Used after the furnace is loaded from storage to set up the internal variables so that cooking continues, if it was active. Returns true if cooking.
- bool ContinueCooking(void);
-
- void ResetCookTimer();
-
- const cItem & GetSlot(int i) const { return m_Items[i]; }
-
- void SetSlot(int a_Slot, const cItem & a_Item);
-
- float GetTimeCooked(void) const {return m_TimeCooked; }
- float GetTimeToBurn(void) const {return m_BurnTime - m_TimeBurned; }
-
- void SetBurnTimes(float a_BurnTime, float a_TimeBurned) {m_BurnTime = a_BurnTime; m_TimeBurned = 0; }
- void SetCookTimes(float a_CookTime, float a_TimeCooked) {m_CookTime = a_CookTime; m_TimeCooked = a_TimeCooked; }
-
-private:
-
- cItem * m_Items;
- cItem * m_CookingItem;
-
- // All timers are in 1 ms
- float m_CookTime; // Amount of time needed to fully cook current item
- float m_TimeCooked; // Amount of time that the current item has been cooking
- float m_BurnTime; // Amount of time that the current fuel can burn (in total); zero if no fuel burning
- float m_TimeBurned; // Amount of time that the current fuel has been burning
-};
-
-
-
-
+ +#pragma once + +#include "cBlockEntity.h" +#include "cWindowOwner.h" +#include "FileDefine.h" +#include "cItem.h" + + + + + +namespace Json +{ + class Value; +} + +class cClientHandle; +class cServer; + + + + +class cFurnaceEntity : + public cBlockEntity, + public cWindowOwner +{ +public: + cFurnaceEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); + virtual ~cFurnaceEntity(); + virtual void Destroy(); + + bool LoadFromFile(cFile & a_File); // deprecated format + + bool LoadFromJson(const Json::Value& a_Value ); + virtual void SaveToJson(Json::Value& a_Value ) override; + + // Returns true if there's any change, forcing the chunk to go dirty. + bool Tick( float a_Dt ); + + virtual void UsedBy( cPlayer * a_Player ) override; + + bool StartCooking(); + + /// Restarts cooking. Used after the furnace is loaded from storage to set up the internal variables so that cooking continues, if it was active. Returns true if cooking. + bool ContinueCooking(void); + + void ResetCookTimer(); + + const cItem & GetSlot(int i) const { return m_Items[i]; } + + void SetSlot(int a_Slot, const cItem & a_Item); + + float GetTimeCooked(void) const {return m_TimeCooked; } + float GetTimeToBurn(void) const {return m_BurnTime - m_TimeBurned; } + + void SetBurnTimes(float a_BurnTime, float a_TimeBurned) {m_BurnTime = a_BurnTime; m_TimeBurned = 0; } + void SetCookTimes(float a_CookTime, float a_TimeCooked) {m_CookTime = a_CookTime; m_TimeCooked = a_TimeCooked; } + +private: + + cItem * m_Items; + cItem * m_CookingItem; + + // All timers are in 1 ms + float m_CookTime; // Amount of time needed to fully cook current item + float m_TimeCooked; // Amount of time that the current item has been cooking + float m_BurnTime; // Amount of time that the current fuel can burn (in total); zero if no fuel burning + float m_TimeBurned; // Amount of time that the current fuel has been burning +}; + + + + diff --git a/source/cFurnaceRecipe.cpp b/source/cFurnaceRecipe.cpp index b17ec51cd..3f6416d92 100644 --- a/source/cFurnaceRecipe.cpp +++ b/source/cFurnaceRecipe.cpp @@ -1,241 +1,241 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cFurnaceRecipe.h"
-#include "cItem.h"
-
-#include <fstream>
-#include <sstream>
-
-
-
-
-
-typedef std::list< cFurnaceRecipe::Recipe > RecipeList;
-typedef std::list< cFurnaceRecipe::Fuel > FuelList;
-
-
-
-
-
-struct cFurnaceRecipe::sFurnaceRecipeState
-{
- RecipeList Recipes;
- FuelList Fuel;
-};
-
-
-
-
-
-cFurnaceRecipe::cFurnaceRecipe()
- : m_pState( new sFurnaceRecipeState )
-{
- ReloadRecipes();
-}
-
-
-
-
-
-cFurnaceRecipe::~cFurnaceRecipe()
-{
- ClearRecipes();
- delete m_pState;
-}
-
-
-
-
-
-void cFurnaceRecipe::ReloadRecipes()
-{
- ClearRecipes();
- LOG("-- Loading furnace recipes --");
-
- std::ifstream f;
- char a_File[] = "furnace.txt";
- f.open(a_File, std::ios::in);
- std::string input;
-
- if( !f.good() )
- {
- f.close();
- LOG("Could not open file for recipes: %s", a_File);
- return;
- }
-
- bool bSyntaxError = false;
- while( f.good() )
- {
- char c;
-
- //////////////////////////////////////////////////////////////////////////
- // comments
- f >> c;
- f.unget();
- if( c == '#' )
- {
- while( f.good() && c != '\n' )
- {
- f.get( c );
- }
- 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;
- }
-
- // Burn time
- float BurnTime;
- f >> c; if( c != '=' ) { bSyntaxError = true; break; }
- f >> BurnTime;
-
- // Add to fuel list
- Fuel F;
- F.In = new cItem( (ENUM_ITEM_ID) IItemID, (char)IItemCount, (short)IItemHealth );
- F.BurnTime = BurnTime;
- m_pState->Fuel.push_back( F );
- continue;
- }
- f.unget();
-
- //////////////////////////////////////////////////////////////////////////
- // 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;
- }
-
- float 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("Got %i furnace recipes, and %i fuels.", m_pState->Recipes.size(), m_pState->Fuel.size() );
-
- LOG("-- Done loading furnace recipes --");
-}
-
-
-
-
-
-void cFurnaceRecipe::ClearRecipes()
-{
- for( RecipeList::iterator itr = m_pState->Recipes.begin(); itr != m_pState->Recipes.end(); ++itr )
- {
- Recipe R = *itr;
- delete R.In;
- delete R.Out;
- }
- m_pState->Recipes.clear();
-
- for( FuelList::iterator itr = m_pState->Fuel.begin(); itr != m_pState->Fuel.end(); ++itr )
- {
- Fuel F = *itr;
- delete F.In;
- }
- m_pState->Fuel.clear();
-}
-
-const cFurnaceRecipe::Recipe* cFurnaceRecipe::GetRecipeFrom( const cItem & a_Ingredient ) const
-{
- const Recipe* BestRecipe = 0;
- for( RecipeList::const_iterator itr = m_pState->Recipes.begin(); itr != m_pState->Recipes.end(); ++itr )
- {
- const Recipe & R = *itr;
- if( (R.In->m_ItemID == a_Ingredient.m_ItemID) && (R.In->m_ItemCount <= a_Ingredient.m_ItemCount ) )
- {
- if( BestRecipe && (BestRecipe->In->m_ItemCount > R.In->m_ItemCount) )
- {
- continue;
- }
- else
- {
- BestRecipe = &R;
- }
- }
- }
- return BestRecipe;
-}
-
-float cFurnaceRecipe::GetBurnTime( const cItem & a_Fuel ) const
-{
- float BestFuel = 0.f;
- for( FuelList::const_iterator itr = m_pState->Fuel.begin(); itr != m_pState->Fuel.end(); ++itr )
- {
- const Fuel & F = *itr;
- if( (F.In->m_ItemID == a_Fuel.m_ItemID) && (F.In->m_ItemCount <= a_Fuel.m_ItemCount ) )
- {
- if( BestFuel > 0.f && (BestFuel > F.BurnTime ) )
- {
- continue;
- }
- else
- {
- BestFuel = F.BurnTime;
- }
- }
- }
- return BestFuel;
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cFurnaceRecipe.h" +#include "cItem.h" + +#include <fstream> +#include <sstream> + + + + + +typedef std::list< cFurnaceRecipe::Recipe > RecipeList; +typedef std::list< cFurnaceRecipe::Fuel > FuelList; + + + + + +struct cFurnaceRecipe::sFurnaceRecipeState +{ + RecipeList Recipes; + FuelList Fuel; +}; + + + + + +cFurnaceRecipe::cFurnaceRecipe() + : m_pState( new sFurnaceRecipeState ) +{ + ReloadRecipes(); +} + + + + + +cFurnaceRecipe::~cFurnaceRecipe() +{ + ClearRecipes(); + delete m_pState; +} + + + + + +void cFurnaceRecipe::ReloadRecipes() +{ + ClearRecipes(); + LOG("-- Loading furnace recipes --"); + + std::ifstream f; + char a_File[] = "furnace.txt"; + f.open(a_File, std::ios::in); + std::string input; + + if( !f.good() ) + { + f.close(); + LOG("Could not open file for recipes: %s", a_File); + return; + } + + bool bSyntaxError = false; + while( f.good() ) + { + char c; + + ////////////////////////////////////////////////////////////////////////// + // comments + f >> c; + f.unget(); + if( c == '#' ) + { + while( f.good() && c != '\n' ) + { + f.get( c ); + } + 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; + } + + // Burn time + float BurnTime; + f >> c; if( c != '=' ) { bSyntaxError = true; break; } + f >> BurnTime; + + // Add to fuel list + Fuel F; + F.In = new cItem( (ENUM_ITEM_ID) IItemID, (char)IItemCount, (short)IItemHealth ); + F.BurnTime = BurnTime; + m_pState->Fuel.push_back( F ); + continue; + } + f.unget(); + + ////////////////////////////////////////////////////////////////////////// + // 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; + } + + float 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("Got %i furnace recipes, and %i fuels.", m_pState->Recipes.size(), m_pState->Fuel.size() ); + + LOG("-- Done loading furnace recipes --"); +} + + + + + +void cFurnaceRecipe::ClearRecipes() +{ + for( RecipeList::iterator itr = m_pState->Recipes.begin(); itr != m_pState->Recipes.end(); ++itr ) + { + Recipe R = *itr; + delete R.In; + delete R.Out; + } + m_pState->Recipes.clear(); + + for( FuelList::iterator itr = m_pState->Fuel.begin(); itr != m_pState->Fuel.end(); ++itr ) + { + Fuel F = *itr; + delete F.In; + } + m_pState->Fuel.clear(); +} + +const cFurnaceRecipe::Recipe* cFurnaceRecipe::GetRecipeFrom( const cItem & a_Ingredient ) const +{ + const Recipe* BestRecipe = 0; + for( RecipeList::const_iterator itr = m_pState->Recipes.begin(); itr != m_pState->Recipes.end(); ++itr ) + { + const Recipe & R = *itr; + if( (R.In->m_ItemID == a_Ingredient.m_ItemID) && (R.In->m_ItemCount <= a_Ingredient.m_ItemCount ) ) + { + if( BestRecipe && (BestRecipe->In->m_ItemCount > R.In->m_ItemCount) ) + { + continue; + } + else + { + BestRecipe = &R; + } + } + } + return BestRecipe; +} + +float cFurnaceRecipe::GetBurnTime( const cItem & a_Fuel ) const +{ + float BestFuel = 0.f; + for( FuelList::const_iterator itr = m_pState->Fuel.begin(); itr != m_pState->Fuel.end(); ++itr ) + { + const Fuel & F = *itr; + if( (F.In->m_ItemID == a_Fuel.m_ItemID) && (F.In->m_ItemCount <= a_Fuel.m_ItemCount ) ) + { + if( BestFuel > 0.f && (BestFuel > F.BurnTime ) ) + { + continue; + } + else + { + BestFuel = F.BurnTime; + } + } + } + return BestFuel; }
\ No newline at end of file diff --git a/source/cFurnaceRecipe.h b/source/cFurnaceRecipe.h index 75e569099..ccb008604 100644 --- a/source/cFurnaceRecipe.h +++ b/source/cFurnaceRecipe.h @@ -1,46 +1,46 @@ -
-#pragma once
-
-
-
-
-
-class cItem;
-
-
-
-
-
-class cFurnaceRecipe
-{
-public:
- cFurnaceRecipe();
- ~cFurnaceRecipe();
-
- void ReloadRecipes();
-
- struct Fuel
- {
- cItem* In;
- float BurnTime;
- };
-
- struct Recipe
- {
- cItem* In;
- cItem* Out;
- float CookTime;
- };
- const Recipe* GetRecipeFrom( const cItem & a_Ingredient ) const;
- float GetBurnTime( const cItem & a_Fuel ) const;
-
-private:
- void ClearRecipes();
-
- struct sFurnaceRecipeState;
- sFurnaceRecipeState* m_pState;
-};
-
-
-
-
+ +#pragma once + + + + + +class cItem; + + + + + +class cFurnaceRecipe +{ +public: + cFurnaceRecipe(); + ~cFurnaceRecipe(); + + void ReloadRecipes(); + + struct Fuel + { + cItem* In; + float BurnTime; + }; + + struct Recipe + { + cItem* In; + cItem* Out; + float CookTime; + }; + const Recipe* GetRecipeFrom( const cItem & a_Ingredient ) const; + float GetBurnTime( const cItem & a_Fuel ) const; + +private: + void ClearRecipes(); + + struct sFurnaceRecipeState; + sFurnaceRecipeState* m_pState; +}; + + + + diff --git a/source/cFurnaceWindow.cpp b/source/cFurnaceWindow.cpp index b76c53498..963c848ec 100644 --- a/source/cFurnaceWindow.cpp +++ b/source/cFurnaceWindow.cpp @@ -1,47 +1,47 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cFurnaceWindow.h"
-#include "cItem.h"
-#include "cFurnaceEntity.h"
-#include "cPlayer.h"
-
-#include "packets/cPacket_WindowClick.h"
-
-
-
-
-
-cFurnaceWindow::cFurnaceWindow( cFurnaceEntity* a_Owner )
- : cWindow( a_Owner, true )
- , m_Furnace( a_Owner )
-{
- SetWindowID( 1 );
- SetWindowType( cWindow::Furnace ); // Furnace
-}
-
-void cFurnaceWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player )
-{
- cItem Fuel = *GetSlot( 0 );
-
- cWindow::Clicked( a_ClickPacket, a_Player );
- if( m_Furnace )
- {
- if( a_ClickPacket->m_SlotNum >= 0 && a_ClickPacket->m_SlotNum <= 2 ) // them important slots
- {
- if( Fuel.m_ItemID != GetSlot( 0 )->m_ItemID )
- m_Furnace->ResetCookTimer();
-
- if( m_Furnace->StartCooking() )
- {
- SendWholeWindow( a_Player.GetClientHandle() );
- }
- }
- }
-}
-
-void cFurnaceWindow::Close( cPlayer & a_Player )
-{
- m_Furnace = 0;
- cWindow::Close( a_Player );
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cFurnaceWindow.h" +#include "cItem.h" +#include "cFurnaceEntity.h" +#include "cPlayer.h" + +#include "packets/cPacket_WindowClick.h" + + + + + +cFurnaceWindow::cFurnaceWindow( cFurnaceEntity* a_Owner ) + : cWindow( a_Owner, true ) + , m_Furnace( a_Owner ) +{ + SetWindowID( 1 ); + SetWindowType( cWindow::Furnace ); // Furnace +} + +void cFurnaceWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ) +{ + cItem Fuel = *GetSlot( 0 ); + + cWindow::Clicked( a_ClickPacket, a_Player ); + if( m_Furnace ) + { + if( a_ClickPacket->m_SlotNum >= 0 && a_ClickPacket->m_SlotNum <= 2 ) // them important slots + { + if( Fuel.m_ItemID != GetSlot( 0 )->m_ItemID ) + m_Furnace->ResetCookTimer(); + + if( m_Furnace->StartCooking() ) + { + SendWholeWindow( a_Player.GetClientHandle() ); + } + } + } +} + +void cFurnaceWindow::Close( cPlayer & a_Player ) +{ + m_Furnace = 0; + cWindow::Close( a_Player ); }
\ No newline at end of file diff --git a/source/cFurnaceWindow.h b/source/cFurnaceWindow.h index 8dd7d3223..f6ae36be5 100644 --- a/source/cFurnaceWindow.h +++ b/source/cFurnaceWindow.h @@ -1,16 +1,16 @@ -#pragma once
-
-#include "cWindow.h"
-
-class cFurnaceEntity;
-class cWindowOwner;
-class cFurnaceWindow : public cWindow
-{
-public:
- cFurnaceWindow( cFurnaceEntity* a_Owner );
-
- virtual void Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player );
- virtual void Close( cPlayer & a_Player );
-private:
- cFurnaceEntity* m_Furnace;
+#pragma once + +#include "cWindow.h" + +class cFurnaceEntity; +class cWindowOwner; +class cFurnaceWindow : public cWindow +{ +public: + cFurnaceWindow( cFurnaceEntity* a_Owner ); + + virtual void Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ); + virtual void Close( cPlayer & a_Player ); +private: + cFurnaceEntity* m_Furnace; };
\ No newline at end of file diff --git a/source/cGhast.cpp b/source/cGhast.cpp index c19753641..857c1c6fb 100644 --- a/source/cGhast.cpp +++ b/source/cGhast.cpp @@ -1,49 +1,49 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cGhast.h"
-
-
-
-
-
-cGhast::cGhast()
-{
- m_MobType = 56;
- GetMonsterConfig("Ghast");
-}
-
-
-
-
-
-cGhast::~cGhast()
-{
-}
-
-
-
-
-
-bool cGhast::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cGhast" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
-
-
-
-
-
-void cGhast::KilledBy( cEntity* a_Killer )
-{
- cItems Drops;
- AddRandomDropItem(Drops, 0, 2, E_ITEM_GUNPOWDER);
- AddRandomDropItem(Drops, 0, 1, E_ITEM_GHAST_TEAR);
-
- cMonster::KilledBy( a_Killer );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cGhast.h" + + + + + +cGhast::cGhast() +{ + m_MobType = 56; + GetMonsterConfig("Ghast"); +} + + + + + +cGhast::~cGhast() +{ +} + + + + + +bool cGhast::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cGhast" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cGhast::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_GUNPOWDER); + AddRandomDropItem(Drops, 0, 1, E_ITEM_GHAST_TEAR); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cGhast.h b/source/cGhast.h index c33d32df5..e65a45ba0 100644 --- a/source/cGhast.h +++ b/source/cGhast.h @@ -1,14 +1,14 @@ -#pragma once
-
-#include "cAggressiveMonster.h"
-
-class cGhast : public cAggressiveMonster
-{
-public:
- cGhast();
- ~cGhast();
-
- virtual bool IsA( const char* a_EntityType );
-
- virtual void KilledBy( cEntity* a_Killer );
-};
+#pragma once + +#include "cAggressiveMonster.h" + +class cGhast : public cAggressiveMonster +{ +public: + cGhast(); + ~cGhast(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/cGroup.cpp b/source/cGroup.cpp index 4fef22cb2..04549b0eb 100644 --- a/source/cGroup.cpp +++ b/source/cGroup.cpp @@ -1,37 +1,37 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cGroup.h"
-
-void cGroup::AddCommand( std::string a_Command )
-{
- m_Commands[ a_Command ] = true;
-}
-
-void cGroup::AddPermission( std::string a_Permission )
-{
- m_Permissions[ a_Permission ] = true;
-}
-
-bool cGroup::HasCommand( std::string a_Command )
-{
- if( m_Commands.find("*") != m_Commands.end() ) return true;
-
- CommandMap::iterator itr = m_Commands.find( a_Command );
- if( itr != m_Commands.end() )
- {
- if( itr->second ) return true;
- }
-
- for( GroupList::iterator itr = m_Inherits.begin(); itr != m_Inherits.end(); ++itr )
- {
- if( (*itr)->HasCommand( a_Command ) ) return true;
- }
- return false;
-}
-
-void cGroup::InheritFrom( cGroup* a_Group )
-{
- m_Inherits.remove( a_Group );
- m_Inherits.push_back( a_Group );
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cGroup.h" + +void cGroup::AddCommand( std::string a_Command ) +{ + m_Commands[ a_Command ] = true; +} + +void cGroup::AddPermission( std::string a_Permission ) +{ + m_Permissions[ a_Permission ] = true; +} + +bool cGroup::HasCommand( std::string a_Command ) +{ + if( m_Commands.find("*") != m_Commands.end() ) return true; + + CommandMap::iterator itr = m_Commands.find( a_Command ); + if( itr != m_Commands.end() ) + { + if( itr->second ) return true; + } + + for( GroupList::iterator itr = m_Inherits.begin(); itr != m_Inherits.end(); ++itr ) + { + if( (*itr)->HasCommand( a_Command ) ) return true; + } + return false; +} + +void cGroup::InheritFrom( cGroup* a_Group ) +{ + m_Inherits.remove( a_Group ); + m_Inherits.push_back( a_Group ); }
\ No newline at end of file diff --git a/source/cGroup.h b/source/cGroup.h index 02fb7f05c..447802e88 100644 --- a/source/cGroup.h +++ b/source/cGroup.h @@ -1,40 +1,40 @@ -
-#pragma once
-
-
-
-
-
-class cGroup //tolua_export
-{ //tolua_export
-public: //tolua_export
- cGroup() {}
- ~cGroup() {}
-
- void SetName( std::string a_Name ) { m_Name = a_Name; } //tolua_export
- const std::string & GetName() const { return m_Name; } //tolua_export
- void SetColor( std::string a_Color ) { m_Color = a_Color; } //tolua_export
- void AddCommand( std::string a_Command ); //tolua_export
- void AddPermission( std::string a_Permission ); //tolua_export
- void InheritFrom( cGroup* a_Group ); //tolua_export
-
- bool HasCommand( std::string a_Command ); //tolua_export
-
- typedef std::map< std::string, bool > PermissionMap;
- const PermissionMap & GetPermissions() const { return m_Permissions; }
-
- typedef std::map< std::string, bool > CommandMap;
- const CommandMap & GetCommands() const { return m_Commands; }
-
- const AString & GetColor() const { return m_Color; } //tolua_export
-
- typedef std::list< cGroup* > GroupList;
- const GroupList & GetInherits() const { return m_Inherits; }
-private:
- std::string m_Name;
- std::string m_Color;
-
- PermissionMap m_Permissions;
- CommandMap m_Commands;
- GroupList m_Inherits;
+ +#pragma once + + + + + +class cGroup //tolua_export +{ //tolua_export +public: //tolua_export + cGroup() {} + ~cGroup() {} + + void SetName( std::string a_Name ) { m_Name = a_Name; } //tolua_export + const std::string & GetName() const { return m_Name; } //tolua_export + void SetColor( std::string a_Color ) { m_Color = a_Color; } //tolua_export + void AddCommand( std::string a_Command ); //tolua_export + void AddPermission( std::string a_Permission ); //tolua_export + void InheritFrom( cGroup* a_Group ); //tolua_export + + bool HasCommand( std::string a_Command ); //tolua_export + + typedef std::map< std::string, bool > PermissionMap; + const PermissionMap & GetPermissions() const { return m_Permissions; } + + typedef std::map< std::string, bool > CommandMap; + const CommandMap & GetCommands() const { return m_Commands; } + + const AString & GetColor() const { return m_Color; } //tolua_export + + typedef std::list< cGroup* > GroupList; + const GroupList & GetInherits() const { return m_Inherits; } +private: + std::string m_Name; + std::string m_Color; + + PermissionMap m_Permissions; + CommandMap m_Commands; + GroupList m_Inherits; };//tolua_export
\ No newline at end of file diff --git a/source/cGroupManager.cpp b/source/cGroupManager.cpp index 30d70171c..2458308c9 100644 --- a/source/cGroupManager.cpp +++ b/source/cGroupManager.cpp @@ -1,108 +1,108 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cGroupManager.h"
-#include "cGroup.h"
-#include "../iniFile/iniFile.h"
-#include "cChatColor.h"
-#include "cRoot.h"
-
-
-
-
-
-typedef std::map< std::string, cGroup* > GroupMap;
-struct cGroupManager::sGroupManagerState
-{
- GroupMap Groups;
-};
-
-cGroupManager* cGroupManager::GetGroupManager()
-{
- LOGWARN("WARNING: Using deprecated function cGroupManager::GetGroupManager() use cRoot::Get()->GetGroupManager() instead!");
- return cRoot::Get()->GetGroupManager();
-}
-
-cGroupManager::~cGroupManager()
-{
- for( GroupMap::iterator itr = m_pState->Groups.begin(); itr != m_pState->Groups.end(); ++itr )
- {
- delete itr->second;
- }
- m_pState->Groups.clear();
-
- delete m_pState;
-}
-
-cGroupManager::cGroupManager()
- : m_pState( new sGroupManagerState )
-{
- LOG("-- Loading Groups --");
- cIniFile IniFile("groups.ini");
- if( IniFile.ReadFile() )
- {
- unsigned int NumKeys = IniFile.GetNumKeys();
- for( unsigned int i = 0; i < NumKeys; i++ )
- {
- std::string KeyName = IniFile.GetKeyName( i );
- cGroup* Group = GetGroup( KeyName.c_str() );
-
- LOG("Loading group: %s", KeyName.c_str() );
-
- Group->SetName( KeyName );
- char Color = IniFile.GetValue( KeyName, "Color", "-" )[0];
- if( Color != '-' )
- Group->SetColor( cChatColor::MakeColor(Color) );
- else
- Group->SetColor( cChatColor::White );
-
- std::string Commands = IniFile.GetValue( KeyName, "Commands", "" );
- if( Commands.size() > 0 )
- {
- AStringVector Split = StringSplit( Commands, "," );
- for( unsigned int i = 0; i < Split.size(); i++)
- {
- Group->AddCommand( Split[i] );
- //LOG("%s", Split[i].c_str() );
- }
- }
-
- std::string Permissions = IniFile.GetValue( KeyName, "Permissions", "" );
- if( Permissions.size() > 0 )
- {
- AStringVector Split = StringSplit( Permissions, "," );
- for( unsigned int i = 0; i < Split.size(); i++)
- {
- Group->AddPermission( Split[i] );
- LOGINFO("Permission: %s", Split[i].c_str() );
- }
- }
-
- std::string Groups = IniFile.GetValue( KeyName, "Inherits", "" );
- if( Groups.size() > 0 )
- {
- AStringVector Split = StringSplit( Groups, "," );
- for( unsigned int i = 0; i < Split.size(); i++)
- {
- Group->InheritFrom( GetGroup( Split[i].c_str() ) );
- }
- }
- }
- }
- LOG("-- Done Loading Groups --");
-}
-
-cGroup* cGroupManager::GetGroup( const char* a_Name )
-{
- GroupMap::iterator itr = m_pState->Groups.find( a_Name );
- if( itr != m_pState->Groups.end() )
- {
- return itr->second;
- }
-
- cGroup* Group = new cGroup();
- m_pState->Groups[a_Name] = Group;
-
- return Group;
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cGroupManager.h" +#include "cGroup.h" +#include "../iniFile/iniFile.h" +#include "cChatColor.h" +#include "cRoot.h" + + + + + +typedef std::map< std::string, cGroup* > GroupMap; +struct cGroupManager::sGroupManagerState +{ + GroupMap Groups; +}; + +cGroupManager* cGroupManager::GetGroupManager() +{ + LOGWARN("WARNING: Using deprecated function cGroupManager::GetGroupManager() use cRoot::Get()->GetGroupManager() instead!"); + return cRoot::Get()->GetGroupManager(); +} + +cGroupManager::~cGroupManager() +{ + for( GroupMap::iterator itr = m_pState->Groups.begin(); itr != m_pState->Groups.end(); ++itr ) + { + delete itr->second; + } + m_pState->Groups.clear(); + + delete m_pState; +} + +cGroupManager::cGroupManager() + : m_pState( new sGroupManagerState ) +{ + LOG("-- Loading Groups --"); + cIniFile IniFile("groups.ini"); + if( IniFile.ReadFile() ) + { + unsigned int NumKeys = IniFile.GetNumKeys(); + for( unsigned int i = 0; i < NumKeys; i++ ) + { + std::string KeyName = IniFile.GetKeyName( i ); + cGroup* Group = GetGroup( KeyName.c_str() ); + + LOG("Loading group: %s", KeyName.c_str() ); + + Group->SetName( KeyName ); + char Color = IniFile.GetValue( KeyName, "Color", "-" )[0]; + if( Color != '-' ) + Group->SetColor( cChatColor::MakeColor(Color) ); + else + Group->SetColor( cChatColor::White ); + + std::string Commands = IniFile.GetValue( KeyName, "Commands", "" ); + if( Commands.size() > 0 ) + { + AStringVector Split = StringSplit( Commands, "," ); + for( unsigned int i = 0; i < Split.size(); i++) + { + Group->AddCommand( Split[i] ); + //LOG("%s", Split[i].c_str() ); + } + } + + std::string Permissions = IniFile.GetValue( KeyName, "Permissions", "" ); + if( Permissions.size() > 0 ) + { + AStringVector Split = StringSplit( Permissions, "," ); + for( unsigned int i = 0; i < Split.size(); i++) + { + Group->AddPermission( Split[i] ); + LOGINFO("Permission: %s", Split[i].c_str() ); + } + } + + std::string Groups = IniFile.GetValue( KeyName, "Inherits", "" ); + if( Groups.size() > 0 ) + { + AStringVector Split = StringSplit( Groups, "," ); + for( unsigned int i = 0; i < Split.size(); i++) + { + Group->InheritFrom( GetGroup( Split[i].c_str() ) ); + } + } + } + } + LOG("-- Done Loading Groups --"); +} + +cGroup* cGroupManager::GetGroup( const char* a_Name ) +{ + GroupMap::iterator itr = m_pState->Groups.find( a_Name ); + if( itr != m_pState->Groups.end() ) + { + return itr->second; + } + + cGroup* Group = new cGroup(); + m_pState->Groups[a_Name] = Group; + + return Group; + }
\ No newline at end of file diff --git a/source/cGroupManager.h b/source/cGroupManager.h index fbd16f117..214d6991d 100644 --- a/source/cGroupManager.h +++ b/source/cGroupManager.h @@ -1,17 +1,17 @@ -#pragma once
-
-class cGroup;
-class cGroupManager
-{
-public:
- static cGroupManager * GetGroupManager(); //tolua_export
-
- cGroup* GetGroup( const char* a_Name );
-private:
- friend class cRoot;
- cGroupManager();
- ~cGroupManager();
-
- struct sGroupManagerState;
- sGroupManagerState* m_pState;
+#pragma once + +class cGroup; +class cGroupManager +{ +public: + static cGroupManager * GetGroupManager(); //tolua_export + + cGroup* GetGroup( const char* a_Name ); +private: + friend class cRoot; + cGroupManager(); + ~cGroupManager(); + + struct sGroupManagerState; + sGroupManagerState* m_pState; };
\ No newline at end of file diff --git a/source/cHeartBeat.cpp b/source/cHeartBeat.cpp index e8c49454d..5ac119593 100644 --- a/source/cHeartBeat.cpp +++ b/source/cHeartBeat.cpp @@ -1,144 +1,144 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cHeartBeat.h"
-#include "cMCLogger.h"
-#include "md5/md5.h"
-
-#include "cRoot.h"
-#include "cServer.h"
-#include "cSleep.h"
-
-
-
-
-
-cHeartBeat::cHeartBeat()
-{
- m_State = 0;
- Authenticate();
-}
-
-
-
-
-
-cHeartBeat::~cHeartBeat()
-{
-}
-
-
-
-
-
-void cHeartBeat::ReceivedData( char a_Data[256], int a_Size )
-{
- if( a_Size < 0 ) // Disconnected
- return;
-
- char MySalt[] = "1234567890";
-
- if( a_Size == 0 )
- {
- Authenticate();
- return;
- }
-
- bool bLoop = false;
- do
- {
- switch (m_State)
- {
- case 1:
- {
- m_ServerID = std::string( a_Data, a_Size );
- LOGINFO("Got server ID %s", m_ServerID.c_str() );
- std::string Hash = md5( m_ServerID + std::string( MySalt ) );
- CloseSocket();
- if( Connect( "mc-server.org", 80 ) )
- {
- SendMessage( (std::string("GET http://master.mc-server.org/?hash=") + Hash + std::string("&server=") + m_ServerID + "\n").c_str() );
- m_State = 2;
- }
- }
- break;
- case 2:
- {
- std::string ReturnedString = std::string( a_Data, a_Size );
- if( ReturnedString.compare("VALIDATED") == 0 )
- {
- LOGINFO("Successfully validated server on master server list");
- }
- else
- {
- LOGINFO("Could not validate server! Will try again later.");
- cSleep::MilliSleep( 10*1000 );
- Authenticate();
- return;
- }
- m_State = 3;
- } // Don't break, but fall through and update server info
- case 3:
- {
- cSleep::MilliSleep( 10*1000 );
- SendUpdate();
- m_State = 4;
- }
- break;
- case 4:
- {
- if( a_Data[0] == '0' )
- {
- LOGINFO("Successfully updated server info!");
- cSleep::MilliSleep( 10*1000 );
- SendUpdate();
- }
- else
- {
- LOGINFO("Failed to update server info, reauthenticating");
- Authenticate();
- }
- }
- default:
- break;
- };
- } while( bLoop );
-}
-
-
-
-
-
-void cHeartBeat::SendUpdate()
-{
- CloseSocket();
- if( Connect( "mc-server.org", 80 ) )
- {
- int Port = cRoot::Get()->GetServer()->GetPort();
- AString Msg;
- AString sPort;
- Printf(sPort, "%i", Port);
- AString sChecksum = md5( m_ServerID + sPort );
- Printf(Msg, "GET http://master.mc-server.org/?update=%s&checksum=%s&port=%d\n", m_ServerID.c_str(), sChecksum.c_str(), Port);
- SendMessage(Msg.c_str());
- }
-}
-
-
-
-
-
-void cHeartBeat::Authenticate()
-{
- CloseSocket();
- if (Connect( "mc-server.org", 80))
- {
- m_State = 1;
- int RetVal = SendMessage( "GET http://master.mc-server.org/\r\n\r\n");
- LOGINFO("Returned %i", RetVal);
- }
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cHeartBeat.h" +#include "cMCLogger.h" +#include "md5/md5.h" + +#include "cRoot.h" +#include "cServer.h" +#include "cSleep.h" + + + + + +cHeartBeat::cHeartBeat() +{ + m_State = 0; + Authenticate(); +} + + + + + +cHeartBeat::~cHeartBeat() +{ +} + + + + + +void cHeartBeat::ReceivedData( char a_Data[256], int a_Size ) +{ + if( a_Size < 0 ) // Disconnected + return; + + char MySalt[] = "1234567890"; + + if( a_Size == 0 ) + { + Authenticate(); + return; + } + + bool bLoop = false; + do + { + switch (m_State) + { + case 1: + { + m_ServerID = std::string( a_Data, a_Size ); + LOGINFO("Got server ID %s", m_ServerID.c_str() ); + std::string Hash = md5( m_ServerID + std::string( MySalt ) ); + CloseSocket(); + if( Connect( "mc-server.org", 80 ) ) + { + SendMessage( (std::string("GET http://master.mc-server.org/?hash=") + Hash + std::string("&server=") + m_ServerID + "\n").c_str() ); + m_State = 2; + } + } + break; + case 2: + { + std::string ReturnedString = std::string( a_Data, a_Size ); + if( ReturnedString.compare("VALIDATED") == 0 ) + { + LOGINFO("Successfully validated server on master server list"); + } + else + { + LOGINFO("Could not validate server! Will try again later."); + cSleep::MilliSleep( 10*1000 ); + Authenticate(); + return; + } + m_State = 3; + } // Don't break, but fall through and update server info + case 3: + { + cSleep::MilliSleep( 10*1000 ); + SendUpdate(); + m_State = 4; + } + break; + case 4: + { + if( a_Data[0] == '0' ) + { + LOGINFO("Successfully updated server info!"); + cSleep::MilliSleep( 10*1000 ); + SendUpdate(); + } + else + { + LOGINFO("Failed to update server info, reauthenticating"); + Authenticate(); + } + } + default: + break; + }; + } while( bLoop ); +} + + + + + +void cHeartBeat::SendUpdate() +{ + CloseSocket(); + if( Connect( "mc-server.org", 80 ) ) + { + int Port = cRoot::Get()->GetServer()->GetPort(); + AString Msg; + AString sPort; + Printf(sPort, "%i", Port); + AString sChecksum = md5( m_ServerID + sPort ); + Printf(Msg, "GET http://master.mc-server.org/?update=%s&checksum=%s&port=%d\n", m_ServerID.c_str(), sChecksum.c_str(), Port); + SendMessage(Msg.c_str()); + } +} + + + + + +void cHeartBeat::Authenticate() +{ + CloseSocket(); + if (Connect( "mc-server.org", 80)) + { + m_State = 1; + int RetVal = SendMessage( "GET http://master.mc-server.org/\r\n\r\n"); + LOGINFO("Returned %i", RetVal); + } +} + + + + diff --git a/source/cHeartBeat.h b/source/cHeartBeat.h index 0adaf6b59..416494701 100644 --- a/source/cHeartBeat.h +++ b/source/cHeartBeat.h @@ -1,28 +1,28 @@ -
-#pragma once
-
-#include "cTCPLink.h"
-
-
-
-
-
-class cHeartBeat : public cTCPLink
-{
-public:
- cHeartBeat();
- ~cHeartBeat();
-private:
- virtual void ReceivedData( char a_Data[256], int a_Size );
-
- void Authenticate();
- int m_State;
-
- void SendUpdate();
-
- std::string m_ServerID;
-};
-
-
-
-
+ +#pragma once + +#include "cTCPLink.h" + + + + + +class cHeartBeat : public cTCPLink +{ +public: + cHeartBeat(); + ~cHeartBeat(); +private: + virtual void ReceivedData( char a_Data[256], int a_Size ); + + void Authenticate(); + int m_State; + + void SendUpdate(); + + std::string m_ServerID; +}; + + + + diff --git a/source/cInventory.cpp b/source/cInventory.cpp index e3c92f307..8854ad29a 100644 --- a/source/cInventory.cpp +++ b/source/cInventory.cpp @@ -1,360 +1,360 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cInventory.h"
-#include "cPlayer.h"
-#include "cClientHandle.h"
-#include "cWindow.h"
-#include "cItem.h"
-#include "cRoot.h"
-
-#include <json/json.h>
-
-#include "packets/cPacket_WindowClick.h"
-#include "packets/cPacket_WholeInventory.h"
-#include "packets/cPacket_InventorySlot.h"
-
-
-
-
-
-cInventory::~cInventory()
-{
- delete [] m_Slots;
- delete m_EquippedItem;
- if( GetWindow() ) GetWindow()->Close( *m_Owner );
- CloseWindow();
-}
-
-
-
-
-
-cInventory::cInventory(cPlayer* a_Owner)
-{
- m_Owner = a_Owner;
-
- m_Slots = new cItem[c_NumSlots];
- for(unsigned int i = 0; i < c_NumSlots; i++)
- m_Slots[i].Empty();
-
- m_CraftSlots = m_Slots + c_CraftOffset;
- m_ArmorSlots = m_Slots + c_ArmorOffset;
- m_MainSlots = m_Slots + c_MainOffset;
- m_HotSlots = m_Slots + c_HotOffset;
-
- m_EquippedItem = new cItem();
- m_EquippedSlot = 0;
-
- if( !GetWindow() )
- {
- cWindow* Window = new cWindow( this, false );
- Window->SetSlots( m_Slots, c_NumSlots );
- Window->SetWindowID( 0 );
- OpenWindow( Window );
- }
-}
-
-
-
-
-
-bool cInventory::AddItem( cItem & a_Item )
-{
- cItem BackupSlots[c_NumSlots];
- memcpy( BackupSlots, m_Slots, c_NumSlots * sizeof( cItem ) );
-
- bool ChangedSlots[c_NumSlots];
- memset( ChangedSlots, false, c_NumSlots * sizeof( bool ) );
-
- if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_HotOffset, c_HotSlots, ChangedSlots, 0 );
- if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_MainOffset, c_MainSlots, ChangedSlots, 0 );
- if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_HotOffset, c_HotSlots, ChangedSlots, 2 );
- if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_MainOffset, c_MainSlots, ChangedSlots, 2 );
-
- if( a_Item.m_ItemCount > 0 ) // Could not add all items
- {
- // retore backup
- memcpy( m_Slots, BackupSlots, c_NumSlots * sizeof( cItem ) );
- return false;
- }
-
- for(unsigned int i = 0; i < c_NumSlots; i++)
- {
- if( ChangedSlots[i] )
- {
- LOG("Item was added to %i ID:%i Count:%i", i, m_Slots[i].m_ItemID, m_Slots[i].m_ItemCount );
- SendSlot(i);
- }
- }
-
- return (a_Item.m_ItemCount == 0);
-}
-
-
-
-
-
-// TODO: Right now if you dont have enough items, the items you did have are removed, and the function returns false anyway
-bool cInventory::RemoveItem( cItem & a_Item )
-{
- // First check equipped slot
- if( m_EquippedSlot >= 0 && m_EquippedSlot < 9 )
- {
- if( m_HotSlots[m_EquippedSlot].m_ItemID == a_Item.m_ItemID )
- {
- cItem & Item = m_HotSlots[m_EquippedSlot];
- if(Item.m_ItemCount > a_Item.m_ItemCount)
- {
- Item.m_ItemCount -= a_Item.m_ItemCount;
- SendSlot( m_EquippedSlot + c_HotOffset );
- return true;
- }
- else if(Item.m_ItemCount > 0 )
- {
- a_Item.m_ItemCount -= Item.m_ItemCount;
- Item.Empty();
- SendSlot( m_EquippedSlot + c_HotOffset );
- }
- }
- }
-
- // Then check other slotz
- if( a_Item.m_ItemCount > 0 )
- {
- for(int i = 0; i < 36; i++)
- {
- cItem & Item = m_MainSlots[i];
- if( Item.m_ItemID == a_Item.m_ItemID )
- {
- if(Item.m_ItemCount > a_Item.m_ItemCount)
- {
- Item.m_ItemCount -= a_Item.m_ItemCount;
- SendSlot( i + c_MainOffset );
- return true;
- }
- else if(Item.m_ItemCount > 0 )
- {
- a_Item.m_ItemCount -= Item.m_ItemCount;
- Item.Empty();
- SendSlot( i + c_MainOffset );
- }
- }
- }
- }
-
- if( a_Item.m_ItemCount == 0 )
- return true;
- else
- return false;
-}
-
-
-
-
-
-void cInventory::Clear()
-{
- for(unsigned int i = 0; i < c_NumSlots; i++)
- m_Slots[i].Empty();
-}
-
-
-
-
-
-cItem * cInventory::GetSlotsForType( int a_Type )
-{
- switch( a_Type )
- {
- case -1:
- return m_MainSlots;
- case -2:
- return m_CraftSlots;
- case -3:
- return m_ArmorSlots;
- }
- return 0;
-}
-
-
-
-
-
-int cInventory::GetSlotCountForType( int a_Type )
-{
- switch (a_Type)
- {
- case -1:
- return 36;
- case -2:
- case -3:
- return 4;
- }
- return 0;
-}
-
-
-
-
-
-cItem* cInventory::GetSlot( int a_SlotNum )
-{
- if( a_SlotNum < 0 || a_SlotNum >= (short)c_NumSlots ) return 0;
- return &m_Slots[a_SlotNum];
-}
-
-
-
-
-
-cItem* cInventory::GetFromHotBar( int a_SlotNum )
-{
- if ((a_SlotNum < 0) || (a_SlotNum >= 9))
- {
- return NULL;
- }
- return &m_HotSlots[a_SlotNum];
-}
-
-
-
-
-
-void cInventory::SetEquippedSlot( int a_SlotNum )
-{
- if( a_SlotNum < 0 || a_SlotNum >= 9 ) m_EquippedSlot = 0;
- else m_EquippedSlot = (short)a_SlotNum;
-}
-
-
-
-
-
-cItem & cInventory::GetEquippedItem()
-{
- cItem* Item = GetFromHotBar( m_EquippedSlot );
- if( Item )
- {
- *m_EquippedItem = *Item;
- return *Item;
- }
- else
- {
- m_EquippedItem->Empty();
- }
- return *m_EquippedItem;
-}
-
-
-
-
-
-void cInventory::SendWholeInventory( cClientHandle* a_Client )
-{
- cPacket_WholeInventory Inventory( this );
- a_Client->Send( Inventory );
-}
-
-
-
-
-
-void cInventory::SendSlot( int a_SlotNum )
-{
- cItem* Item = GetSlot( a_SlotNum );
- if( Item )
- {
- cPacket_InventorySlot InventorySlot;
- InventorySlot.m_ItemCount = Item->m_ItemCount;
- InventorySlot.m_ItemID = (short) Item->m_ItemID;
- InventorySlot.m_ItemUses = (char) Item->m_ItemHealth;
- InventorySlot.m_SlotNum = (short) a_SlotNum;
- InventorySlot.m_WindowID = 0; // Inventory window ID
- m_Owner->GetClientHandle()->Send( InventorySlot );
- }
-}
-
-
-
-
-
-bool cInventory::AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode /* = 0 */ )
-{
- // Fill already present stacks
- if( a_Mode < 2 )
- {
- for(int i = 0; i < a_Size; i++)
- {
- if( m_Slots[i + a_Offset].m_ItemID == a_Item.m_ItemID && m_Slots[i + a_Offset].m_ItemCount < 64 && m_Slots[i + a_Offset].m_ItemHealth == a_Item.m_ItemHealth )
- {
- int NumFree = 64 - m_Slots[i + a_Offset].m_ItemCount;
- if( NumFree >= a_Item.m_ItemCount )
- {
-
- //printf("1. Adding %i items ( free: %i )\n", a_Item.m_ItemCount, NumFree );
- m_Slots[i + a_Offset].m_ItemCount += a_Item.m_ItemCount;
- a_Item.m_ItemCount = 0;
- a_bChangedSlots[i + a_Offset] = true;
- break;
- }
- else
- {
- //printf("2. Adding %i items\n", NumFree );
- m_Slots[i + a_Offset].m_ItemCount += (char)NumFree;
- a_Item.m_ItemCount -= (char)NumFree;
- a_bChangedSlots[i + a_Offset] = true;
- }
- }
- }
- }
-
- if( a_Mode > 0 )
- {
- // If we got more left, find first empty slot
- for(int i = 0; i < a_Size && a_Item.m_ItemCount > 0; i++)
- {
- if( m_Slots[i + a_Offset].m_ItemID == -1 )
- {
- m_Slots[i + a_Offset] = a_Item;
- a_Item.m_ItemCount = 0;
- a_bChangedSlots[i + a_Offset] = true;
- }
- }
- }
-
- return true;
-}
-
-
-
-
-
-void cInventory::SaveToJson(Json::Value & a_Value)
-{
- for(unsigned int i = 0; i < c_NumSlots; i++)
- {
- Json::Value JSON_Item;
- m_Slots[i].GetJson( JSON_Item );
- a_Value.append( JSON_Item );
- }
-}
-
-
-
-
-
-bool cInventory::LoadFromJson(Json::Value & a_Value)
-{
- int SlotIdx = 0;
- for( Json::Value::iterator itr = a_Value.begin(); itr != a_Value.end(); ++itr )
- {
- m_Slots[SlotIdx].FromJson( *itr );
- SlotIdx++;
- }
- return true;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cInventory.h" +#include "cPlayer.h" +#include "cClientHandle.h" +#include "cWindow.h" +#include "cItem.h" +#include "cRoot.h" + +#include <json/json.h> + +#include "packets/cPacket_WindowClick.h" +#include "packets/cPacket_WholeInventory.h" +#include "packets/cPacket_InventorySlot.h" + + + + + +cInventory::~cInventory() +{ + delete [] m_Slots; + delete m_EquippedItem; + if( GetWindow() ) GetWindow()->Close( *m_Owner ); + CloseWindow(); +} + + + + + +cInventory::cInventory(cPlayer* a_Owner) +{ + m_Owner = a_Owner; + + m_Slots = new cItem[c_NumSlots]; + for(unsigned int i = 0; i < c_NumSlots; i++) + m_Slots[i].Empty(); + + m_CraftSlots = m_Slots + c_CraftOffset; + m_ArmorSlots = m_Slots + c_ArmorOffset; + m_MainSlots = m_Slots + c_MainOffset; + m_HotSlots = m_Slots + c_HotOffset; + + m_EquippedItem = new cItem(); + m_EquippedSlot = 0; + + if( !GetWindow() ) + { + cWindow* Window = new cWindow( this, false ); + Window->SetSlots( m_Slots, c_NumSlots ); + Window->SetWindowID( 0 ); + OpenWindow( Window ); + } +} + + + + + +bool cInventory::AddItem( cItem & a_Item ) +{ + cItem BackupSlots[c_NumSlots]; + memcpy( BackupSlots, m_Slots, c_NumSlots * sizeof( cItem ) ); + + bool ChangedSlots[c_NumSlots]; + memset( ChangedSlots, false, c_NumSlots * sizeof( bool ) ); + + if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_HotOffset, c_HotSlots, ChangedSlots, 0 ); + if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_MainOffset, c_MainSlots, ChangedSlots, 0 ); + if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_HotOffset, c_HotSlots, ChangedSlots, 2 ); + if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_MainOffset, c_MainSlots, ChangedSlots, 2 ); + + if( a_Item.m_ItemCount > 0 ) // Could not add all items + { + // retore backup + memcpy( m_Slots, BackupSlots, c_NumSlots * sizeof( cItem ) ); + return false; + } + + for(unsigned int i = 0; i < c_NumSlots; i++) + { + if( ChangedSlots[i] ) + { + LOG("Item was added to %i ID:%i Count:%i", i, m_Slots[i].m_ItemID, m_Slots[i].m_ItemCount ); + SendSlot(i); + } + } + + return (a_Item.m_ItemCount == 0); +} + + + + + +// TODO: Right now if you dont have enough items, the items you did have are removed, and the function returns false anyway +bool cInventory::RemoveItem( cItem & a_Item ) +{ + // First check equipped slot + if( m_EquippedSlot >= 0 && m_EquippedSlot < 9 ) + { + if( m_HotSlots[m_EquippedSlot].m_ItemID == a_Item.m_ItemID ) + { + cItem & Item = m_HotSlots[m_EquippedSlot]; + if(Item.m_ItemCount > a_Item.m_ItemCount) + { + Item.m_ItemCount -= a_Item.m_ItemCount; + SendSlot( m_EquippedSlot + c_HotOffset ); + return true; + } + else if(Item.m_ItemCount > 0 ) + { + a_Item.m_ItemCount -= Item.m_ItemCount; + Item.Empty(); + SendSlot( m_EquippedSlot + c_HotOffset ); + } + } + } + + // Then check other slotz + if( a_Item.m_ItemCount > 0 ) + { + for(int i = 0; i < 36; i++) + { + cItem & Item = m_MainSlots[i]; + if( Item.m_ItemID == a_Item.m_ItemID ) + { + if(Item.m_ItemCount > a_Item.m_ItemCount) + { + Item.m_ItemCount -= a_Item.m_ItemCount; + SendSlot( i + c_MainOffset ); + return true; + } + else if(Item.m_ItemCount > 0 ) + { + a_Item.m_ItemCount -= Item.m_ItemCount; + Item.Empty(); + SendSlot( i + c_MainOffset ); + } + } + } + } + + if( a_Item.m_ItemCount == 0 ) + return true; + else + return false; +} + + + + + +void cInventory::Clear() +{ + for(unsigned int i = 0; i < c_NumSlots; i++) + m_Slots[i].Empty(); +} + + + + + +cItem * cInventory::GetSlotsForType( int a_Type ) +{ + switch( a_Type ) + { + case -1: + return m_MainSlots; + case -2: + return m_CraftSlots; + case -3: + return m_ArmorSlots; + } + return 0; +} + + + + + +int cInventory::GetSlotCountForType( int a_Type ) +{ + switch (a_Type) + { + case -1: + return 36; + case -2: + case -3: + return 4; + } + return 0; +} + + + + + +cItem* cInventory::GetSlot( int a_SlotNum ) +{ + if( a_SlotNum < 0 || a_SlotNum >= (short)c_NumSlots ) return 0; + return &m_Slots[a_SlotNum]; +} + + + + + +cItem* cInventory::GetFromHotBar( int a_SlotNum ) +{ + if ((a_SlotNum < 0) || (a_SlotNum >= 9)) + { + return NULL; + } + return &m_HotSlots[a_SlotNum]; +} + + + + + +void cInventory::SetEquippedSlot( int a_SlotNum ) +{ + if( a_SlotNum < 0 || a_SlotNum >= 9 ) m_EquippedSlot = 0; + else m_EquippedSlot = (short)a_SlotNum; +} + + + + + +cItem & cInventory::GetEquippedItem() +{ + cItem* Item = GetFromHotBar( m_EquippedSlot ); + if( Item ) + { + *m_EquippedItem = *Item; + return *Item; + } + else + { + m_EquippedItem->Empty(); + } + return *m_EquippedItem; +} + + + + + +void cInventory::SendWholeInventory( cClientHandle* a_Client ) +{ + cPacket_WholeInventory Inventory( this ); + a_Client->Send( Inventory ); +} + + + + + +void cInventory::SendSlot( int a_SlotNum ) +{ + cItem* Item = GetSlot( a_SlotNum ); + if( Item ) + { + cPacket_InventorySlot InventorySlot; + InventorySlot.m_ItemCount = Item->m_ItemCount; + InventorySlot.m_ItemID = (short) Item->m_ItemID; + InventorySlot.m_ItemUses = (char) Item->m_ItemHealth; + InventorySlot.m_SlotNum = (short) a_SlotNum; + InventorySlot.m_WindowID = 0; // Inventory window ID + m_Owner->GetClientHandle()->Send( InventorySlot ); + } +} + + + + + +bool cInventory::AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode /* = 0 */ ) +{ + // Fill already present stacks + if( a_Mode < 2 ) + { + for(int i = 0; i < a_Size; i++) + { + if( m_Slots[i + a_Offset].m_ItemID == a_Item.m_ItemID && m_Slots[i + a_Offset].m_ItemCount < 64 && m_Slots[i + a_Offset].m_ItemHealth == a_Item.m_ItemHealth ) + { + int NumFree = 64 - m_Slots[i + a_Offset].m_ItemCount; + if( NumFree >= a_Item.m_ItemCount ) + { + + //printf("1. Adding %i items ( free: %i )\n", a_Item.m_ItemCount, NumFree ); + m_Slots[i + a_Offset].m_ItemCount += a_Item.m_ItemCount; + a_Item.m_ItemCount = 0; + a_bChangedSlots[i + a_Offset] = true; + break; + } + else + { + //printf("2. Adding %i items\n", NumFree ); + m_Slots[i + a_Offset].m_ItemCount += (char)NumFree; + a_Item.m_ItemCount -= (char)NumFree; + a_bChangedSlots[i + a_Offset] = true; + } + } + } + } + + if( a_Mode > 0 ) + { + // If we got more left, find first empty slot + for(int i = 0; i < a_Size && a_Item.m_ItemCount > 0; i++) + { + if( m_Slots[i + a_Offset].m_ItemID == -1 ) + { + m_Slots[i + a_Offset] = a_Item; + a_Item.m_ItemCount = 0; + a_bChangedSlots[i + a_Offset] = true; + } + } + } + + return true; +} + + + + + +void cInventory::SaveToJson(Json::Value & a_Value) +{ + for(unsigned int i = 0; i < c_NumSlots; i++) + { + Json::Value JSON_Item; + m_Slots[i].GetJson( JSON_Item ); + a_Value.append( JSON_Item ); + } +} + + + + + +bool cInventory::LoadFromJson(Json::Value & a_Value) +{ + int SlotIdx = 0; + for( Json::Value::iterator itr = a_Value.begin(); itr != a_Value.end(); ++itr ) + { + m_Slots[SlotIdx].FromJson( *itr ); + SlotIdx++; + } + return true; +} + + + + diff --git a/source/cInventory.h b/source/cInventory.h index b7e91195b..0b4220b32 100644 --- a/source/cInventory.h +++ b/source/cInventory.h @@ -1,82 +1,82 @@ -
-#pragma once
-
-#include "cWindowOwner.h"
-#include "FileDefine.h"
-
-namespace Json
-{
- class Value;
-};
-
-class cItem;
-class cClientHandle;
-class cPlayer;
-class cPacket;
-class cPacket_EntityEquipment;
-
-
-
-
-
-class cInventory //tolua_export
- : public cWindowOwner
-{ //tolua_export
-public:
- cInventory(cPlayer* a_Owner);
- ~cInventory();
-
- void Clear(); //tolua_export
-
- cItem* GetSlotsForType( int a_Type );
- int GetSlotCountForType( int a_Type );
-
- bool AddItem( cItem & a_Item ); //tolua_export
- bool RemoveItem( cItem & a_Item ); //tolua_export
-
- void SaveToJson(Json::Value & a_Value);
- bool LoadFromJson(Json::Value & a_Value);
-
- void SendWholeInventory( cClientHandle* a_Client );
-
- cItem* GetSlot( int a_SlotNum ); //tolua_export
- cItem* GetSlots() { return m_Slots; }
- cItem* GetFromHotBar( int a_SlotNum ); //tolua_export
-
- cItem & GetEquippedItem(); //tolua_export
- void SetEquippedSlot( int a_SlotNum ); //tolua_export
- short GetEquippedSlot() { return m_EquippedSlot; } //tolua_export
-
- virtual void Clicked( cPacket* a_ClickPacket ) = 0;
-
- void SendSlot( int a_SlotNum ); //tolua_export
-
- static const unsigned int c_NumSlots = 45;
- static const unsigned int c_MainSlots = 27;
- static const unsigned int c_HotSlots = 9;
- static const unsigned int c_CraftSlots = 4;
- static const unsigned int c_ArmorSlots = 4;
-
- static const unsigned int c_CraftOffset = 0;
- static const unsigned int c_ArmorOffset = 5;
- static const unsigned int c_MainOffset = 9;
- static const unsigned int c_HotOffset = 36;
-
-protected:
- bool AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode = 0 );
-
- cItem* m_Slots;
- cItem* m_MainSlots;
- cItem* m_CraftSlots;
- cItem* m_ArmorSlots;
- cItem* m_HotSlots;
-
- cItem* m_EquippedItem;
- short m_EquippedSlot;
-
- cPlayer* m_Owner;
-}; //tolua_export
-
-
-
-
+ +#pragma once + +#include "cWindowOwner.h" +#include "FileDefine.h" + +namespace Json +{ + class Value; +}; + +class cItem; +class cClientHandle; +class cPlayer; +class cPacket; +class cPacket_EntityEquipment; + + + + + +class cInventory //tolua_export + : public cWindowOwner +{ //tolua_export +public: + cInventory(cPlayer* a_Owner); + ~cInventory(); + + void Clear(); //tolua_export + + cItem* GetSlotsForType( int a_Type ); + int GetSlotCountForType( int a_Type ); + + bool AddItem( cItem & a_Item ); //tolua_export + bool RemoveItem( cItem & a_Item ); //tolua_export + + void SaveToJson(Json::Value & a_Value); + bool LoadFromJson(Json::Value & a_Value); + + void SendWholeInventory( cClientHandle* a_Client ); + + cItem* GetSlot( int a_SlotNum ); //tolua_export + cItem* GetSlots() { return m_Slots; } + cItem* GetFromHotBar( int a_SlotNum ); //tolua_export + + cItem & GetEquippedItem(); //tolua_export + void SetEquippedSlot( int a_SlotNum ); //tolua_export + short GetEquippedSlot() { return m_EquippedSlot; } //tolua_export + + virtual void Clicked( cPacket* a_ClickPacket ) = 0; + + void SendSlot( int a_SlotNum ); //tolua_export + + static const unsigned int c_NumSlots = 45; + static const unsigned int c_MainSlots = 27; + static const unsigned int c_HotSlots = 9; + static const unsigned int c_CraftSlots = 4; + static const unsigned int c_ArmorSlots = 4; + + static const unsigned int c_CraftOffset = 0; + static const unsigned int c_ArmorOffset = 5; + static const unsigned int c_MainOffset = 9; + static const unsigned int c_HotOffset = 36; + +protected: + bool AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode = 0 ); + + cItem* m_Slots; + cItem* m_MainSlots; + cItem* m_CraftSlots; + cItem* m_ArmorSlots; + cItem* m_HotSlots; + + cItem* m_EquippedItem; + short m_EquippedSlot; + + cPlayer* m_Owner; +}; //tolua_export + + + + diff --git a/source/cIsThread.cpp b/source/cIsThread.cpp index edde68767..cfc6fa72a 100644 --- a/source/cIsThread.cpp +++ b/source/cIsThread.cpp @@ -1,167 +1,167 @@ -
-// cIsThread.cpp
-
-// Implements the cIsThread class representing an OS-independent wrapper for a class that implements a thread.
-// This class will eventually suupersede the old cThread class
-
-#include "Globals.h"
-
-#include "cIsThread.h"
-
-
-
-
-
-// When in MSVC, the debugger provides "thread naming" by catching special exceptions. Interface here:
-#if defined(_MSC_VER) && defined(_DEBUG)
-//
-// Usage: SetThreadName (-1, "MainThread");
-//
-
-static void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName)
-{
- struct
- {
- DWORD dwType; // must be 0x1000
- LPCSTR szName; // pointer to name (in user addr space)
- DWORD dwThreadID; // thread ID (-1=caller thread)
- DWORD dwFlags; // reserved for future use, must be zero
- } info;
-
- info.dwType = 0x1000;
- info.szName = szThreadName;
- info.dwThreadID = dwThreadID;
- info.dwFlags = 0;
-
- __try
- {
- RaiseException(0x406D1388, 0, sizeof(info) / sizeof(DWORD), (DWORD *)&info);
- }
- __except(EXCEPTION_CONTINUE_EXECUTION)
- {
- }
-}
-#endif // _MSC_VER && _DEBUG
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// cIsThread:
-
-cIsThread::cIsThread(const AString & iThreadName) :
- m_ThreadName(iThreadName),
- m_ShouldTerminate(false),
- #ifdef _WIN32
- m_Handle(NULL)
- #else // _WIN32
- m_HasStarted(false)
- #endif // else _WIN32
-{
-}
-
-
-
-
-
-cIsThread::~cIsThread()
-{
- m_ShouldTerminate = true;
- Wait();
-}
-
-
-
-
-
-bool cIsThread::Start(void)
-{
- #ifdef _WIN32
- ASSERT(m_Handle == NULL); // Has already started one thread?
-
- // Create the thread suspended, so that the mHandle variable is valid in the thread procedure
- DWORD ThreadID = 0;
- m_Handle = CreateThread(NULL, 0, thrExecute, this, CREATE_SUSPENDED, &ThreadID);
- if (m_Handle == NULL)
- {
- LOGERROR("ERROR: Could not create thread \"%s\", GLE = %d!", m_ThreadName.c_str(), GetLastError());
- return false;
- }
- ResumeThread(m_Handle);
-
- #if defined(_DEBUG) && defined(_MSC_VER)
- // Thread naming is available only in MSVC
- if (!m_ThreadName.empty())
- {
- SetThreadName(ThreadID, m_ThreadName.c_str());
- }
- #endif // _DEBUG and _MSC_VER
-
- #else // _WIN32
- ASSERT(!m_HasStarted);
-
- if (pthread_create(&m_Handle, NULL, thrExecute, this))
- {
- LOGERROR("ERROR: Could not create thread \"%s\", !", m_ThreadName.c_str());
- return false;
- }
- m_HasStarted = true;
- #endif // else _WIN32
-
- return true;
-}
-
-
-
-
-
-bool cIsThread::Wait(void)
-{
- #ifdef _WIN32
-
- if (m_Handle == NULL)
- {
- return true;
- }
- // Cannot log, logger may already be stopped:
- // LOG("Waiting for thread \"%s\" to terminate.", m_ThreadName.c_str());
- int res = WaitForSingleObject(m_Handle, INFINITE);
- m_Handle = NULL;
- // Cannot log, logger may already be stopped:
- // LOG("Thread \"%s\" %s terminated, GLE = %d", m_ThreadName.c_str(), (res == WAIT_OBJECT_0) ? "" : "not", GetLastError());
- return (res == WAIT_OBJECT_0);
-
- #else // _WIN32
-
- if (!m_HasStarted)
- {
- return true;
- }
- // Cannot log, logger may already be stopped:
- // LOG("Waiting for thread \"%s\" to terminate.", m_ThreadName.c_str());
- int res = pthread_join(m_Handle, NULL);
- m_HasStarted = false;
- // Cannot log, logger may already be stopped:
- // LOG("Thread \"%s\" %s terminated, errno = %d", m_ThreadName.c_str(), (res == 0) ? "" : "not", errno);
- return (res == 0);
-
- #endif // else _WIN32
-}
-
-
-
-
-
-unsigned long cIsThread::GetCurrentID(void)
-{
- #ifdef _WIN32
- return (unsigned long) GetCurrentThreadId();
- #else
- return (unsigned long) pthread_self();
- #endif
-}
-
-
-
-
+ +// cIsThread.cpp + +// Implements the cIsThread class representing an OS-independent wrapper for a class that implements a thread. +// This class will eventually suupersede the old cThread class + +#include "Globals.h" + +#include "cIsThread.h" + + + + + +// When in MSVC, the debugger provides "thread naming" by catching special exceptions. Interface here: +#if defined(_MSC_VER) && defined(_DEBUG) +// +// Usage: SetThreadName (-1, "MainThread"); +// + +static void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName) +{ + struct + { + DWORD dwType; // must be 0x1000 + LPCSTR szName; // pointer to name (in user addr space) + DWORD dwThreadID; // thread ID (-1=caller thread) + DWORD dwFlags; // reserved for future use, must be zero + } info; + + info.dwType = 0x1000; + info.szName = szThreadName; + info.dwThreadID = dwThreadID; + info.dwFlags = 0; + + __try + { + RaiseException(0x406D1388, 0, sizeof(info) / sizeof(DWORD), (DWORD *)&info); + } + __except(EXCEPTION_CONTINUE_EXECUTION) + { + } +} +#endif // _MSC_VER && _DEBUG + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cIsThread: + +cIsThread::cIsThread(const AString & iThreadName) : + m_ThreadName(iThreadName), + m_ShouldTerminate(false), + #ifdef _WIN32 + m_Handle(NULL) + #else // _WIN32 + m_HasStarted(false) + #endif // else _WIN32 +{ +} + + + + + +cIsThread::~cIsThread() +{ + m_ShouldTerminate = true; + Wait(); +} + + + + + +bool cIsThread::Start(void) +{ + #ifdef _WIN32 + ASSERT(m_Handle == NULL); // Has already started one thread? + + // Create the thread suspended, so that the mHandle variable is valid in the thread procedure + DWORD ThreadID = 0; + m_Handle = CreateThread(NULL, 0, thrExecute, this, CREATE_SUSPENDED, &ThreadID); + if (m_Handle == NULL) + { + LOGERROR("ERROR: Could not create thread \"%s\", GLE = %d!", m_ThreadName.c_str(), GetLastError()); + return false; + } + ResumeThread(m_Handle); + + #if defined(_DEBUG) && defined(_MSC_VER) + // Thread naming is available only in MSVC + if (!m_ThreadName.empty()) + { + SetThreadName(ThreadID, m_ThreadName.c_str()); + } + #endif // _DEBUG and _MSC_VER + + #else // _WIN32 + ASSERT(!m_HasStarted); + + if (pthread_create(&m_Handle, NULL, thrExecute, this)) + { + LOGERROR("ERROR: Could not create thread \"%s\", !", m_ThreadName.c_str()); + return false; + } + m_HasStarted = true; + #endif // else _WIN32 + + return true; +} + + + + + +bool cIsThread::Wait(void) +{ + #ifdef _WIN32 + + if (m_Handle == NULL) + { + return true; + } + // Cannot log, logger may already be stopped: + // LOG("Waiting for thread \"%s\" to terminate.", m_ThreadName.c_str()); + int res = WaitForSingleObject(m_Handle, INFINITE); + m_Handle = NULL; + // Cannot log, logger may already be stopped: + // LOG("Thread \"%s\" %s terminated, GLE = %d", m_ThreadName.c_str(), (res == WAIT_OBJECT_0) ? "" : "not", GetLastError()); + return (res == WAIT_OBJECT_0); + + #else // _WIN32 + + if (!m_HasStarted) + { + return true; + } + // Cannot log, logger may already be stopped: + // LOG("Waiting for thread \"%s\" to terminate.", m_ThreadName.c_str()); + int res = pthread_join(m_Handle, NULL); + m_HasStarted = false; + // Cannot log, logger may already be stopped: + // LOG("Thread \"%s\" %s terminated, errno = %d", m_ThreadName.c_str(), (res == 0) ? "" : "not", errno); + return (res == 0); + + #endif // else _WIN32 +} + + + + + +unsigned long cIsThread::GetCurrentID(void) +{ + #ifdef _WIN32 + return (unsigned long) GetCurrentThreadId(); + #else + return (unsigned long) pthread_self(); + #endif +} + + + + diff --git a/source/cIsThread.h b/source/cIsThread.h index 20084dfad..e2d53565d 100644 --- a/source/cIsThread.h +++ b/source/cIsThread.h @@ -1,78 +1,78 @@ -
-// cIsThread.h
-
-// Interfaces to the cIsThread class representing an OS-independent wrapper for a class that implements a thread.
-// This class will eventually suupersede the old cThread class
-
-/*
-Usage:
-To have a new thread, declare a class descending from cIsClass.
-Then override its Execute() method to provide your thread processing.
-In the descending class' constructor call the Start() method to start the thread once you're finished with initialization.
-*/
-
-
-
-
-
-#pragma once
-#ifndef CISTHREAD_H_INCLUDED
-#define CISTHREAD_H_INCLUDED
-
-
-
-
-
-class cIsThread
-{
-protected:
- virtual void Execute(void) = 0; // This function is called in the new thread's context
-
- volatile bool m_ShouldTerminate; // The overriden Execute() method should check this periodically and terminate if this is true
-
-public:
- cIsThread(const AString & iThreadName);
- ~cIsThread();
-
- bool Start(void); // Starts the thread
- bool Wait(void); // Waits for the thread to finish
-
- static unsigned long GetCurrentID(void); // Returns the OS-dependent thread ID for the caller's thread
-
-private:
- AString m_ThreadName;
-
- #ifdef _WIN32
-
- HANDLE m_Handle;
-
- static DWORD_PTR __stdcall thrExecute(LPVOID a_Param)
- {
- ((cIsThread *)a_Param)->Execute();
- return 0;
- }
-
- #else // _WIN32
-
- pthread_t m_Handle;
- bool m_HasStarted;
-
- static void * thrExecute(void * a_Param)
- {
- ((cIsThread *)a_Param)->Execute();
- return NULL;
- }
-
- #endif // else _WIN32
-
-} ;
-
-
-
-
-
-#endif // CISTHREAD_H_INCLUDED
-
-
-
-
+ +// cIsThread.h + +// Interfaces to the cIsThread class representing an OS-independent wrapper for a class that implements a thread. +// This class will eventually suupersede the old cThread class + +/* +Usage: +To have a new thread, declare a class descending from cIsClass. +Then override its Execute() method to provide your thread processing. +In the descending class' constructor call the Start() method to start the thread once you're finished with initialization. +*/ + + + + + +#pragma once +#ifndef CISTHREAD_H_INCLUDED +#define CISTHREAD_H_INCLUDED + + + + + +class cIsThread +{ +protected: + virtual void Execute(void) = 0; // This function is called in the new thread's context + + volatile bool m_ShouldTerminate; // The overriden Execute() method should check this periodically and terminate if this is true + +public: + cIsThread(const AString & iThreadName); + ~cIsThread(); + + bool Start(void); // Starts the thread + bool Wait(void); // Waits for the thread to finish + + static unsigned long GetCurrentID(void); // Returns the OS-dependent thread ID for the caller's thread + +private: + AString m_ThreadName; + + #ifdef _WIN32 + + HANDLE m_Handle; + + static DWORD_PTR __stdcall thrExecute(LPVOID a_Param) + { + ((cIsThread *)a_Param)->Execute(); + return 0; + } + + #else // _WIN32 + + pthread_t m_Handle; + bool m_HasStarted; + + static void * thrExecute(void * a_Param) + { + ((cIsThread *)a_Param)->Execute(); + return NULL; + } + + #endif // else _WIN32 + +} ; + + + + + +#endif // CISTHREAD_H_INCLUDED + + + + diff --git a/source/cItem.cpp b/source/cItem.cpp index acb51611a..f13b9cbf3 100644 --- a/source/cItem.cpp +++ b/source/cItem.cpp @@ -1,51 +1,51 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cItem.h"
-#include <json/json.h>
-
-
-
-
-
-void cItem::GetJson( Json::Value & a_OutValue ) const
-{
- a_OutValue["ID"] = m_ItemID;
- if( m_ItemID > 0 )
- {
- a_OutValue["Count"] = m_ItemCount;
- a_OutValue["Health"] = m_ItemHealth;
- }
-}
-
-void cItem::FromJson( const Json::Value & a_Value )
-{
- m_ItemID = (ENUM_ITEM_ID)a_Value.get("ID", -1 ).asInt();
- if( m_ItemID > 0 )
- {
- m_ItemCount = (char)a_Value.get("Count", -1 ).asInt();
- m_ItemHealth = (short)a_Value.get("Health", -1 ).asInt();
- }
-}
-
-bool cItem::IsEnchantable(ENUM_ITEM_ID item)
-{
- if(item >= 256 && item <= 259)
- return true;
- if(item >= 267 && item <= 279)
- return true;
- if(item >= 283 && item <= 286)
- return true;
- if(item >= 290 && item <= 294)
- return true;
- if(item >= 298 && item <= 317)
- return true;
- if(item >= 290 && item <= 294)
- return true;
-
- if(item == 346 || item == 359 || item == 261)
- return true;
-
-
- return false;
-}
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cItem.h" +#include <json/json.h> + + + + + +void cItem::GetJson( Json::Value & a_OutValue ) const +{ + a_OutValue["ID"] = m_ItemID; + if( m_ItemID > 0 ) + { + a_OutValue["Count"] = m_ItemCount; + a_OutValue["Health"] = m_ItemHealth; + } +} + +void cItem::FromJson( const Json::Value & a_Value ) +{ + m_ItemID = (ENUM_ITEM_ID)a_Value.get("ID", -1 ).asInt(); + if( m_ItemID > 0 ) + { + m_ItemCount = (char)a_Value.get("Count", -1 ).asInt(); + m_ItemHealth = (short)a_Value.get("Health", -1 ).asInt(); + } +} + +bool cItem::IsEnchantable(ENUM_ITEM_ID item) +{ + if(item >= 256 && item <= 259) + return true; + if(item >= 267 && item <= 279) + return true; + if(item >= 283 && item <= 286) + return true; + if(item >= 290 && item <= 294) + return true; + if(item >= 298 && item <= 317) + return true; + if(item >= 290 && item <= 294) + return true; + + if(item == 346 || item == 359 || item == 261) + return true; + + + return false; +} diff --git a/source/cItem.h b/source/cItem.h index 28eed0d42..0f4aa6b70 100644 --- a/source/cItem.h +++ b/source/cItem.h @@ -1,114 +1,114 @@ -#pragma once
-
-#include "Defines.h"
-#include "BlockID.h"
-
-namespace Json
-{
- class Value;
-};
-
-
-
-
-
-// tolua_begin
-class cItem
-{
-public:
- cItem( ENUM_ITEM_ID a_ItemID = E_ITEM_EMPTY, char a_ItemCount = 0, short a_ItemHealth = 0 )
- : m_ItemID ( a_ItemID )
- , m_ItemCount ( a_ItemCount )
- , m_ItemHealth ( a_ItemHealth )
- {
- if(!IsValidItem( m_ItemID ) ) m_ItemID = E_ITEM_EMPTY;
- }
- void Empty()
- {
- m_ItemID = E_ITEM_EMPTY;
- m_ItemCount = 0;
- m_ItemHealth = 0;
- }
- void Clear(void)
- {
- m_ItemID = E_ITEM_EMPTY;
- m_ItemCount = 0;
- m_ItemHealth = 0;
- }
- bool IsEmpty(void) const
- {
- return (m_ItemID <= 0 || m_ItemCount <= 0);
- }
- bool Equals( cItem & a_Item ) const
- {
- return ( (m_ItemID == a_Item.m_ItemID) && (m_ItemHealth == a_Item.m_ItemHealth) );
- }
-
- // TODO Sorry for writing the functions in the header. But somehow it doesn´t worked when I put them into the cpp File :s
-
- inline int GetMaxDuration(void) const
- {
- switch(m_ItemID)
- {
- case 256: return 251;
- case 257: return 251;
- case 258: return 251;
- case 259: return 65; //Lighter / Flint and Steel
- case 267: return 251;
- case 268: return 60;
- case 269: return 60;
- case 270: return 60;
- case 271: return 60;
- case 272: return 132;
- case 273: return 132;
- case 274: return 132;
- case 275: return 132;
- case 276: return 1563;
- case 277: return 1563;
- case 278: return 1563;
- case 279: return 1563;
- case 283: return 32;
- case 284: return 32;
- case 285: return 32;
- case 286: return 32;
- case 290: return 60;
- case 291: return 132;
- case 292: return 251;
- case 293: return 1563;
- case 294: return 32;
- case 359: return 251;
- default: return 0;
- }
- }
-
- // Damages a weapon / tool. Returns true when destroyed
- inline bool DamageItem()
- {
- if (HasDuration())
- {
- m_ItemHealth++;
- if(m_ItemHealth >= GetMaxDuration())
- return true;
- }
- return false;
- }
-
- inline bool HasDuration() { return GetMaxDuration() > 0; }
-
- void GetJson( Json::Value & a_OutValue ) const;
- void FromJson( const Json::Value & a_Value );
-
- static bool IsEnchantable(ENUM_ITEM_ID item);
-
- ENUM_ITEM_ID m_ItemID;
- char m_ItemCount;
- short m_ItemHealth;
-
-};
-// tolua_end
-
-typedef std::vector<cItem> cItems;
-
-
-
-
+#pragma once + +#include "Defines.h" +#include "BlockID.h" + +namespace Json +{ + class Value; +}; + + + + + +// tolua_begin +class cItem +{ +public: + cItem( ENUM_ITEM_ID a_ItemID = E_ITEM_EMPTY, char a_ItemCount = 0, short a_ItemHealth = 0 ) + : m_ItemID ( a_ItemID ) + , m_ItemCount ( a_ItemCount ) + , m_ItemHealth ( a_ItemHealth ) + { + if(!IsValidItem( m_ItemID ) ) m_ItemID = E_ITEM_EMPTY; + } + void Empty() + { + m_ItemID = E_ITEM_EMPTY; + m_ItemCount = 0; + m_ItemHealth = 0; + } + void Clear(void) + { + m_ItemID = E_ITEM_EMPTY; + m_ItemCount = 0; + m_ItemHealth = 0; + } + bool IsEmpty(void) const + { + return (m_ItemID <= 0 || m_ItemCount <= 0); + } + bool Equals( cItem & a_Item ) const + { + return ( (m_ItemID == a_Item.m_ItemID) && (m_ItemHealth == a_Item.m_ItemHealth) ); + } + + // TODO Sorry for writing the functions in the header. But somehow it doesn´t worked when I put them into the cpp File :s + + inline int GetMaxDuration(void) const + { + switch(m_ItemID) + { + case 256: return 251; + case 257: return 251; + case 258: return 251; + case 259: return 65; //Lighter / Flint and Steel + case 267: return 251; + case 268: return 60; + case 269: return 60; + case 270: return 60; + case 271: return 60; + case 272: return 132; + case 273: return 132; + case 274: return 132; + case 275: return 132; + case 276: return 1563; + case 277: return 1563; + case 278: return 1563; + case 279: return 1563; + case 283: return 32; + case 284: return 32; + case 285: return 32; + case 286: return 32; + case 290: return 60; + case 291: return 132; + case 292: return 251; + case 293: return 1563; + case 294: return 32; + case 359: return 251; + default: return 0; + } + } + + // Damages a weapon / tool. Returns true when destroyed + inline bool DamageItem() + { + if (HasDuration()) + { + m_ItemHealth++; + if(m_ItemHealth >= GetMaxDuration()) + return true; + } + return false; + } + + inline bool HasDuration() { return GetMaxDuration() > 0; } + + void GetJson( Json::Value & a_OutValue ) const; + void FromJson( const Json::Value & a_Value ); + + static bool IsEnchantable(ENUM_ITEM_ID item); + + ENUM_ITEM_ID m_ItemID; + char m_ItemCount; + short m_ItemHealth; + +}; +// tolua_end + +typedef std::vector<cItem> cItems; + + + + diff --git a/source/cLadder.h b/source/cLadder.h index be3964f10..b3dc0fb96 100644 --- a/source/cLadder.h +++ b/source/cLadder.h @@ -1,43 +1,43 @@ -#pragma once
-
-class cLadder //tolua_export
-{ //tolua_export
-public:
-
- static char DirectionToMetaData( char a_Direction ) //tolua_export
- { //tolua_export
- switch( a_Direction )
- {
- case 0x2:
- return 0x2;
- case 0x3:
- return 0x3;
- case 0x4:
- return 0x4;
- case 0x5:
- return 0x5;
- default:
- break;
- };
- return 0x2;
- } //tolua_export
-
- static char MetaDataToDirection( char a_MetaData ) //tolua_export
- { //tolua_export
- switch( a_MetaData )
- {
- case 0x2:
- return 0x2;
- case 0x3:
- return 0x3;
- case 0x4:
- return 0x4;
- case 0x5:
- return 0x5;
- default:
- break;
- };
- return 0x2;
- } //tolua_export
-
+#pragma once + +class cLadder //tolua_export +{ //tolua_export +public: + + static char DirectionToMetaData( char a_Direction ) //tolua_export + { //tolua_export + switch( a_Direction ) + { + case 0x2: + return 0x2; + case 0x3: + return 0x3; + case 0x4: + return 0x4; + case 0x5: + return 0x5; + default: + break; + }; + return 0x2; + } //tolua_export + + static char MetaDataToDirection( char a_MetaData ) //tolua_export + { //tolua_export + switch( a_MetaData ) + { + case 0x2: + return 0x2; + case 0x3: + return 0x3; + case 0x4: + return 0x4; + case 0x5: + return 0x5; + default: + break; + }; + return 0x2; + } //tolua_export + }; //tolua_export
\ No newline at end of file diff --git a/source/cLavaSimulator.cpp b/source/cLavaSimulator.cpp index ad9afcdc8..6e3c2a3fa 100644 --- a/source/cLavaSimulator.cpp +++ b/source/cLavaSimulator.cpp @@ -1,20 +1,20 @@ -#include "Globals.h"
-#include "cLavaSimulator.h"
-#include "Defines.h"
-#include "cWorld.h"
-
-
-cLavaSimulator::cLavaSimulator(cWorld *a_World)
- : cFluidSimulator(a_World)
-{
- m_FluidBlock = E_BLOCK_LAVA;
- m_StationaryFluidBlock = E_BLOCK_STATIONARY_LAVA;
- m_MaxHeight = 6;
- m_FlowReduction = 2;
-}
-
-
-bool cLavaSimulator::IsAllowedBlock(char a_BlockID)
-{
- return IsBlockLava(a_BlockID);
+#include "Globals.h" +#include "cLavaSimulator.h" +#include "Defines.h" +#include "cWorld.h" + + +cLavaSimulator::cLavaSimulator(cWorld *a_World) + : cFluidSimulator(a_World) +{ + m_FluidBlock = E_BLOCK_LAVA; + m_StationaryFluidBlock = E_BLOCK_STATIONARY_LAVA; + m_MaxHeight = 6; + m_FlowReduction = 2; +} + + +bool cLavaSimulator::IsAllowedBlock(char a_BlockID) +{ + return IsBlockLava(a_BlockID); }
\ No newline at end of file diff --git a/source/cLavaSimulator.h b/source/cLavaSimulator.h index aa20b4d1d..44f9935dd 100644 --- a/source/cLavaSimulator.h +++ b/source/cLavaSimulator.h @@ -1,12 +1,12 @@ -#pragma once
-#include "cFluidSimulator.h"
-
-class cLavaSimulator : public cFluidSimulator
-{
-public:
- cLavaSimulator( cWorld* a_World );
-
- virtual bool IsAllowedBlock( char a_BlockID );
-
-
+#pragma once +#include "cFluidSimulator.h" + +class cLavaSimulator : public cFluidSimulator +{ +public: + cLavaSimulator( cWorld* a_World ); + + virtual bool IsAllowedBlock( char a_BlockID ); + + };
\ No newline at end of file diff --git a/source/cLog.cpp b/source/cLog.cpp index cf8448d8b..5e79b48bf 100644 --- a/source/cLog.cpp +++ b/source/cLog.cpp @@ -1,159 +1,159 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cLog.h"
-
-#include <fstream>
-#include <ctime>
-#include "cMakeDir.h"
-
-#include "cIsThread.h"
-
-
-
-
-
-cLog* cLog::s_Log = NULL;
-
-cLog::cLog(const AString & a_FileName )
- : m_File(NULL)
-{
- s_Log = this;
-
- // create logs directory
- cMakeDir::MakeDir("logs");
-
- OpenLog( (std::string("logs/") + a_FileName).c_str() );
-}
-
-
-
-
-
-cLog::~cLog()
-{
- CloseLog();
- s_Log = NULL;
-}
-
-
-
-
-
-cLog* cLog::GetInstance()
-{
- if(s_Log)
- return s_Log;
-
- new cLog("log.txt");
- return s_Log;
-}
-
-
-
-
-
-void cLog::CloseLog()
-{
- if( m_File )
- fclose (m_File);
- m_File = 0;
-}
-
-
-
-
-
-void cLog::OpenLog( const char* a_FileName )
-{
- if(m_File) fclose (m_File);
- #ifdef _WIN32
- fopen_s( &m_File, a_FileName, "a+" );
- #else
- m_File = fopen(a_FileName, "a+" );
- #endif
-}
-
-
-
-
-
-void cLog::ClearLog()
-{
- #ifdef _WIN32
- if( fopen_s( &m_File, "log.txt", "w" ) == 0)
- fclose (m_File);
- #else
- m_File = fopen("log.txt", "w" );
- if( m_File )
- fclose (m_File);
- #endif
- m_File = 0;
-}
-
-
-
-
-
-void cLog::Log(const char * a_Format, va_list argList)
-{
- AString Message;
- AppendVPrintf(Message, a_Format, argList);
-
- time_t rawtime;
- time ( &rawtime );
-
- struct tm* timeinfo;
-#ifdef _WIN32
- struct tm timeinforeal;
- timeinfo = &timeinforeal;
- localtime_s(timeinfo, &rawtime );
-#else
- timeinfo = localtime( &rawtime );
-#endif
-
- AString Line;
- #ifdef _DEBUG
- Printf(Line, "[%04x|%02d:%02d:%02d] %s\n", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str());
- #else
- Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str());
- #endif
- if (m_File)
- {
- fputs(Line.c_str(), m_File);
- fflush(m_File);
- }
-
- // Print to console:
- printf("%s", Line.c_str());
-
- #if defined (_WIN32) && defined(_DEBUG)
- // In a Windows Debug build, output the log to debug console as well:
- OutputDebugString(Line.c_str());
- #endif // _WIN32
-}
-
-
-
-
-
-void cLog::Log(const char* a_Format, ...)
-{
- va_list argList;
- va_start(argList, a_Format);
- Log( a_Format, argList );
- va_end(argList);
-}
-
-
-
-
-
-void cLog::SimpleLog(const char* a_String)
-{
- Log("%s", a_String );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cLog.h" + +#include <fstream> +#include <ctime> +#include "cMakeDir.h" + +#include "cIsThread.h" + + + + + +cLog* cLog::s_Log = NULL; + +cLog::cLog(const AString & a_FileName ) + : m_File(NULL) +{ + s_Log = this; + + // create logs directory + cMakeDir::MakeDir("logs"); + + OpenLog( (std::string("logs/") + a_FileName).c_str() ); +} + + + + + +cLog::~cLog() +{ + CloseLog(); + s_Log = NULL; +} + + + + + +cLog* cLog::GetInstance() +{ + if(s_Log) + return s_Log; + + new cLog("log.txt"); + return s_Log; +} + + + + + +void cLog::CloseLog() +{ + if( m_File ) + fclose (m_File); + m_File = 0; +} + + + + + +void cLog::OpenLog( const char* a_FileName ) +{ + if(m_File) fclose (m_File); + #ifdef _WIN32 + fopen_s( &m_File, a_FileName, "a+" ); + #else + m_File = fopen(a_FileName, "a+" ); + #endif +} + + + + + +void cLog::ClearLog() +{ + #ifdef _WIN32 + if( fopen_s( &m_File, "log.txt", "w" ) == 0) + fclose (m_File); + #else + m_File = fopen("log.txt", "w" ); + if( m_File ) + fclose (m_File); + #endif + m_File = 0; +} + + + + + +void cLog::Log(const char * a_Format, va_list argList) +{ + AString Message; + AppendVPrintf(Message, a_Format, argList); + + time_t rawtime; + time ( &rawtime ); + + struct tm* timeinfo; +#ifdef _WIN32 + struct tm timeinforeal; + timeinfo = &timeinforeal; + localtime_s(timeinfo, &rawtime ); +#else + timeinfo = localtime( &rawtime ); +#endif + + AString Line; + #ifdef _DEBUG + Printf(Line, "[%04x|%02d:%02d:%02d] %s\n", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); + #else + Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); + #endif + if (m_File) + { + fputs(Line.c_str(), m_File); + fflush(m_File); + } + + // Print to console: + printf("%s", Line.c_str()); + + #if defined (_WIN32) && defined(_DEBUG) + // In a Windows Debug build, output the log to debug console as well: + OutputDebugString(Line.c_str()); + #endif // _WIN32 +} + + + + + +void cLog::Log(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + Log( a_Format, argList ); + va_end(argList); +} + + + + + +void cLog::SimpleLog(const char* a_String) +{ + Log("%s", a_String ); +} + + + + diff --git a/source/cLog.h b/source/cLog.h index 1a688b0c0..f48dae822 100644 --- a/source/cLog.h +++ b/source/cLog.h @@ -1,32 +1,32 @@ -
-#pragma once
-
-#include "FileDefine.h"
-
-
-
-
-
-class cLog
-{ // tolua_export
-private:
- FILE * m_File;
- static cLog * s_Log;
-
-public:
- cLog(const AString & a_FileName);
- ~cLog();
- void Log(const char* a_Format, va_list argList );
- void Log(const char* a_Format, ...);
- //tolua_begin
- void SimpleLog(const char* a_String);
- void OpenLog( const char* a_FileName );
- void CloseLog();
- void ClearLog();
- static cLog* GetInstance();
-};
-//tolua_end
-
-
-
-
+ +#pragma once + +#include "FileDefine.h" + + + + + +class cLog +{ // tolua_export +private: + FILE * m_File; + static cLog * s_Log; + +public: + cLog(const AString & a_FileName); + ~cLog(); + void Log(const char* a_Format, va_list argList ); + void Log(const char* a_Format, ...); + //tolua_begin + void SimpleLog(const char* a_String); + void OpenLog( const char* a_FileName ); + void CloseLog(); + void ClearLog(); + static cLog* GetInstance(); +}; +//tolua_end + + + + diff --git a/source/cLuaChunk.cpp b/source/cLuaChunk.cpp index c97595599..a5f831ba7 100644 --- a/source/cLuaChunk.cpp +++ b/source/cLuaChunk.cpp @@ -1,4 +1,4 @@ -#include "Globals.h"
-
-#include "cLuaChunk.h"
-
+#include "Globals.h" + +#include "cLuaChunk.h" + diff --git a/source/cLuaChunk.h b/source/cLuaChunk.h index 70aa4e615..dc6f2a0f2 100644 --- a/source/cLuaChunk.h +++ b/source/cLuaChunk.h @@ -1,139 +1,139 @@ -#pragma once
-
-#include "ChunkDef.h"
-
-class cLuaChunk //tolua_export
-{ //tolua_export
-public:
- cLuaChunk( cChunkDef::BlockTypes & a_BlockTypes
- , cChunkDef::BlockNibbles & a_BlockNibbles
- , cChunkDef::HeightMap & a_HeightMap
- , cChunkDef::BiomeMap & a_BiomeMap
- )
- : m_BiomeMap( a_BiomeMap )
- , m_BlockTypes( a_BlockTypes )
- , m_BlockMeta( a_BlockNibbles )
- , m_HeightMap( a_HeightMap )
- , m_bUseDefaultBiomes( false )
- , m_bUseDefaultComposition( false )
- , m_bUseDefaultStructures( false )
- , m_bUseDefaultFinish( false )
- {
- memset( m_BlockTypes, 0, sizeof( cChunkDef::BlockTypes ) );
- memset( m_BlockMeta, 0, sizeof( cChunkDef::BlockNibbles ) );
- memset( m_BiomeMap, 0, sizeof( cChunkDef::BiomeMap ) );
- memset( m_HeightMap, 0, sizeof( cChunkDef::HeightMap ) );
- }
- ~cLuaChunk()
- {}
-
- //tolua_begin
-
- // Block functions
- void FillBlocks( char a_BlockID, unsigned char a_BlockMeta )
- {
- const NIBBLETYPE CompressedMeta = a_BlockMeta | a_BlockMeta << 4;
- memset( m_BlockTypes, a_BlockID, sizeof( cChunkDef::BlockTypes ) );
- memset( m_BlockMeta, CompressedMeta, sizeof( cChunkDef::BlockNibbles ) );
- }
-
- void SetBlock( int a_X, int a_Y, int a_Z, char a_BlockID, unsigned char a_BlockMeta )
- {
- cChunkDef::SetBlock( m_BlockTypes, a_X, a_Y, a_Z, a_BlockID );
- cChunkDef::SetNibble( m_BlockMeta, a_X, a_Y, a_Z, a_BlockMeta );
- }
-
- char GetBlock( int a_X, int a_Y, int a_Z )
- {
- return cChunkDef::GetBlock( m_BlockTypes, a_X, a_Y, a_Z );
- }
-
- char GetBlockMeta( int a_X, int a_Y, int a_Z )
- {
- return cChunkDef::GetNibble( m_BlockMeta, a_X, a_Y, a_Z );
- }
-
-
-
-
-
- // Biome functinos
- void SetBiome( int a_X, int a_Z, int a_BiomeID )
- {
- cChunkDef::SetBiome( m_BiomeMap, a_X, a_Z, (EMCSBiome)a_BiomeID );
- }
-
- int GetBiome( int a_X, int a_Z )
- {
- return cChunkDef::GetBiome( m_BiomeMap, a_X, a_Z );
- }
-
-
-
-
-
- // Height functions
- void SetHeight( int a_X, int a_Z, int a_Height )
- {
- cChunkDef::SetHeight( m_HeightMap, a_X, a_Z, a_Height );
- }
-
- int GetHeight( int a_X, int a_Z )
- {
- return cChunkDef::GetHeight( m_HeightMap, a_X, a_Z );
- }
-
-
-
-
-
- // Functions to explicitly tell the server to use default behavior for certain parts of generating terrain
- void SetUseDefaultBiomes( bool a_bUseDefaultBiomes )
- {
- m_bUseDefaultBiomes = a_bUseDefaultBiomes;
- }
- bool IsUsingDefaultBiomes()
- {
- return m_bUseDefaultBiomes;
- }
-
- void SetUseDefaultComposition( bool a_bUseDefaultComposition )
- {
- m_bUseDefaultComposition = a_bUseDefaultComposition;
- }
- bool IsUsingDefaultComposition()
- {
- return m_bUseDefaultComposition;
- }
-
- void SetUseDefaultStructures( bool a_bUseDefaultStructures )
- {
- m_bUseDefaultStructures = a_bUseDefaultStructures;
- }
- bool IsUsingDefaultStructures()
- {
- return m_bUseDefaultStructures;
- }
-
- void SetUseDefaultFinish( bool a_bUseDefaultFinish )
- {
- m_bUseDefaultFinish = a_bUseDefaultFinish;
- }
- bool IsUsingDefaultFinish()
- {
- return m_bUseDefaultFinish;
- }
-
- //tolua_end
-
-private:
- bool m_bUseDefaultBiomes;
- bool m_bUseDefaultComposition;
- bool m_bUseDefaultStructures;
- bool m_bUseDefaultFinish;
-
- cChunkDef::BiomeMap & m_BiomeMap;
- cChunkDef::BlockTypes & m_BlockTypes;
- cChunkDef::BlockNibbles & m_BlockMeta;
- cChunkDef::HeightMap & m_HeightMap;
+#pragma once + +#include "ChunkDef.h" + +class cLuaChunk //tolua_export +{ //tolua_export +public: + cLuaChunk( cChunkDef::BlockTypes & a_BlockTypes + , cChunkDef::BlockNibbles & a_BlockNibbles + , cChunkDef::HeightMap & a_HeightMap + , cChunkDef::BiomeMap & a_BiomeMap + ) + : m_BiomeMap( a_BiomeMap ) + , m_BlockTypes( a_BlockTypes ) + , m_BlockMeta( a_BlockNibbles ) + , m_HeightMap( a_HeightMap ) + , m_bUseDefaultBiomes( false ) + , m_bUseDefaultComposition( false ) + , m_bUseDefaultStructures( false ) + , m_bUseDefaultFinish( false ) + { + memset( m_BlockTypes, 0, sizeof( cChunkDef::BlockTypes ) ); + memset( m_BlockMeta, 0, sizeof( cChunkDef::BlockNibbles ) ); + memset( m_BiomeMap, 0, sizeof( cChunkDef::BiomeMap ) ); + memset( m_HeightMap, 0, sizeof( cChunkDef::HeightMap ) ); + } + ~cLuaChunk() + {} + + //tolua_begin + + // Block functions + void FillBlocks( char a_BlockID, unsigned char a_BlockMeta ) + { + const NIBBLETYPE CompressedMeta = a_BlockMeta | a_BlockMeta << 4; + memset( m_BlockTypes, a_BlockID, sizeof( cChunkDef::BlockTypes ) ); + memset( m_BlockMeta, CompressedMeta, sizeof( cChunkDef::BlockNibbles ) ); + } + + void SetBlock( int a_X, int a_Y, int a_Z, char a_BlockID, unsigned char a_BlockMeta ) + { + cChunkDef::SetBlock( m_BlockTypes, a_X, a_Y, a_Z, a_BlockID ); + cChunkDef::SetNibble( m_BlockMeta, a_X, a_Y, a_Z, a_BlockMeta ); + } + + char GetBlock( int a_X, int a_Y, int a_Z ) + { + return cChunkDef::GetBlock( m_BlockTypes, a_X, a_Y, a_Z ); + } + + char GetBlockMeta( int a_X, int a_Y, int a_Z ) + { + return cChunkDef::GetNibble( m_BlockMeta, a_X, a_Y, a_Z ); + } + + + + + + // Biome functinos + void SetBiome( int a_X, int a_Z, int a_BiomeID ) + { + cChunkDef::SetBiome( m_BiomeMap, a_X, a_Z, (EMCSBiome)a_BiomeID ); + } + + int GetBiome( int a_X, int a_Z ) + { + return cChunkDef::GetBiome( m_BiomeMap, a_X, a_Z ); + } + + + + + + // Height functions + void SetHeight( int a_X, int a_Z, int a_Height ) + { + cChunkDef::SetHeight( m_HeightMap, a_X, a_Z, a_Height ); + } + + int GetHeight( int a_X, int a_Z ) + { + return cChunkDef::GetHeight( m_HeightMap, a_X, a_Z ); + } + + + + + + // Functions to explicitly tell the server to use default behavior for certain parts of generating terrain + void SetUseDefaultBiomes( bool a_bUseDefaultBiomes ) + { + m_bUseDefaultBiomes = a_bUseDefaultBiomes; + } + bool IsUsingDefaultBiomes() + { + return m_bUseDefaultBiomes; + } + + void SetUseDefaultComposition( bool a_bUseDefaultComposition ) + { + m_bUseDefaultComposition = a_bUseDefaultComposition; + } + bool IsUsingDefaultComposition() + { + return m_bUseDefaultComposition; + } + + void SetUseDefaultStructures( bool a_bUseDefaultStructures ) + { + m_bUseDefaultStructures = a_bUseDefaultStructures; + } + bool IsUsingDefaultStructures() + { + return m_bUseDefaultStructures; + } + + void SetUseDefaultFinish( bool a_bUseDefaultFinish ) + { + m_bUseDefaultFinish = a_bUseDefaultFinish; + } + bool IsUsingDefaultFinish() + { + return m_bUseDefaultFinish; + } + + //tolua_end + +private: + bool m_bUseDefaultBiomes; + bool m_bUseDefaultComposition; + bool m_bUseDefaultStructures; + bool m_bUseDefaultFinish; + + cChunkDef::BiomeMap & m_BiomeMap; + cChunkDef::BlockTypes & m_BlockTypes; + cChunkDef::BlockNibbles & m_BlockMeta; + cChunkDef::HeightMap & m_HeightMap; }; //tolua_export
\ No newline at end of file diff --git a/source/cLuaCommandBinder.cpp b/source/cLuaCommandBinder.cpp index 712ea61c3..62d57b640 100644 --- a/source/cLuaCommandBinder.cpp +++ b/source/cLuaCommandBinder.cpp @@ -1,122 +1,122 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cLuaCommandBinder.h"
-#include "cPlayer.h"
-#include "cPlugin.h"
-#include "cPlugin_Lua.h"
-
-#include "tolua++.h"
-
-
-
-
-
-extern bool report_errors(lua_State* lua, int status);
-
-cLuaCommandBinder::cLuaCommandBinder()
-{
-}
-
-cLuaCommandBinder::~cLuaCommandBinder()
-{
-}
-
-void cLuaCommandBinder::ClearBindings()
-{
- m_BoundCommands.clear();
-}
-
-void cLuaCommandBinder::RemoveBindingsForPlugin( cPlugin* a_Plugin )
-{
- for( CommandMap::iterator itr = m_BoundCommands.begin(); itr != m_BoundCommands.end(); )
- {
- if( itr->second.Plugin == a_Plugin )
- {
- LOGINFO("Unbinding %s ", itr->first.c_str( ) );
- luaL_unref( itr->second.LuaState, LUA_REGISTRYINDEX, itr->second.Reference ); // unreference
- CommandMap::iterator eraseme = itr;
- ++itr;
- m_BoundCommands.erase( eraseme );
- continue;
- }
- ++itr;
- }
-}
-
-bool cLuaCommandBinder::BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, lua_State * a_LuaState, int a_FunctionReference )
-{
- if( !a_Plugin->CanBindCommands() )
- {
- LOGERROR("ERROR: Trying to bind command \"%s\" to a plugin that is not initialized.", a_Command.c_str() );
- return false;
- }
- if( m_BoundCommands.find( a_Command ) != m_BoundCommands.end() )
- {
- LOGERROR("ERROR: Trying to bind command \"%s\" that has already been bound.", a_Command.c_str() );
- return false;
- }
- LOGINFO("Binding %s (%s)", a_Command.c_str(), a_Permission.c_str() );
- m_BoundCommands[ a_Command ] = BoundFunction( a_Plugin, a_LuaState, a_FunctionReference, a_Permission );
- return true;
-}
-
-bool cLuaCommandBinder::HandleCommand( const std::string & a_Command, cPlayer* a_Player )
-{
- AStringVector Split = StringSplit(a_Command, " ");
- if (Split.size() == 0)
- {
- return false;
- }
-
- CommandMap::iterator FoundCommand = m_BoundCommands.find( Split[0] );
- if( FoundCommand != m_BoundCommands.end() )
- {
- const BoundFunction & func = FoundCommand->second;
- if( func.Permission.size() > 0 )
- {
- if( !a_Player->HasPermission( func.Permission.c_str() ) )
- {
- return false;
- }
- }
-
- // For enabling 'self' in the function, it's kind of a hack I'm not sure this is the way to go
- lua_pushvalue(func.LuaState, LUA_GLOBALSINDEX);
- lua_pushstring(func.LuaState, "self");
- tolua_pushusertype( func.LuaState, func.Plugin, "cPlugin" );
- lua_rawset(func.LuaState, -3);
- lua_pop(func.LuaState, 1);
-
- LOGINFO("1. Stack size: %i", lua_gettop(func.LuaState) );
- lua_rawgeti( func.LuaState, LUA_REGISTRYINDEX, func.Reference); // same as lua_getref()
-
- // Push the split
- LOGINFO("2. Stack size: %i", lua_gettop(func.LuaState) );
- lua_createtable(func.LuaState, Split.size(), 0);
- int newTable = lua_gettop(func.LuaState);
- int index = 1;
- std::vector<std::string>::const_iterator iter = Split.begin();
- while(iter != Split.end()) {
- tolua_pushstring( func.LuaState, (*iter).c_str() );
- lua_rawseti(func.LuaState, newTable, index);
- ++iter;
- ++index;
- }
- LOGINFO("3. Stack size: %i", lua_gettop(func.LuaState) );
- // Push player
- tolua_pushusertype( func.LuaState, a_Player, "cPlayer" );
- LOGINFO("Calling bound function! :D");
- int s = lua_pcall(func.LuaState, 2, 1, 0);
- if( report_errors( func.LuaState, s ) )
- {
- LOGINFO("error. Stack size: %i", lua_gettop(func.LuaState) );
- return false;
- }
- bool RetVal = (tolua_toboolean(func.LuaState, -1, 0) > 0);
- lua_pop(func.LuaState, 1); // Pop return value
- LOGINFO("ok. Stack size: %i", lua_gettop(func.LuaState) );
- return RetVal;
- }
- return false;
-}
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cLuaCommandBinder.h" +#include "cPlayer.h" +#include "cPlugin.h" +#include "cPlugin_Lua.h" + +#include "tolua++.h" + + + + + +extern bool report_errors(lua_State* lua, int status); + +cLuaCommandBinder::cLuaCommandBinder() +{ +} + +cLuaCommandBinder::~cLuaCommandBinder() +{ +} + +void cLuaCommandBinder::ClearBindings() +{ + m_BoundCommands.clear(); +} + +void cLuaCommandBinder::RemoveBindingsForPlugin( cPlugin* a_Plugin ) +{ + for( CommandMap::iterator itr = m_BoundCommands.begin(); itr != m_BoundCommands.end(); ) + { + if( itr->second.Plugin == a_Plugin ) + { + LOGINFO("Unbinding %s ", itr->first.c_str( ) ); + luaL_unref( itr->second.LuaState, LUA_REGISTRYINDEX, itr->second.Reference ); // unreference + CommandMap::iterator eraseme = itr; + ++itr; + m_BoundCommands.erase( eraseme ); + continue; + } + ++itr; + } +} + +bool cLuaCommandBinder::BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, lua_State * a_LuaState, int a_FunctionReference ) +{ + if( !a_Plugin->CanBindCommands() ) + { + LOGERROR("ERROR: Trying to bind command \"%s\" to a plugin that is not initialized.", a_Command.c_str() ); + return false; + } + if( m_BoundCommands.find( a_Command ) != m_BoundCommands.end() ) + { + LOGERROR("ERROR: Trying to bind command \"%s\" that has already been bound.", a_Command.c_str() ); + return false; + } + LOGINFO("Binding %s (%s)", a_Command.c_str(), a_Permission.c_str() ); + m_BoundCommands[ a_Command ] = BoundFunction( a_Plugin, a_LuaState, a_FunctionReference, a_Permission ); + return true; +} + +bool cLuaCommandBinder::HandleCommand( const std::string & a_Command, cPlayer* a_Player ) +{ + AStringVector Split = StringSplit(a_Command, " "); + if (Split.size() == 0) + { + return false; + } + + CommandMap::iterator FoundCommand = m_BoundCommands.find( Split[0] ); + if( FoundCommand != m_BoundCommands.end() ) + { + const BoundFunction & func = FoundCommand->second; + if( func.Permission.size() > 0 ) + { + if( !a_Player->HasPermission( func.Permission.c_str() ) ) + { + return false; + } + } + + // For enabling 'self' in the function, it's kind of a hack I'm not sure this is the way to go + lua_pushvalue(func.LuaState, LUA_GLOBALSINDEX); + lua_pushstring(func.LuaState, "self"); + tolua_pushusertype( func.LuaState, func.Plugin, "cPlugin" ); + lua_rawset(func.LuaState, -3); + lua_pop(func.LuaState, 1); + + LOGINFO("1. Stack size: %i", lua_gettop(func.LuaState) ); + lua_rawgeti( func.LuaState, LUA_REGISTRYINDEX, func.Reference); // same as lua_getref() + + // Push the split + LOGINFO("2. Stack size: %i", lua_gettop(func.LuaState) ); + lua_createtable(func.LuaState, Split.size(), 0); + int newTable = lua_gettop(func.LuaState); + int index = 1; + std::vector<std::string>::const_iterator iter = Split.begin(); + while(iter != Split.end()) { + tolua_pushstring( func.LuaState, (*iter).c_str() ); + lua_rawseti(func.LuaState, newTable, index); + ++iter; + ++index; + } + LOGINFO("3. Stack size: %i", lua_gettop(func.LuaState) ); + // Push player + tolua_pushusertype( func.LuaState, a_Player, "cPlayer" ); + LOGINFO("Calling bound function! :D"); + int s = lua_pcall(func.LuaState, 2, 1, 0); + if( report_errors( func.LuaState, s ) ) + { + LOGINFO("error. Stack size: %i", lua_gettop(func.LuaState) ); + return false; + } + bool RetVal = (tolua_toboolean(func.LuaState, -1, 0) > 0); + lua_pop(func.LuaState, 1); // Pop return value + LOGINFO("ok. Stack size: %i", lua_gettop(func.LuaState) ); + return RetVal; + } + return false; +} diff --git a/source/cLuaCommandBinder.h b/source/cLuaCommandBinder.h index b623c5c92..768d097f8 100644 --- a/source/cLuaCommandBinder.h +++ b/source/cLuaCommandBinder.h @@ -1,42 +1,42 @@ -
-#pragma once
-
-struct lua_State;
-class cPlugin;
-class cPlayer;
-
-
-
-
-
-class cLuaCommandBinder
-{
-public:
- cLuaCommandBinder();
- ~cLuaCommandBinder();
-
- bool HandleCommand( const std::string & a_Command, cPlayer* a_Player );
-
- bool BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, lua_State * a_LuaState, int a_FunctionReference );
-
- void ClearBindings();
- void RemoveBindingsForPlugin( cPlugin* a_Plugin );
-private:
- struct BoundFunction
- {
- BoundFunction() : Plugin( 0 ), LuaState( 0 ), Reference( 0 ) {}
- BoundFunction( cPlugin* a_Plugin, lua_State * a_LuaState, int a_Reference, const std::string & a_Permission ) : Plugin( a_Plugin ), LuaState( a_LuaState ), Reference( a_Reference ), Permission( a_Permission ) {}
- cPlugin* Plugin;
- lua_State* LuaState;
- int Reference;
- std::string Permission;
- };
-
- typedef std::map< std::string, BoundFunction > CommandMap;
- CommandMap m_BoundCommands;
-};
-
-
-
-
-
+ +#pragma once + +struct lua_State; +class cPlugin; +class cPlayer; + + + + + +class cLuaCommandBinder +{ +public: + cLuaCommandBinder(); + ~cLuaCommandBinder(); + + bool HandleCommand( const std::string & a_Command, cPlayer* a_Player ); + + bool BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, lua_State * a_LuaState, int a_FunctionReference ); + + void ClearBindings(); + void RemoveBindingsForPlugin( cPlugin* a_Plugin ); +private: + struct BoundFunction + { + BoundFunction() : Plugin( 0 ), LuaState( 0 ), Reference( 0 ) {} + BoundFunction( cPlugin* a_Plugin, lua_State * a_LuaState, int a_Reference, const std::string & a_Permission ) : Plugin( a_Plugin ), LuaState( a_LuaState ), Reference( a_Reference ), Permission( a_Permission ) {} + cPlugin* Plugin; + lua_State* LuaState; + int Reference; + std::string Permission; + }; + + typedef std::map< std::string, BoundFunction > CommandMap; + CommandMap m_BoundCommands; +}; + + + + + diff --git a/source/cMCLogger.cpp b/source/cMCLogger.cpp index 0869daa53..4e0823d14 100644 --- a/source/cMCLogger.cpp +++ b/source/cMCLogger.cpp @@ -1,191 +1,191 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include <time.h>
-#include "cLog.h"
-
-
-
-
-
-cMCLogger* cMCLogger::s_MCLogger = 0;
-
-cMCLogger* cMCLogger::GetInstance()
-{
- return s_MCLogger;
-}
-
-
-
-
-
-cMCLogger::cMCLogger()
-{
- AString FileName;
- Printf(FileName, "LOG_%d.txt", (int)time(0) );
- m_Log = new cLog(FileName);
- m_Log->Log("--- Started Log ---");
-
- s_MCLogger = this;
-}
-
-
-
-
-
-cMCLogger::cMCLogger( char* a_File )
-{
- m_Log = new cLog( a_File );
-}
-
-
-
-
-
-cMCLogger::~cMCLogger()
-{
- m_Log->Log("--- Stopped Log ---");
- delete m_Log;
- if (this == s_MCLogger)
- s_MCLogger = NULL;
-}
-
-
-
-
-
-void cMCLogger::LogSimple(const char* a_Text, int a_LogType /* = 0 */ )
-{
- switch( a_LogType )
- {
- case 0:
- LOG("%s", a_Text);
- break;
- case 1:
- LOGINFO("%s", a_Text);
- break;
- case 2:
- LOGWARN("%s", a_Text);
- break;
- case 3:
- LOGERROR("%s", a_Text);
- break;
- default:
- LOG("(#%d#: %s", a_LogType, a_Text);
- break;
- }
-}
-
-
-
-
-
-void cMCLogger::Log(const char* a_Format, va_list a_ArgList)
-{
- cCSLock Lock(m_CriticalSection);
- SetColor( 0x7 ); // 0x7 is default grey color
- m_Log->Log( a_Format, a_ArgList );
- SetColor(0x07); // revert color back
-}
-
-
-
-
-
-void cMCLogger::Info(const char* a_Format, va_list a_ArgList)
-{
- cCSLock Lock(m_CriticalSection);
-// for( int i = 0; i < 16; i++)
-// {
-// for( int j = 0; j < 16; j++ )
-// {
-// SetConsoleTextAttribute( hConsole, i | (j<<4) );
-// printf("0x%x", (i|j<<4));
-// }
-// printf("\n");
-// }
-
- SetColor( 0xe ); // 0xe is yellow
- m_Log->Log( a_Format, a_ArgList );
- SetColor(0x07); // revert color back
-}
-
-
-
-
-
-void cMCLogger::Warn(const char* a_Format, va_list a_ArgList)
-{
- cCSLock Lock(m_CriticalSection);
- SetColor( 0xc ); // 0xc is red
- m_Log->Log( a_Format, a_ArgList );
- SetColor(0x07); // revert color back
-}
-
-
-
-
-
-void cMCLogger::Error(const char* a_Format, va_list a_ArgList)
-{
- cCSLock Lock(m_CriticalSection);
- SetColor( 0xc0 ); // 0xc0 is red bg and black text
- m_Log->Log( a_Format, a_ArgList );
- SetColor(0x07); // revert color back
-}
-
-
-
-
-
-void cMCLogger::SetColor( unsigned char a_Color )
-{
-#ifdef _WIN32
- HANDLE hConsole = GetStdHandle( STD_OUTPUT_HANDLE );
- SetConsoleTextAttribute( hConsole, a_Color );
-#else
- (void)a_Color;
-#endif
-}
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////
-// Global functions
-void LOG(const char* a_Format, ...)
-{
- va_list argList;
- va_start(argList, a_Format);
- cMCLogger::GetInstance()->Log( a_Format, argList );
- va_end(argList);
-}
-
-void LOGINFO(const char* a_Format, ...)
-{
- va_list argList;
- va_start(argList, a_Format);
- cMCLogger::GetInstance()->Info( a_Format, argList );
- va_end(argList);
-}
-
-void LOGWARN(const char* a_Format, ...)
-{
- va_list argList;
- va_start(argList, a_Format);
- cMCLogger::GetInstance()->Warn( a_Format, argList );
- va_end(argList);
-}
-
-void LOGERROR(const char* a_Format, ...)
-{
- va_list argList;
- va_start(argList, a_Format);
- cMCLogger::GetInstance()->Error( a_Format, argList );
- va_end(argList);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include <time.h> +#include "cLog.h" + + + + + +cMCLogger* cMCLogger::s_MCLogger = 0; + +cMCLogger* cMCLogger::GetInstance() +{ + return s_MCLogger; +} + + + + + +cMCLogger::cMCLogger() +{ + AString FileName; + Printf(FileName, "LOG_%d.txt", (int)time(0) ); + m_Log = new cLog(FileName); + m_Log->Log("--- Started Log ---"); + + s_MCLogger = this; +} + + + + + +cMCLogger::cMCLogger( char* a_File ) +{ + m_Log = new cLog( a_File ); +} + + + + + +cMCLogger::~cMCLogger() +{ + m_Log->Log("--- Stopped Log ---"); + delete m_Log; + if (this == s_MCLogger) + s_MCLogger = NULL; +} + + + + + +void cMCLogger::LogSimple(const char* a_Text, int a_LogType /* = 0 */ ) +{ + switch( a_LogType ) + { + case 0: + LOG("%s", a_Text); + break; + case 1: + LOGINFO("%s", a_Text); + break; + case 2: + LOGWARN("%s", a_Text); + break; + case 3: + LOGERROR("%s", a_Text); + break; + default: + LOG("(#%d#: %s", a_LogType, a_Text); + break; + } +} + + + + + +void cMCLogger::Log(const char* a_Format, va_list a_ArgList) +{ + cCSLock Lock(m_CriticalSection); + SetColor( 0x7 ); // 0x7 is default grey color + m_Log->Log( a_Format, a_ArgList ); + SetColor(0x07); // revert color back +} + + + + + +void cMCLogger::Info(const char* a_Format, va_list a_ArgList) +{ + cCSLock Lock(m_CriticalSection); +// for( int i = 0; i < 16; i++) +// { +// for( int j = 0; j < 16; j++ ) +// { +// SetConsoleTextAttribute( hConsole, i | (j<<4) ); +// printf("0x%x", (i|j<<4)); +// } +// printf("\n"); +// } + + SetColor( 0xe ); // 0xe is yellow + m_Log->Log( a_Format, a_ArgList ); + SetColor(0x07); // revert color back +} + + + + + +void cMCLogger::Warn(const char* a_Format, va_list a_ArgList) +{ + cCSLock Lock(m_CriticalSection); + SetColor( 0xc ); // 0xc is red + m_Log->Log( a_Format, a_ArgList ); + SetColor(0x07); // revert color back +} + + + + + +void cMCLogger::Error(const char* a_Format, va_list a_ArgList) +{ + cCSLock Lock(m_CriticalSection); + SetColor( 0xc0 ); // 0xc0 is red bg and black text + m_Log->Log( a_Format, a_ArgList ); + SetColor(0x07); // revert color back +} + + + + + +void cMCLogger::SetColor( unsigned char a_Color ) +{ +#ifdef _WIN32 + HANDLE hConsole = GetStdHandle( STD_OUTPUT_HANDLE ); + SetConsoleTextAttribute( hConsole, a_Color ); +#else + (void)a_Color; +#endif +} + + + + + +////////////////////////////////////////////////////////////////////////// +// Global functions +void LOG(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cMCLogger::GetInstance()->Log( a_Format, argList ); + va_end(argList); +} + +void LOGINFO(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cMCLogger::GetInstance()->Info( a_Format, argList ); + va_end(argList); +} + +void LOGWARN(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cMCLogger::GetInstance()->Warn( a_Format, argList ); + va_end(argList); +} + +void LOGERROR(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cMCLogger::GetInstance()->Error( a_Format, argList ); + va_end(argList); +} + + + + diff --git a/source/cMCLogger.h b/source/cMCLogger.h index b483fb0b8..04ba732bf 100644 --- a/source/cMCLogger.h +++ b/source/cMCLogger.h @@ -1,60 +1,60 @@ -
-#pragma once
-
-
-
-
-class cLog;
-
-
-
-
-
-class cMCLogger //tolua_export
-{ //tolua_export
-public: //tolua_export
- cMCLogger();
- cMCLogger( char* a_File ); //tolua_export
- ~cMCLogger(); //tolua_export
-
- void Log(const char* a_Format, va_list a_ArgList);
- void Info(const char* a_Format, va_list a_ArgList);
- void Warn(const char* a_Format, va_list a_ArgList);
- void Error(const char* a_Format, va_list a_ArgList);
-
- void LogSimple(const char* a_Text, int a_LogType = 0 ); //tolua_export
-
- static cMCLogger* GetInstance();
-private:
- void SetColor( unsigned char a_Color );
-
- cCriticalSection m_CriticalSection;
- cLog* m_Log;
- static cMCLogger* s_MCLogger;
-}; //tolua_export
-
-extern void LOG(const char* a_Format, ...);
-extern void LOGINFO(const char* a_Format, ...);
-extern void LOGWARN(const char* a_Format, ...);
-extern void LOGERROR(const char* a_Format, ...);
-
-
-
-
-
-// In debug builds, translate LOGD to LOG, otherwise leave it out altogether:
-#ifdef _DEBUG
- #define LOGD LOG
-#else
- #define LOGD(...)
-#endif // _DEBUG
-
-
-
-
-
-#define LOGWARNING LOGWARN
-
-
-
-
+ +#pragma once + + + + +class cLog; + + + + + +class cMCLogger //tolua_export +{ //tolua_export +public: //tolua_export + cMCLogger(); + cMCLogger( char* a_File ); //tolua_export + ~cMCLogger(); //tolua_export + + void Log(const char* a_Format, va_list a_ArgList); + void Info(const char* a_Format, va_list a_ArgList); + void Warn(const char* a_Format, va_list a_ArgList); + void Error(const char* a_Format, va_list a_ArgList); + + void LogSimple(const char* a_Text, int a_LogType = 0 ); //tolua_export + + static cMCLogger* GetInstance(); +private: + void SetColor( unsigned char a_Color ); + + cCriticalSection m_CriticalSection; + cLog* m_Log; + static cMCLogger* s_MCLogger; +}; //tolua_export + +extern void LOG(const char* a_Format, ...); +extern void LOGINFO(const char* a_Format, ...); +extern void LOGWARN(const char* a_Format, ...); +extern void LOGERROR(const char* a_Format, ...); + + + + + +// In debug builds, translate LOGD to LOG, otherwise leave it out altogether: +#ifdef _DEBUG + #define LOGD LOG +#else + #define LOGD(...) +#endif // _DEBUG + + + + + +#define LOGWARNING LOGWARN + + + + diff --git a/source/cMakeDir.cpp b/source/cMakeDir.cpp index a28b3a088..a9e35cece 100644 --- a/source/cMakeDir.cpp +++ b/source/cMakeDir.cpp @@ -1,25 +1,25 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cMakeDir.h"
-
-
-
-
-
-void cMakeDir::MakeDir(const AString & a_Directory)
-{
-#ifdef _WIN32
- SECURITY_ATTRIBUTES Attrib;
- Attrib.nLength = sizeof(SECURITY_ATTRIBUTES);
- Attrib.lpSecurityDescriptor = NULL;
- Attrib.bInheritHandle = false;
- ::CreateDirectory(a_Directory.c_str(), &Attrib);
-#else
- mkdir(a_Directory.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
-#endif
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cMakeDir.h" + + + + + +void cMakeDir::MakeDir(const AString & a_Directory) +{ +#ifdef _WIN32 + SECURITY_ATTRIBUTES Attrib; + Attrib.nLength = sizeof(SECURITY_ATTRIBUTES); + Attrib.lpSecurityDescriptor = NULL; + Attrib.bInheritHandle = false; + ::CreateDirectory(a_Directory.c_str(), &Attrib); +#else + mkdir(a_Directory.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); +#endif +} + + + + diff --git a/source/cMakeDir.h b/source/cMakeDir.h index f109e17dd..e66cf1071 100644 --- a/source/cMakeDir.h +++ b/source/cMakeDir.h @@ -1,16 +1,16 @@ -
-#pragma once
-
-
-
-
-
-class cMakeDir
-{
-public:
- static void MakeDir(const AString & a_Directory);
-};
-
-
-
-
+ +#pragma once + + + + + +class cMakeDir +{ +public: + static void MakeDir(const AString & a_Directory); +}; + + + + diff --git a/source/cMonster.cpp b/source/cMonster.cpp index 7834b855a..3c73cae8a 100644 --- a/source/cMonster.cpp +++ b/source/cMonster.cpp @@ -1,560 +1,560 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cMonster.h"
-#include "cRoot.h"
-#include "cServer.h"
-#include "cClientHandle.h"
-#include "cWorld.h"
-#include "cPlayer.h"
-#include "Defines.h"
-#include "cMonsterConfig.h"
-#include "MersenneTwister.h"
-
-#include "packets/cPacket_SpawnMob.h"
-#include "packets/cPacket_EntityLook.h"
-#include "packets/cPacket_TeleportEntity.h"
-#include "packets/cPacket_RelativeEntityMoveLook.h"
-#include "packets/cPacket_RelativeEntityMove.h"
-#include "packets/cPacket_Metadata.h"
-
-#include "Vector3f.h"
-#include "Vector3i.h"
-#include "Vector3d.h"
-
-#include "cTracer.h"
-#include "../iniFile/iniFile.h"
-
-#ifndef _WIN32
- #include <cstdlib> // rand
- #include <unistd.h>
-#endif
-
-
-
-
-
-cMonster::cMonster()
- : m_Target(0)
- , m_bMovingToDestination(false)
- , m_DestinationTime( 0 )
- , m_Gravity( -9.81f)
- , m_bOnGround( false )
- , m_DestroyTimer( 0 )
- , m_Jump(0)
- , m_MobType( 0 )
- , m_EMState(IDLE)
- , m_SightDistance(25)
- , m_SeePlayerInterval (0)
- , m_EMPersonality(AGGRESSIVE)
- , m_AttackDamage(1.0f)
- , m_AttackRange(5.0f)
- , m_AttackInterval(0)
- , m_AttackRate(3)
- , idle_interval(0)
-{
- LOG("cMonster::cMonster()");
- LOG("In state: %s", GetState());
-
- m_bBurnable = true;
- m_MetaData = NORMAL;
-}
-
-cMonster::~cMonster()
-{
- LOG("cMonster::~cMonster()");
-}
-
-bool cMonster::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cMonster" ) == 0 ) return true;
- return cPawn::IsA( a_EntityType );
-}
-
-
-
-
-
-cPacket * cMonster::GetSpawnPacket(void) const
-{
- cPacket_SpawnMob * Spawn = new cPacket_SpawnMob;
- Spawn->m_UniqueID = GetUniqueID();
- Spawn->m_Type = m_MobType;
- *Spawn->m_Pos = ((Vector3i)(m_Pos)) * 32;
- Spawn->m_Yaw = 0;
- Spawn->m_Pitch = 0;
- Spawn->m_MetaDataSize = 1;
- Spawn->m_MetaData = new char[Spawn->m_MetaDataSize];
- Spawn->m_MetaData[0] = 0x7f; // not on fire/crouching/riding
- return Spawn;
-}
-
-
-
-
-
-void cMonster::MoveToPosition( const Vector3f & a_Position )
-{
- m_bMovingToDestination = true;
-
- m_Destination = a_Position;
-}
-
-bool cMonster::ReachedDestination()
-{
- Vector3f Distance = (m_Destination) - Vector3f( m_Pos );
- if( Distance.SqrLength() < 2.f )
- return true;
-
- return false;
-}
-
-
-
-
-
-void cMonster::Tick(float a_Dt)
-{
- cPawn::Tick(a_Dt);
-
- if( m_Health <= 0 )
- {
- m_DestroyTimer += a_Dt/1000;
- if( m_DestroyTimer > 1 )
- {
- Destroy();
- }
- return;
- }
-
- a_Dt /= 1000;
-
- if( m_bMovingToDestination )
- {
- Vector3f Pos( m_Pos );
- Vector3f Distance = m_Destination - Pos;
- if( !ReachedDestination() )
- {
- Distance.y = 0;
- Distance.Normalize();
- Distance *= 3;
- m_Speed.x = Distance.x;
- m_Speed.z = Distance.z;
-
- if (m_EMState == ESCAPING)
- { //Runs Faster when escaping :D otherwise they just walk away
- m_Speed.x *= 2.f;
- m_Speed.z *= 2.f;
- }
- }
- else
- {
- m_bMovingToDestination = false;
- }
-
- if( m_Speed.SqrLength() > 0.f )
- {
- if( m_bOnGround )
- {
- Vector3f NormSpeed = m_Speed.NormalizeCopy();
- Vector3f NextBlock = Vector3f( m_Pos ) + NormSpeed;
- double NextHeight = (double)GetWorld()->GetHeight( (int)NextBlock.x, (int)NextBlock.z );
- if( NextHeight > m_Pos.y - 1.2 && NextHeight - m_Pos.y < 2.5 )
- {
- m_bOnGround = false;
- m_Speed.y = 7.f; // Jump!!
- }
- }
- }
- }
-
- HandlePhysics( a_Dt );
-
- ReplicateMovement();
-
- Vector3f Distance = m_Destination - Vector3f( m_Pos );
- if( Distance.SqrLength() > 0.1f )
- {
- float Rotation, Pitch;
- Distance.Normalize();
- VectorToEuler( Distance.x, Distance.y, Distance.z, Rotation, Pitch );
- SetRotation( Rotation );
- SetPitch( Pitch );
- }
-
- if(m_EMState == IDLE) { //If enemy passive we ignore checks for player visibility
- InStateIdle(a_Dt);
- }
-
- if(m_EMState == CHASING) { //If we do not see a player anymore skip chasing action
- InStateChasing(a_Dt);
- }
-
- if(m_EMState == ESCAPING) {
- InStateEscaping(a_Dt);
- }
-
-}
-
-
-
-
-
-void cMonster::ReplicateMovement()
-{
- if(m_bDirtyOrientation && !m_bDirtyPosition)
- {
- cPacket_EntityLook EntityLook(*this);
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityLook );
- m_bDirtyOrientation = false;
- }
-
- if( m_bDirtyPosition )
- {
- float DiffX = (float)(GetPosX() - m_LastPosX );
- float DiffY = (float)(GetPosY() - m_LastPosY );
- float DiffZ = (float)(GetPosZ() - m_LastPosZ );
- float SqrDist = DiffX*DiffX + DiffY*DiffY + DiffZ*DiffZ;
- if (
- (SqrDist > 4 * 4) // 4 blocks is max Relative Move
- || (cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds
- )
- {
- //LOG("Teleported %f", sqrtf(SqrDist) );
- cPacket_TeleportEntity TeleportEntity( this );
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity);
- m_TimeLastTeleportPacket = cWorld::GetTime();
- }
- else
- { // Relative move sucks balls! It's always wrong wtf!
- if( m_bDirtyOrientation )
- {
- cPacket_RelativeEntityMoveLook RelativeEntityMoveLook;
- RelativeEntityMoveLook.m_UniqueID = GetUniqueID();
- RelativeEntityMoveLook.m_MoveX = (char)(DiffX*32);
- RelativeEntityMoveLook.m_MoveY = (char)(DiffY*32);
- RelativeEntityMoveLook.m_MoveZ = (char)(DiffZ*32);
- RelativeEntityMoveLook.m_Yaw = (char)((GetRotation()/360.f)*256);
- RelativeEntityMoveLook.m_Pitch = (char)((GetPitch()/360.f)*256);
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMoveLook );
- }
- else
- {
- cPacket_RelativeEntityMove RelativeEntityMove;
- RelativeEntityMove.m_UniqueID = GetUniqueID();
- RelativeEntityMove.m_MoveX = (char)(DiffX*32);
- RelativeEntityMove.m_MoveY = (char)(DiffY*32);
- RelativeEntityMove.m_MoveZ = (char)(DiffZ*32);
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMove );
- }
- }
- m_LastPosX = GetPosX();
- m_LastPosY = GetPosY();
- m_LastPosZ = GetPosZ();
- m_bDirtyPosition = false;
- }
-
- MoveToCorrectChunk();
-}
-
-
-
-
-
-void cMonster::HandlePhysics(float a_Dt)
-{
- if( m_bOnGround ) // check if it's still on the ground
- {
- cWorld* World = GetWorld();
- if( World->GetBlock( (int)m_Pos.x, (int)m_Pos.y -1, (int)m_Pos.z ) == E_BLOCK_AIR )
- {
- m_bOnGround = false;
- }
- if( World->GetBlock( (int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z ) != E_BLOCK_AIR ) // If in ground itself, push it out
- {
- m_bOnGround = true;
- m_Pos.y += 0.2;
- m_bDirtyPosition = true;
- }
- m_Speed.x *= 0.7f/(1+a_Dt);
- if( fabs(m_Speed.x) < 0.05 ) m_Speed.x = 0;
- m_Speed.z *= 0.7f/(1+a_Dt);
- if( fabs(m_Speed.z) < 0.05 ) m_Speed.z = 0;
- }
-
- if( !m_bOnGround )
- {
- float Gravity = -9.81f*a_Dt;
- m_Speed.y += Gravity;
- }
-
- if( m_Speed.SqrLength() > 0.f )
- {
- cTracer Tracer( GetWorld() );
- int Ret = Tracer.Trace( m_Pos, m_Speed, 2 );
- if( Ret ) // Oh noez! we hit something
- {
- // Set to hit position
- if( (Tracer.RealHit - Vector3f(m_Pos)).SqrLength() <= ( m_Speed * a_Dt ).SqrLength() )
- {
- if( Ret == 1 )
- {
-
- if( Tracer.HitNormal.x != 0.f ) m_Speed.x = 0.f;
- if( Tracer.HitNormal.y != 0.f ) m_Speed.y = 0.f;
- if( Tracer.HitNormal.z != 0.f ) m_Speed.z = 0.f;
-
- if( Tracer.HitNormal.y > 0 ) // means on ground
- {
- m_bOnGround = true;
- }
- }
- m_Pos = Tracer.RealHit;
- m_Pos += Tracer.HitNormal * 0.2f;
-
- }
- else
- m_Pos += m_Speed*a_Dt;
- }
- else
- { // We didn't hit anything, so move =]
- m_Pos += m_Speed*a_Dt;
- }
-
- m_bDirtyPosition = true;
- }
-}
-
-void cMonster::TakeDamage(int a_Damage, cEntity* a_Instigator)
-{
- cPawn::TakeDamage( a_Damage, a_Instigator );
- m_Target = a_Instigator;
- AddReference( m_Target );
-}
-
-void cMonster::KilledBy( cEntity* a_Killer )
-{
- cPawn::KilledBy( a_Killer );
- m_DestroyTimer = 0;
-}
-
-//----State Logic
-
-const char *cMonster::GetState() {
- switch(m_EMState) {
- case IDLE:
- return "Idle";
- break;
- case ATTACKING:
- return "Attacking";
- break;
- case CHASING:
- return "Chasing";
- break;
- default:
- return "Unknown";
- break;
- }
-}
-
-//for debugging
-void cMonster::SetState(const char* a_str)
-{
- std::string str = a_str;
- if(str.compare("Idle") == 0 ) {
- m_EMState = IDLE;
- } else if(str.compare("Attacking") == 0 ) {
- m_EMState = ATTACKING;
- } else if(str.compare("Chasing") == 0 ) {
- m_EMState = CHASING;
- } else {
- printf("Invalid State");
- }
-}
-
-//Checks to see if EventSeePlayer should be fired
-//monster sez: Do I see the player
-void cMonster::CheckEventSeePlayer()
-{
- cPlayer *Closest = FindClosestPlayer();
-
- if(Closest)
- {
- EventSeePlayer(Closest);
- }
-}
-
-void cMonster::CheckEventLostPlayer()
-{
- Vector3f pos;
- cTracer LineOfSight(GetWorld() );
-
- if(m_Target != 0) {
- pos = m_Target->GetPosition();
- if((pos - m_Pos).Length() > m_SightDistance || LineOfSight.Trace(m_Pos,(pos - m_Pos), (int)(pos - m_Pos).Length()))
- {
- EventLosePlayer();
- }
- } else {
- EventLosePlayer();
- }
-}
-
-//What to do if player is seen
-//default to change state to chasing
-void cMonster::EventSeePlayer(cEntity *a_SeenPlayer)
-{
- m_Target = a_SeenPlayer;
- AddReference( m_Target );
-}
-
-void cMonster::EventLosePlayer(){
- Dereference(m_Target);
- m_Target = 0;
- m_EMState = IDLE;
-}
-
-//What to do if in Idle State
-void cMonster::InStateIdle(float a_Dt) {
- idle_interval += a_Dt;
- if(idle_interval > 1) { //at this interval the results are predictable
- MTRand r1;
- int rem = r1.randInt()%6 + 1;
- //LOG("Moving: int: %3.3f rem: %i",idle_interval,rem);
- idle_interval -= 1; //So nothing gets dropped when the server hangs for a few seconds
- Vector3f Dist;
- Dist.x = (float)((r1.randInt()%11)-5);
- Dist.z = (float)((r1.randInt()%11)-5);
- if( Dist.SqrLength() > 2 && rem >= 3)
- {
- m_Destination.x = (float)(m_Pos.x + Dist.x);
- m_Destination.z = (float)(m_Pos.z + Dist.z);
- m_Destination.y = (float)GetWorld()->GetHeight( (int)m_Destination.x, (int)m_Destination.z ) + 1.2f;
- MoveToPosition( m_Destination );
- }
- }
-}
-
-//What to do if in Chasing State
-//This state should always be defined in each child class
-void cMonster::InStateChasing(float a_Dt) {
- (void)a_Dt;
-}
-
-//What to do if in Escaping State
-void cMonster::InStateEscaping(float a_Dt) {
- (void)a_Dt;
- if(m_Target) {
- Vector3d newloc = m_Pos;
- newloc.x = (m_Target->GetPosition().x < newloc.x)? (newloc.x + m_SightDistance): (newloc.x - m_SightDistance);
- newloc.z = (m_Target->GetPosition().z < newloc.z)? (newloc.z + m_SightDistance): (newloc.z - m_SightDistance);
- MoveToPosition(newloc);
- } else {
- m_EMState = IDLE; //this shouldnt be required but just to be safe
- }
-}
-
-
-//Do attack here
-//a_Dt is passed so we can set attack rate
-void cMonster::Attack(float a_Dt) {
- m_AttackInterval += a_Dt * m_AttackRate;
- if(m_Target != 0 && m_AttackInterval > 3.0) { //Setting this higher gives us more wiggle room for attackrate
- m_AttackInterval = 0.0;
- ((cPawn *)m_Target)->TakeDamage((int)m_AttackDamage,this);
- }
-}
-
-
-
-
-
-#if 0
-// TODO: Implement this debug function inside cWorld instead - the world owns the entities
-void cMonster::ListMonsters()
-{
-
- cWorld::EntityList Entities = cRoot::Get()->GetWorld()->GetEntities();
- cRoot::Get()->GetWorld()->LockEntities();
- for( cWorld::EntityList::iterator itr = Entities.begin(); itr != Entities.end(); ++itr) {
- if((*itr)->GetEntityType() == cEntity::E_ENTITY){
- LOG("In state: %s type: %i attack rate: %i",((cMonster *)(*itr))->GetState(), ((cMonster *)(*itr))->GetMobType(),((cMonster *)(*itr))->GetAttackRate());
-
- }
- }
- cRoot::Get()->GetWorld()->UnlockEntities();
-}
-#endif
-
-
-
-
-
-//Checks for Players close by and if they are visible return the closest
-cPlayer * cMonster::FindClosestPlayer(void)
-{
- return m_World->FindClosestPlayer(m_Pos, m_SightDistance);
-}
-
-
-
-
-
-void cMonster::GetMonsterConfig(const char* pm_name)
-{
- cRoot::Get()->GetMonsterConfig()->AssignAttributes(this, pm_name);
-}
-
-
-
-
-
-void cMonster::SetAttackRate(int ar)
-{
- m_AttackRate = (float)ar;
-}
-
-
-
-
-
-void cMonster::SetAttackRange(float ar)
-{
- m_AttackRange = ar;
-}
-
-
-
-
-
-void cMonster::SetAttackDamage(float ad)
-{
- m_AttackDamage = ad;
-}
-
-
-
-
-
-void cMonster::SetSightDistance(float sd)
-{
- m_SightDistance = sd;
-}
-
-
-
-
-
-void cMonster::AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, ENUM_ITEM_ID a_Item, short a_ItemHealth)
-{
- MTRand r1;
- int Count = r1.randInt() % (a_Max + 1 - a_Min) + a_Min;
- if (Count > 0)
- {
- a_Drops.push_back(cItem(a_Item, Count, a_ItemHealth));
- }
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cMonster.h" +#include "cRoot.h" +#include "cServer.h" +#include "cClientHandle.h" +#include "cWorld.h" +#include "cPlayer.h" +#include "Defines.h" +#include "cMonsterConfig.h" +#include "MersenneTwister.h" + +#include "packets/cPacket_SpawnMob.h" +#include "packets/cPacket_EntityLook.h" +#include "packets/cPacket_TeleportEntity.h" +#include "packets/cPacket_RelativeEntityMoveLook.h" +#include "packets/cPacket_RelativeEntityMove.h" +#include "packets/cPacket_Metadata.h" + +#include "Vector3f.h" +#include "Vector3i.h" +#include "Vector3d.h" + +#include "cTracer.h" +#include "../iniFile/iniFile.h" + +#ifndef _WIN32 + #include <cstdlib> // rand + #include <unistd.h> +#endif + + + + + +cMonster::cMonster() + : m_Target(0) + , m_bMovingToDestination(false) + , m_DestinationTime( 0 ) + , m_Gravity( -9.81f) + , m_bOnGround( false ) + , m_DestroyTimer( 0 ) + , m_Jump(0) + , m_MobType( 0 ) + , m_EMState(IDLE) + , m_SightDistance(25) + , m_SeePlayerInterval (0) + , m_EMPersonality(AGGRESSIVE) + , m_AttackDamage(1.0f) + , m_AttackRange(5.0f) + , m_AttackInterval(0) + , m_AttackRate(3) + , idle_interval(0) +{ + LOG("cMonster::cMonster()"); + LOG("In state: %s", GetState()); + + m_bBurnable = true; + m_MetaData = NORMAL; +} + +cMonster::~cMonster() +{ + LOG("cMonster::~cMonster()"); +} + +bool cMonster::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cMonster" ) == 0 ) return true; + return cPawn::IsA( a_EntityType ); +} + + + + + +cPacket * cMonster::GetSpawnPacket(void) const +{ + cPacket_SpawnMob * Spawn = new cPacket_SpawnMob; + Spawn->m_UniqueID = GetUniqueID(); + Spawn->m_Type = m_MobType; + *Spawn->m_Pos = ((Vector3i)(m_Pos)) * 32; + Spawn->m_Yaw = 0; + Spawn->m_Pitch = 0; + Spawn->m_MetaDataSize = 1; + Spawn->m_MetaData = new char[Spawn->m_MetaDataSize]; + Spawn->m_MetaData[0] = 0x7f; // not on fire/crouching/riding + return Spawn; +} + + + + + +void cMonster::MoveToPosition( const Vector3f & a_Position ) +{ + m_bMovingToDestination = true; + + m_Destination = a_Position; +} + +bool cMonster::ReachedDestination() +{ + Vector3f Distance = (m_Destination) - Vector3f( m_Pos ); + if( Distance.SqrLength() < 2.f ) + return true; + + return false; +} + + + + + +void cMonster::Tick(float a_Dt) +{ + cPawn::Tick(a_Dt); + + if( m_Health <= 0 ) + { + m_DestroyTimer += a_Dt/1000; + if( m_DestroyTimer > 1 ) + { + Destroy(); + } + return; + } + + a_Dt /= 1000; + + if( m_bMovingToDestination ) + { + Vector3f Pos( m_Pos ); + Vector3f Distance = m_Destination - Pos; + if( !ReachedDestination() ) + { + Distance.y = 0; + Distance.Normalize(); + Distance *= 3; + m_Speed.x = Distance.x; + m_Speed.z = Distance.z; + + if (m_EMState == ESCAPING) + { //Runs Faster when escaping :D otherwise they just walk away + m_Speed.x *= 2.f; + m_Speed.z *= 2.f; + } + } + else + { + m_bMovingToDestination = false; + } + + if( m_Speed.SqrLength() > 0.f ) + { + if( m_bOnGround ) + { + Vector3f NormSpeed = m_Speed.NormalizeCopy(); + Vector3f NextBlock = Vector3f( m_Pos ) + NormSpeed; + double NextHeight = (double)GetWorld()->GetHeight( (int)NextBlock.x, (int)NextBlock.z ); + if( NextHeight > m_Pos.y - 1.2 && NextHeight - m_Pos.y < 2.5 ) + { + m_bOnGround = false; + m_Speed.y = 7.f; // Jump!! + } + } + } + } + + HandlePhysics( a_Dt ); + + ReplicateMovement(); + + Vector3f Distance = m_Destination - Vector3f( m_Pos ); + if( Distance.SqrLength() > 0.1f ) + { + float Rotation, Pitch; + Distance.Normalize(); + VectorToEuler( Distance.x, Distance.y, Distance.z, Rotation, Pitch ); + SetRotation( Rotation ); + SetPitch( Pitch ); + } + + if(m_EMState == IDLE) { //If enemy passive we ignore checks for player visibility + InStateIdle(a_Dt); + } + + if(m_EMState == CHASING) { //If we do not see a player anymore skip chasing action + InStateChasing(a_Dt); + } + + if(m_EMState == ESCAPING) { + InStateEscaping(a_Dt); + } + +} + + + + + +void cMonster::ReplicateMovement() +{ + if(m_bDirtyOrientation && !m_bDirtyPosition) + { + cPacket_EntityLook EntityLook(*this); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityLook ); + m_bDirtyOrientation = false; + } + + if( m_bDirtyPosition ) + { + float DiffX = (float)(GetPosX() - m_LastPosX ); + float DiffY = (float)(GetPosY() - m_LastPosY ); + float DiffZ = (float)(GetPosZ() - m_LastPosZ ); + float SqrDist = DiffX*DiffX + DiffY*DiffY + DiffZ*DiffZ; + if ( + (SqrDist > 4 * 4) // 4 blocks is max Relative Move + || (cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds + ) + { + //LOG("Teleported %f", sqrtf(SqrDist) ); + cPacket_TeleportEntity TeleportEntity( this ); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity); + m_TimeLastTeleportPacket = cWorld::GetTime(); + } + else + { // Relative move sucks balls! It's always wrong wtf! + if( m_bDirtyOrientation ) + { + cPacket_RelativeEntityMoveLook RelativeEntityMoveLook; + RelativeEntityMoveLook.m_UniqueID = GetUniqueID(); + RelativeEntityMoveLook.m_MoveX = (char)(DiffX*32); + RelativeEntityMoveLook.m_MoveY = (char)(DiffY*32); + RelativeEntityMoveLook.m_MoveZ = (char)(DiffZ*32); + RelativeEntityMoveLook.m_Yaw = (char)((GetRotation()/360.f)*256); + RelativeEntityMoveLook.m_Pitch = (char)((GetPitch()/360.f)*256); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMoveLook ); + } + else + { + cPacket_RelativeEntityMove RelativeEntityMove; + RelativeEntityMove.m_UniqueID = GetUniqueID(); + RelativeEntityMove.m_MoveX = (char)(DiffX*32); + RelativeEntityMove.m_MoveY = (char)(DiffY*32); + RelativeEntityMove.m_MoveZ = (char)(DiffZ*32); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMove ); + } + } + m_LastPosX = GetPosX(); + m_LastPosY = GetPosY(); + m_LastPosZ = GetPosZ(); + m_bDirtyPosition = false; + } + + MoveToCorrectChunk(); +} + + + + + +void cMonster::HandlePhysics(float a_Dt) +{ + if( m_bOnGround ) // check if it's still on the ground + { + cWorld* World = GetWorld(); + if( World->GetBlock( (int)m_Pos.x, (int)m_Pos.y -1, (int)m_Pos.z ) == E_BLOCK_AIR ) + { + m_bOnGround = false; + } + if( World->GetBlock( (int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z ) != E_BLOCK_AIR ) // If in ground itself, push it out + { + m_bOnGround = true; + m_Pos.y += 0.2; + m_bDirtyPosition = true; + } + m_Speed.x *= 0.7f/(1+a_Dt); + if( fabs(m_Speed.x) < 0.05 ) m_Speed.x = 0; + m_Speed.z *= 0.7f/(1+a_Dt); + if( fabs(m_Speed.z) < 0.05 ) m_Speed.z = 0; + } + + if( !m_bOnGround ) + { + float Gravity = -9.81f*a_Dt; + m_Speed.y += Gravity; + } + + if( m_Speed.SqrLength() > 0.f ) + { + cTracer Tracer( GetWorld() ); + int Ret = Tracer.Trace( m_Pos, m_Speed, 2 ); + if( Ret ) // Oh noez! we hit something + { + // Set to hit position + if( (Tracer.RealHit - Vector3f(m_Pos)).SqrLength() <= ( m_Speed * a_Dt ).SqrLength() ) + { + if( Ret == 1 ) + { + + if( Tracer.HitNormal.x != 0.f ) m_Speed.x = 0.f; + if( Tracer.HitNormal.y != 0.f ) m_Speed.y = 0.f; + if( Tracer.HitNormal.z != 0.f ) m_Speed.z = 0.f; + + if( Tracer.HitNormal.y > 0 ) // means on ground + { + m_bOnGround = true; + } + } + m_Pos = Tracer.RealHit; + m_Pos += Tracer.HitNormal * 0.2f; + + } + else + m_Pos += m_Speed*a_Dt; + } + else + { // We didn't hit anything, so move =] + m_Pos += m_Speed*a_Dt; + } + + m_bDirtyPosition = true; + } +} + +void cMonster::TakeDamage(int a_Damage, cEntity* a_Instigator) +{ + cPawn::TakeDamage( a_Damage, a_Instigator ); + m_Target = a_Instigator; + AddReference( m_Target ); +} + +void cMonster::KilledBy( cEntity* a_Killer ) +{ + cPawn::KilledBy( a_Killer ); + m_DestroyTimer = 0; +} + +//----State Logic + +const char *cMonster::GetState() { + switch(m_EMState) { + case IDLE: + return "Idle"; + break; + case ATTACKING: + return "Attacking"; + break; + case CHASING: + return "Chasing"; + break; + default: + return "Unknown"; + break; + } +} + +//for debugging +void cMonster::SetState(const char* a_str) +{ + std::string str = a_str; + if(str.compare("Idle") == 0 ) { + m_EMState = IDLE; + } else if(str.compare("Attacking") == 0 ) { + m_EMState = ATTACKING; + } else if(str.compare("Chasing") == 0 ) { + m_EMState = CHASING; + } else { + printf("Invalid State"); + } +} + +//Checks to see if EventSeePlayer should be fired +//monster sez: Do I see the player +void cMonster::CheckEventSeePlayer() +{ + cPlayer *Closest = FindClosestPlayer(); + + if(Closest) + { + EventSeePlayer(Closest); + } +} + +void cMonster::CheckEventLostPlayer() +{ + Vector3f pos; + cTracer LineOfSight(GetWorld() ); + + if(m_Target != 0) { + pos = m_Target->GetPosition(); + if((pos - m_Pos).Length() > m_SightDistance || LineOfSight.Trace(m_Pos,(pos - m_Pos), (int)(pos - m_Pos).Length())) + { + EventLosePlayer(); + } + } else { + EventLosePlayer(); + } +} + +//What to do if player is seen +//default to change state to chasing +void cMonster::EventSeePlayer(cEntity *a_SeenPlayer) +{ + m_Target = a_SeenPlayer; + AddReference( m_Target ); +} + +void cMonster::EventLosePlayer(){ + Dereference(m_Target); + m_Target = 0; + m_EMState = IDLE; +} + +//What to do if in Idle State +void cMonster::InStateIdle(float a_Dt) { + idle_interval += a_Dt; + if(idle_interval > 1) { //at this interval the results are predictable + MTRand r1; + int rem = r1.randInt()%6 + 1; + //LOG("Moving: int: %3.3f rem: %i",idle_interval,rem); + idle_interval -= 1; //So nothing gets dropped when the server hangs for a few seconds + Vector3f Dist; + Dist.x = (float)((r1.randInt()%11)-5); + Dist.z = (float)((r1.randInt()%11)-5); + if( Dist.SqrLength() > 2 && rem >= 3) + { + m_Destination.x = (float)(m_Pos.x + Dist.x); + m_Destination.z = (float)(m_Pos.z + Dist.z); + m_Destination.y = (float)GetWorld()->GetHeight( (int)m_Destination.x, (int)m_Destination.z ) + 1.2f; + MoveToPosition( m_Destination ); + } + } +} + +//What to do if in Chasing State +//This state should always be defined in each child class +void cMonster::InStateChasing(float a_Dt) { + (void)a_Dt; +} + +//What to do if in Escaping State +void cMonster::InStateEscaping(float a_Dt) { + (void)a_Dt; + if(m_Target) { + Vector3d newloc = m_Pos; + newloc.x = (m_Target->GetPosition().x < newloc.x)? (newloc.x + m_SightDistance): (newloc.x - m_SightDistance); + newloc.z = (m_Target->GetPosition().z < newloc.z)? (newloc.z + m_SightDistance): (newloc.z - m_SightDistance); + MoveToPosition(newloc); + } else { + m_EMState = IDLE; //this shouldnt be required but just to be safe + } +} + + +//Do attack here +//a_Dt is passed so we can set attack rate +void cMonster::Attack(float a_Dt) { + m_AttackInterval += a_Dt * m_AttackRate; + if(m_Target != 0 && m_AttackInterval > 3.0) { //Setting this higher gives us more wiggle room for attackrate + m_AttackInterval = 0.0; + ((cPawn *)m_Target)->TakeDamage((int)m_AttackDamage,this); + } +} + + + + + +#if 0 +// TODO: Implement this debug function inside cWorld instead - the world owns the entities +void cMonster::ListMonsters() +{ + + cWorld::EntityList Entities = cRoot::Get()->GetWorld()->GetEntities(); + cRoot::Get()->GetWorld()->LockEntities(); + for( cWorld::EntityList::iterator itr = Entities.begin(); itr != Entities.end(); ++itr) { + if((*itr)->GetEntityType() == cEntity::E_ENTITY){ + LOG("In state: %s type: %i attack rate: %i",((cMonster *)(*itr))->GetState(), ((cMonster *)(*itr))->GetMobType(),((cMonster *)(*itr))->GetAttackRate()); + + } + } + cRoot::Get()->GetWorld()->UnlockEntities(); +} +#endif + + + + + +//Checks for Players close by and if they are visible return the closest +cPlayer * cMonster::FindClosestPlayer(void) +{ + return m_World->FindClosestPlayer(m_Pos, m_SightDistance); +} + + + + + +void cMonster::GetMonsterConfig(const char* pm_name) +{ + cRoot::Get()->GetMonsterConfig()->AssignAttributes(this, pm_name); +} + + + + + +void cMonster::SetAttackRate(int ar) +{ + m_AttackRate = (float)ar; +} + + + + + +void cMonster::SetAttackRange(float ar) +{ + m_AttackRange = ar; +} + + + + + +void cMonster::SetAttackDamage(float ad) +{ + m_AttackDamage = ad; +} + + + + + +void cMonster::SetSightDistance(float sd) +{ + m_SightDistance = sd; +} + + + + + +void cMonster::AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, ENUM_ITEM_ID a_Item, short a_ItemHealth) +{ + MTRand r1; + int Count = r1.randInt() % (a_Max + 1 - a_Min) + a_Min; + if (Count > 0) + { + a_Drops.push_back(cItem(a_Item, Count, a_ItemHealth)); + } +} + + + + diff --git a/source/cMonster.h b/source/cMonster.h index b1e237d80..ab247fcfa 100644 --- a/source/cMonster.h +++ b/source/cMonster.h @@ -1,101 +1,101 @@ -
-#pragma once
-
-#include "cPawn.h"
-#include "Defines.h"
-#include "cWorld.h"
-#include "BlockID.h"
-#include "cItem.h"
-#include "BlockID.h"
-
-
-
-
-
-class Vector3f;
-class cClientHandle;
-
-
-
-
-class cMonster : public cPawn //tolua_export
-{ //tolua_export
-public:
-
- cMonster();
- virtual ~cMonster();
-
- virtual bool IsA( const char* a_EntityType );
-
- virtual cPacket * GetSpawnPacket(void) const override;
-
- virtual void Tick(float a_Dt) override;
-
- virtual void HandlePhysics(float a_Dt);
- virtual void ReplicateMovement();
-
- virtual void TakeDamage( int a_Damage, cEntity* a_Instigator );
- virtual void KilledBy( cEntity* a_Killer );
-
- virtual void MoveToPosition( const Vector3f & a_Position );
- virtual bool ReachedDestination();
-
- const char *GetState();
- void SetState(const char* str);
- static void ListMonsters();
-
- virtual void CheckEventSeePlayer();
- virtual void EventSeePlayer(cEntity *);
- float m_SightDistance;
- virtual cPlayer *FindClosestPlayer(); //non static is easier. also virtual so other mobs can implement their own searching algo
- virtual void GetMonsterConfig(const char* pm_name);
- virtual void EventLosePlayer();
- virtual void CheckEventLostPlayer();
-
- virtual void InStateIdle(float a_Dt);
- virtual void InStateChasing(float a_Dt);
- virtual void InStateEscaping(float a_Dt);
-
- virtual void Attack(float a_Dt);
- int GetMobType() {return m_MobType;}
- int GetAttackRate(){return (int)m_AttackRate;}
- void SetAttackRate(int ar);
- void SetAttackRange(float ar);
- void SetAttackDamage(float ad);
- void SetSightDistance(float sd);
-
- enum MState{ATTACKING, IDLE, CHASING, ESCAPING} m_EMState;
- enum MPersonality{PASSIVE,AGGRESSIVE,COWARDLY} m_EMPersonality;
-
-protected:
-
- cEntity* m_Target;
- float m_AttackRate;
- float idle_interval;
-
- Vector3f m_Destination;
- bool m_bMovingToDestination;
- bool m_bPassiveAggressive;
-
- Vector3f m_Speed;
- float m_DestinationTime;
-
- float m_Gravity;
- bool m_bOnGround;
-
- float m_DestroyTimer;
- float m_Jump;
-
- char m_MobType;
-
- float m_SeePlayerInterval;
- float m_AttackDamage;
- float m_AttackRange;
- float m_AttackInterval;
-
- void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, ENUM_ITEM_ID a_Item, short a_ItemHealth = 0);
-}; //tolua_export
-
-
-
-
+ +#pragma once + +#include "cPawn.h" +#include "Defines.h" +#include "cWorld.h" +#include "BlockID.h" +#include "cItem.h" +#include "BlockID.h" + + + + + +class Vector3f; +class cClientHandle; + + + + +class cMonster : public cPawn //tolua_export +{ //tolua_export +public: + + cMonster(); + virtual ~cMonster(); + + virtual bool IsA( const char* a_EntityType ); + + virtual cPacket * GetSpawnPacket(void) const override; + + virtual void Tick(float a_Dt) override; + + virtual void HandlePhysics(float a_Dt); + virtual void ReplicateMovement(); + + virtual void TakeDamage( int a_Damage, cEntity* a_Instigator ); + virtual void KilledBy( cEntity* a_Killer ); + + virtual void MoveToPosition( const Vector3f & a_Position ); + virtual bool ReachedDestination(); + + const char *GetState(); + void SetState(const char* str); + static void ListMonsters(); + + virtual void CheckEventSeePlayer(); + virtual void EventSeePlayer(cEntity *); + float m_SightDistance; + virtual cPlayer *FindClosestPlayer(); //non static is easier. also virtual so other mobs can implement their own searching algo + virtual void GetMonsterConfig(const char* pm_name); + virtual void EventLosePlayer(); + virtual void CheckEventLostPlayer(); + + virtual void InStateIdle(float a_Dt); + virtual void InStateChasing(float a_Dt); + virtual void InStateEscaping(float a_Dt); + + virtual void Attack(float a_Dt); + int GetMobType() {return m_MobType;} + int GetAttackRate(){return (int)m_AttackRate;} + void SetAttackRate(int ar); + void SetAttackRange(float ar); + void SetAttackDamage(float ad); + void SetSightDistance(float sd); + + enum MState{ATTACKING, IDLE, CHASING, ESCAPING} m_EMState; + enum MPersonality{PASSIVE,AGGRESSIVE,COWARDLY} m_EMPersonality; + +protected: + + cEntity* m_Target; + float m_AttackRate; + float idle_interval; + + Vector3f m_Destination; + bool m_bMovingToDestination; + bool m_bPassiveAggressive; + + Vector3f m_Speed; + float m_DestinationTime; + + float m_Gravity; + bool m_bOnGround; + + float m_DestroyTimer; + float m_Jump; + + char m_MobType; + + float m_SeePlayerInterval; + float m_AttackDamage; + float m_AttackRange; + float m_AttackInterval; + + void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, ENUM_ITEM_ID a_Item, short a_ItemHealth = 0); +}; //tolua_export + + + + diff --git a/source/cMonsterConfig.cpp b/source/cMonsterConfig.cpp index 92f65aeec..f8bc9e16f 100644 --- a/source/cMonsterConfig.cpp +++ b/source/cMonsterConfig.cpp @@ -1,114 +1,114 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cMonsterConfig.h"
-#include "cMonster.h"
-#include "../iniFile/iniFile.h"
-//#include <cstdio>
-
-
-
-
-
-struct cMonsterConfig::sAttributesStruct
-{
- AString m_name;
- float m_SightDistance;
- float m_AttackDamage;
- float m_AttackRange;
- float m_AttackRate;
- int m_MaxHealth;
-};
-
-
-
-
-
-struct cMonsterConfig::sMonsterConfigState
-{
- AString MonsterTypes;
- std::list< sAttributesStruct > AttributesList;
-};
-
-
-
-
-
-cMonsterConfig::cMonsterConfig(void)
- : m_pState( new sMonsterConfigState )
-{
- Initialize();
-}
-
-
-
-
-
-cMonsterConfig::~cMonsterConfig() {
- delete m_pState;
-}
-
-
-
-
-
-void cMonsterConfig::Initialize() {
-
- sAttributesStruct Attributes;
- cIniFile SettingsIniFile("settings.ini");
- cIniFile MonstersIniFile("monsters.ini");
-
- if (!SettingsIniFile.ReadFile() || !MonstersIniFile.ReadFile())
- {
- LOGWARNING("cMonsterConfig: Must have both settings.ini and monsters.ini to configure attributes\n\tusing default attributes \n");
- return;
- }
-
- m_pState->MonsterTypes = SettingsIniFile.GetValue("Monsters","Types","");
-
- if ( m_pState->MonsterTypes.empty() )
- {
- LOGWARNING("cMonsterConfig: No Monster types listed in config file, using default attributes \n");
- return;
- }
-
- AStringVector SplitList = StringSplit(m_pState->MonsterTypes,",");
- for (unsigned int i = 0; i < SplitList.size(); ++i)
- {
- if (!SplitList[i].empty())
- {
- Attributes.m_name = SplitList[i].c_str();
- Attributes.m_AttackDamage = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "AttackDamage", 0);
- Attributes.m_AttackRange = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "AttackRange", 0);
- Attributes.m_SightDistance = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "SightDistance", 0);
- Attributes.m_AttackRate = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "AttackRate", 0);
- Attributes.m_MaxHealth = MonstersIniFile.GetValueI(SplitList[i].c_str(), "MaxHealth", 0);
- m_pState->AttributesList.push_front(Attributes);
- }
- } // for i - SplitList[]
-}
-
-
-
-
-
-void cMonsterConfig::AssignAttributes(cMonster *m, const char* n)
-{
- std::list<sAttributesStruct>::const_iterator itr;
- for (itr = m_pState->AttributesList.begin(); itr != m_pState->AttributesList.end(); ++itr)
- {
- if(itr->m_name.compare(n) == 0)
- {
- m->SetAttackDamage (itr->m_AttackDamage);
- m->SetAttackRange (itr->m_AttackRange);
- m->SetSightDistance(itr->m_SightDistance);
- m->SetAttackRate ((int)itr->m_AttackRate);
- m->SetMaxHealth ((short)itr->m_MaxHealth);
- }
- } // for itr - m_pState->AttributesList[]
-}
-
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cMonsterConfig.h" +#include "cMonster.h" +#include "../iniFile/iniFile.h" +//#include <cstdio> + + + + + +struct cMonsterConfig::sAttributesStruct +{ + AString m_name; + float m_SightDistance; + float m_AttackDamage; + float m_AttackRange; + float m_AttackRate; + int m_MaxHealth; +}; + + + + + +struct cMonsterConfig::sMonsterConfigState +{ + AString MonsterTypes; + std::list< sAttributesStruct > AttributesList; +}; + + + + + +cMonsterConfig::cMonsterConfig(void) + : m_pState( new sMonsterConfigState ) +{ + Initialize(); +} + + + + + +cMonsterConfig::~cMonsterConfig() { + delete m_pState; +} + + + + + +void cMonsterConfig::Initialize() { + + sAttributesStruct Attributes; + cIniFile SettingsIniFile("settings.ini"); + cIniFile MonstersIniFile("monsters.ini"); + + if (!SettingsIniFile.ReadFile() || !MonstersIniFile.ReadFile()) + { + LOGWARNING("cMonsterConfig: Must have both settings.ini and monsters.ini to configure attributes\n\tusing default attributes \n"); + return; + } + + m_pState->MonsterTypes = SettingsIniFile.GetValue("Monsters","Types",""); + + if ( m_pState->MonsterTypes.empty() ) + { + LOGWARNING("cMonsterConfig: No Monster types listed in config file, using default attributes \n"); + return; + } + + AStringVector SplitList = StringSplit(m_pState->MonsterTypes,","); + for (unsigned int i = 0; i < SplitList.size(); ++i) + { + if (!SplitList[i].empty()) + { + Attributes.m_name = SplitList[i].c_str(); + Attributes.m_AttackDamage = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "AttackDamage", 0); + Attributes.m_AttackRange = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "AttackRange", 0); + Attributes.m_SightDistance = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "SightDistance", 0); + Attributes.m_AttackRate = (float)MonstersIniFile.GetValueF(SplitList[i].c_str(), "AttackRate", 0); + Attributes.m_MaxHealth = MonstersIniFile.GetValueI(SplitList[i].c_str(), "MaxHealth", 0); + m_pState->AttributesList.push_front(Attributes); + } + } // for i - SplitList[] +} + + + + + +void cMonsterConfig::AssignAttributes(cMonster *m, const char* n) +{ + std::list<sAttributesStruct>::const_iterator itr; + for (itr = m_pState->AttributesList.begin(); itr != m_pState->AttributesList.end(); ++itr) + { + if(itr->m_name.compare(n) == 0) + { + m->SetAttackDamage (itr->m_AttackDamage); + m->SetAttackRange (itr->m_AttackRange); + m->SetSightDistance(itr->m_SightDistance); + m->SetAttackRate ((int)itr->m_AttackRate); + m->SetMaxHealth ((short)itr->m_MaxHealth); + } + } // for itr - m_pState->AttributesList[] +} + + + + + diff --git a/source/cMonsterConfig.h b/source/cMonsterConfig.h index fbe537802..d1a514b17 100644 --- a/source/cMonsterConfig.h +++ b/source/cMonsterConfig.h @@ -1,17 +1,17 @@ -#pragma once
-
-class cMonster;
-class cMonsterConfig
-{
-public:
- cMonsterConfig(void);
- ~cMonsterConfig();
-
- void AssignAttributes(cMonster *m, const char* n);
-
-private:
- struct sAttributesStruct;
- struct sMonsterConfigState;
- sMonsterConfigState* m_pState;
- void Initialize();
+#pragma once + +class cMonster; +class cMonsterConfig +{ +public: + cMonsterConfig(void); + ~cMonsterConfig(); + + void AssignAttributes(cMonster *m, const char* n); + +private: + struct sAttributesStruct; + struct sMonsterConfigState; + sMonsterConfigState* m_pState; + void Initialize(); };
\ No newline at end of file diff --git a/source/cNoise.cpp b/source/cNoise.cpp index 653b9e95c..2dd26e5aa 100644 --- a/source/cNoise.cpp +++ b/source/cNoise.cpp @@ -1,305 +1,305 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cNoise.h"
-#include <math.h>
-
-#if NOISE_USE_SSE
-#include <smmintrin.h> //_mm_mul_epi32
-#endif
-
-#define FAST_FLOOR( x ) ( (x) < 0 ? ((int)x)-1 : ((int)x) )
-
-
-
-
-
-cNoise::cNoise( unsigned int a_Seed )
- : m_Seed( a_Seed )
-{
-}
-
-
-cNoise::~cNoise()
-{
-}
-
-#if NOISE_USE_SSE
-/****************
- * SSE Random value generator
- **/
-__m128 cNoise::SSE_IntNoise2D( int a_X1, int a_Y1, int a_X2, int a_Y2, int a_X3, int a_Y3, int a_X4, int a_Y4 ) const
-{
- const __m128i X4 = _mm_set_epi32(a_X4, a_X3, a_X2, a_X1);
- const __m128i Y4 = _mm_set_epi32(a_Y4, a_Y3, a_Y2, a_Y1);
-
- const __m128 One4 = _mm_set_ps1( 1.f );
- const __m128i YScale4 = _mm_set1_epi32( 57 );
-
- const __m128i i15731 = _mm_set1_epi32( 15731 );
- const __m128i i789221 = _mm_set1_epi32( 789221 );
- const __m128i i1376312589 = _mm_set1_epi32(1376312589);
- const __m128i MaskValue4 = _mm_set1_epi32(0x7fffffff);
- const __m128 f1073741824 = _mm_set_ps1( 1073741824.0f );
-
- const __m128i Seed4 = _mm_mullo_epi32( _mm_mullo_epi32( _mm_set1_epi32( m_Seed ), YScale4 ), YScale4 );
-
- const __m128i ScaledY4 = _mm_mullo_epi32( Y4, YScale4 );
- const __m128i n4 = _mm_add_epi32( _mm_add_epi32( X4, ScaledY4 ), Seed4 );
- const __m128i nn4 = _mm_slli_epi32( n4, 13 );
- const __m128i nnn4 = _mm_xor_si128( nn4, n4 );
-
- const __m128i StepA4 = _mm_mullo_epi32( nnn4, nnn4 );
- const __m128i StepAA4 = _mm_add_epi32( _mm_mullo_epi32( StepA4, i15731 ), i789221 );
- const __m128i StepB4 = _mm_add_epi32( _mm_mullo_epi32( nnn4, StepAA4 ), i1376312589 );
- const __m128i StepC4 = _mm_and_si128( StepB4, MaskValue4 );
- const __m128 StepD4 = _mm_div_ps( _mm_cvtepi32_ps( StepC4 ), f1073741824 );
- const __m128 Result4 = _mm_sub_ps( One4, StepD4 );
-
- return Result4;
-}
-#endif
-
-
-/***************
- * Interpolated (and 1 smoothed) noise in 1-dimension
- **/
-float cNoise::LinearNoise1D( float a_X ) const
-{
- int BaseX = FAST_FLOOR( a_X );
- float FracX = (a_X) - BaseX;
- return LinearInterpolate( IntNoise( BaseX ), IntNoise( BaseX+1 ), FracX);
-}
-
-float cNoise::CosineNoise1D( float a_X ) const
-{
- int BaseX = FAST_FLOOR( a_X );
- float FracX = (a_X) - BaseX;
- return CosineInterpolate( IntNoise( BaseX ), IntNoise( BaseX+1 ), FracX);
-}
-
-float cNoise::CubicNoise1D( float a_X ) const
-{
- int BaseX = FAST_FLOOR( a_X );
- float FracX = (a_X) - BaseX;
- return CubicInterpolate( IntNoise( BaseX-1 ), IntNoise( BaseX ), IntNoise( BaseX+1 ), IntNoise( BaseX+2 ), FracX);
-}
-
-float cNoise::SmoothNoise1D( int a_X ) const
-{
- return IntNoise(a_X)/2 + IntNoise(a_X-1)/4 + IntNoise(a_X+1)/4;
-}
-
-/******************
- * Interpolated (and 1 smoothed) noise in 2-dimensions
- **/
-float cNoise::LinearNoise2D( float a_X, float a_Y ) const
-{
- const int BaseX = FAST_FLOOR( a_X );
- const int BaseY = FAST_FLOOR( a_Y );
-
- const float tl = IntNoise2D( BaseX, BaseY );
- const float tr = IntNoise2D( BaseX+1, BaseY );
- const float bl = IntNoise2D( BaseX, BaseY+1 );
- const float br = IntNoise2D( BaseX+1, BaseY+1 );
-
- const float FracX = (a_X) - BaseX;
- const float interp1 = LinearInterpolate( tl, tr, FracX );
- const float interp2 = LinearInterpolate( bl, br, FracX );
-
- const float FracY = (a_Y) - BaseY;
- return LinearInterpolate( interp1, interp2, FracY );
-}
-
-float cNoise::CosineNoise2D( float a_X, float a_Y ) const
-{
- const int BaseX = FAST_FLOOR( a_X );
- const int BaseY = FAST_FLOOR( a_Y );
-
- const float tl = IntNoise2D( BaseX, BaseY );
- const float tr = IntNoise2D( BaseX+1, BaseY );
- const float bl = IntNoise2D( BaseX, BaseY+1 );
- const float br = IntNoise2D( BaseX+1, BaseY+1 );
-
- const float FracX = (a_X) - BaseX;
- const float interp1 = CosineInterpolate( tl, tr, FracX );
- const float interp2 = CosineInterpolate( bl, br, FracX );
-
- const float FracY = (a_Y) - BaseY;
- return CosineInterpolate( interp1, interp2, FracY );
-}
-
-
-
-
-
-float cNoise::CubicNoise2D( float a_X, float a_Y ) const
-{
- const int BaseX = FAST_FLOOR( a_X );
- const int BaseY = FAST_FLOOR( a_Y );
-
- const float points[4][4] =
- {
- IntNoise2D( BaseX-1, BaseY-1 ), IntNoise2D( BaseX, BaseY-1 ), IntNoise2D( BaseX+1, BaseY-1 ), IntNoise2D( BaseX+2, BaseY-1 ),
- IntNoise2D( BaseX-1, BaseY ), IntNoise2D( BaseX, BaseY ), IntNoise2D( BaseX+1, BaseY ), IntNoise2D( BaseX+2, BaseY ),
- IntNoise2D( BaseX-1, BaseY+1 ), IntNoise2D( BaseX, BaseY+1 ), IntNoise2D( BaseX+1, BaseY+1 ), IntNoise2D( BaseX+2, BaseY+1 ),
- IntNoise2D( BaseX-1, BaseY+2 ), IntNoise2D( BaseX, BaseY+2 ), IntNoise2D( BaseX+1, BaseY+2 ), IntNoise2D( BaseX+2, BaseY+2 ),
- };
-
- const float FracX = (a_X) - BaseX;
- const float interp1 = CubicInterpolate( points[0][0], points[0][1], points[0][2], points[0][3], FracX );
- const float interp2 = CubicInterpolate( points[1][0], points[1][1], points[1][2], points[1][3], FracX );
- const float interp3 = CubicInterpolate( points[2][0], points[2][1], points[2][2], points[2][3], FracX );
- const float interp4 = CubicInterpolate( points[3][0], points[3][1], points[3][2], points[3][3], FracX );
-
-
- const float FracY = (a_Y) - BaseY;
- return CubicInterpolate( interp1, interp2, interp3, interp4, FracY );
-}
-
-
-
-
-
-#if NOISE_USE_SSE
-float cNoise::SSE_CubicNoise2D( float a_X, float a_Y ) const
-{
- const int BaseX = FAST_FLOOR( a_X );
- const int BaseY = FAST_FLOOR( a_Y );
-
- __m128 points4[4] = {
- SSE_IntNoise2D( BaseX-1, BaseY-1, BaseX-1, BaseY, BaseX-1, BaseY+1, BaseX-1, BaseY+2 ),
- SSE_IntNoise2D( BaseX, BaseY-1, BaseX, BaseY, BaseX, BaseY+1, BaseX, BaseY+2 ),
- SSE_IntNoise2D( BaseX+1, BaseY-1, BaseX+1, BaseY, BaseX+1, BaseY+1, BaseX+1, BaseY+2 ),
- SSE_IntNoise2D( BaseX+2, BaseY-1, BaseX+2, BaseY, BaseX+2, BaseY+1, BaseX+2, BaseY+2 ),
- };
-
- const float FracX = (a_X) - BaseX;
- union { __m128 p4; float p[4]; }
- AllInterp = { CubicInterpolate4( points4[0], points4[1], points4[2], points4[3], FracX ) };
-
- const float FracY = (a_Y) - BaseY;
- return CubicInterpolate( AllInterp.p[0], AllInterp.p[1], AllInterp.p[2], AllInterp.p[3], FracY );
-}
-#endif
-
-/******************
- * Interpolated (and 1 smoothed) noise in 3-dimensions
- **/
-float cNoise::CosineNoise3D( float a_X, float a_Y, float a_Z ) const
-{
- const int BaseX = FAST_FLOOR( a_X );
- const int BaseY = FAST_FLOOR( a_Y );
- const int BaseZ = FAST_FLOOR( a_Z );
-
- const float ftl = IntNoise3D( BaseX, BaseY, BaseZ );
- const float ftr = IntNoise3D( BaseX+1, BaseY, BaseZ );
- const float fbl = IntNoise3D( BaseX, BaseY+1, BaseZ );
- const float fbr = IntNoise3D( BaseX+1, BaseY+1, BaseZ );
-
- const float btl = IntNoise3D( BaseX, BaseY, BaseZ+1 );
- const float btr = IntNoise3D( BaseX+1, BaseY, BaseZ+1 );
- const float bbl = IntNoise3D( BaseX, BaseY+1, BaseZ+1 );
- const float bbr = IntNoise3D( BaseX+1, BaseY+1, BaseZ+1 );
-
- const float FracX = (a_X) - BaseX;
- const float finterp1 = CosineInterpolate( ftl, ftr, FracX );
- const float finterp2 = CosineInterpolate( fbl, fbr, FracX );
- const float binterp1 = CosineInterpolate( btl, btr, FracX );
- const float binterp2 = CosineInterpolate( bbl, bbr, FracX );
-
- const float FracY = (a_Y) - BaseY;
- const float interp1 = CosineInterpolate( finterp1, finterp2, FracY );
- const float interp2 = CosineInterpolate( binterp1, binterp2, FracY );
-
- const float FracZ = (a_Z) - BaseZ;
- return CosineInterpolate( interp1, interp2, FracZ );
-}
-
-float cNoise::CubicNoise3D( float a_X, float a_Y, float a_Z ) const
-{
- const int BaseX = FAST_FLOOR( a_X );
- const int BaseY = FAST_FLOOR( a_Y );
- const int BaseZ = FAST_FLOOR( a_Z );
-
- const float points1[4][4] = {
- IntNoise3D( BaseX-1, BaseY-1, BaseZ-1 ), IntNoise3D( BaseX, BaseY-1, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY-1, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY-1, BaseZ-1 ),
- IntNoise3D( BaseX-1, BaseY, BaseZ-1 ), IntNoise3D( BaseX, BaseY, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY, BaseZ-1 ),
- IntNoise3D( BaseX-1, BaseY+1, BaseZ-1 ), IntNoise3D( BaseX, BaseY+1, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY+1, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY+1, BaseZ-1 ),
- IntNoise3D( BaseX-1, BaseY+2, BaseZ-1 ), IntNoise3D( BaseX, BaseY+2, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY+2, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY+2, BaseZ-1 ),
- };
-
- const float FracX = (a_X) - BaseX;
- const float x1interp1 = CubicInterpolate( points1[0][0], points1[0][1], points1[0][2], points1[0][3], FracX );
- const float x1interp2 = CubicInterpolate( points1[1][0], points1[1][1], points1[1][2], points1[1][3], FracX );
- const float x1interp3 = CubicInterpolate( points1[2][0], points1[2][1], points1[2][2], points1[2][3], FracX );
- const float x1interp4 = CubicInterpolate( points1[3][0], points1[3][1], points1[3][2], points1[3][3], FracX );
-
- const float points2[4][4] = {
- IntNoise3D( BaseX-1, BaseY-1, BaseZ ), IntNoise3D( BaseX, BaseY-1, BaseZ ), IntNoise3D( BaseX+1, BaseY-1, BaseZ ), IntNoise3D( BaseX+2, BaseY-1, BaseZ ),
- IntNoise3D( BaseX-1, BaseY, BaseZ ), IntNoise3D( BaseX, BaseY, BaseZ ), IntNoise3D( BaseX+1, BaseY, BaseZ ), IntNoise3D( BaseX+2, BaseY, BaseZ ),
- IntNoise3D( BaseX-1, BaseY+1, BaseZ ), IntNoise3D( BaseX, BaseY+1, BaseZ ), IntNoise3D( BaseX+1, BaseY+1, BaseZ ), IntNoise3D( BaseX+2, BaseY+1, BaseZ ),
- IntNoise3D( BaseX-1, BaseY+2, BaseZ ), IntNoise3D( BaseX, BaseY+2, BaseZ ), IntNoise3D( BaseX+1, BaseY+2, BaseZ ), IntNoise3D( BaseX+2, BaseY+2, BaseZ ),
- };
-
- const float x2interp1 = CubicInterpolate( points2[0][0], points2[0][1], points2[0][2], points2[0][3], FracX );
- const float x2interp2 = CubicInterpolate( points2[1][0], points2[1][1], points2[1][2], points2[1][3], FracX );
- const float x2interp3 = CubicInterpolate( points2[2][0], points2[2][1], points2[2][2], points2[2][3], FracX );
- const float x2interp4 = CubicInterpolate( points2[3][0], points2[3][1], points2[3][2], points2[3][3], FracX );
-
- const float points3[4][4] = {
- IntNoise3D( BaseX-1, BaseY-1, BaseZ+1 ), IntNoise3D( BaseX, BaseY-1, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY-1, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY-1, BaseZ+1 ),
- IntNoise3D( BaseX-1, BaseY, BaseZ+1 ), IntNoise3D( BaseX, BaseY, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY, BaseZ+1 ),
- IntNoise3D( BaseX-1, BaseY+1, BaseZ+1 ), IntNoise3D( BaseX, BaseY+1, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY+1, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY+1, BaseZ+1 ),
- IntNoise3D( BaseX-1, BaseY+2, BaseZ+1 ), IntNoise3D( BaseX, BaseY+2, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY+2, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY+2, BaseZ+1 ),
- };
-
- const float x3interp1 = CubicInterpolate( points3[0][0], points3[0][1], points3[0][2], points3[0][3], FracX );
- const float x3interp2 = CubicInterpolate( points3[1][0], points3[1][1], points3[1][2], points3[1][3], FracX );
- const float x3interp3 = CubicInterpolate( points3[2][0], points3[2][1], points3[2][2], points3[2][3], FracX );
- const float x3interp4 = CubicInterpolate( points3[3][0], points3[3][1], points3[3][2], points3[3][3], FracX );
-
- const float points4[4][4] = {
- IntNoise3D( BaseX-1, BaseY-1, BaseZ+2 ), IntNoise3D( BaseX, BaseY-1, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY-1, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY-1, BaseZ+2 ),
- IntNoise3D( BaseX-1, BaseY, BaseZ+2 ), IntNoise3D( BaseX, BaseY, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY, BaseZ+2 ),
- IntNoise3D( BaseX-1, BaseY+1, BaseZ+2 ), IntNoise3D( BaseX, BaseY+1, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY+1, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY+1, BaseZ+2 ),
- IntNoise3D( BaseX-1, BaseY+2, BaseZ+2 ), IntNoise3D( BaseX, BaseY+2, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY+2, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY+2, BaseZ+2 ),
- };
-
- const float x4interp1 = CubicInterpolate( points4[0][0], points4[0][1], points4[0][2], points4[0][3], FracX );
- const float x4interp2 = CubicInterpolate( points4[1][0], points4[1][1], points4[1][2], points4[1][3], FracX );
- const float x4interp3 = CubicInterpolate( points4[2][0], points4[2][1], points4[2][2], points4[2][3], FracX );
- const float x4interp4 = CubicInterpolate( points4[3][0], points4[3][1], points4[3][2], points4[3][3], FracX );
-
- const float FracY = (a_Y) - BaseY;
- const float yinterp1 = CubicInterpolate( x1interp1, x1interp2, x1interp3, x1interp4, FracY );
- const float yinterp2 = CubicInterpolate( x2interp1, x2interp2, x2interp3, x2interp4, FracY );
- const float yinterp3 = CubicInterpolate( x3interp1, x3interp2, x3interp3, x3interp4, FracY );
- const float yinterp4 = CubicInterpolate( x4interp1, x4interp2, x4interp3, x4interp4, FracY );
-
- const float FracZ = (a_Z) - BaseZ;
- return CubicInterpolate( yinterp1, yinterp2, yinterp3, yinterp4, FracZ );
-}
-
-/******************
- * Private
- **/
-
-#if NOISE_USE_SSE
-__m128 cNoise::CubicInterpolate4( const __m128 & a_A, const __m128 & a_B, const __m128 & a_C, const __m128 & a_D, float a_Pct ) const
-{
- const __m128 P = _mm_sub_ps( _mm_sub_ps( a_D, a_C ), _mm_sub_ps( a_A, a_B ) );
- const __m128 Q = _mm_sub_ps( _mm_sub_ps( a_A, a_B ), P );
- const __m128 R = _mm_sub_ps( a_C, a_A );
-
- const __m128 Pct = _mm_set_ps1( a_Pct );
- const __m128 Pct2 = _mm_mul_ps( Pct, Pct );
- const __m128 Pct3 = _mm_mul_ps( Pct2, Pct );
-
- return _mm_add_ps( _mm_add_ps( _mm_add_ps( _mm_mul_ps(P, Pct3), _mm_mul_ps( Q, Pct2 ) ), _mm_mul_ps( R, Pct ) ), a_B );
-}
-#endif
-
-#if NOISE_USE_INLINE
-# include "cNoise.inc"
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cNoise.h" +#include <math.h> + +#if NOISE_USE_SSE +#include <smmintrin.h> //_mm_mul_epi32 +#endif + +#define FAST_FLOOR( x ) ( (x) < 0 ? ((int)x)-1 : ((int)x) ) + + + + + +cNoise::cNoise( unsigned int a_Seed ) + : m_Seed( a_Seed ) +{ +} + + +cNoise::~cNoise() +{ +} + +#if NOISE_USE_SSE +/**************** + * SSE Random value generator + **/ +__m128 cNoise::SSE_IntNoise2D( int a_X1, int a_Y1, int a_X2, int a_Y2, int a_X3, int a_Y3, int a_X4, int a_Y4 ) const +{ + const __m128i X4 = _mm_set_epi32(a_X4, a_X3, a_X2, a_X1); + const __m128i Y4 = _mm_set_epi32(a_Y4, a_Y3, a_Y2, a_Y1); + + const __m128 One4 = _mm_set_ps1( 1.f ); + const __m128i YScale4 = _mm_set1_epi32( 57 ); + + const __m128i i15731 = _mm_set1_epi32( 15731 ); + const __m128i i789221 = _mm_set1_epi32( 789221 ); + const __m128i i1376312589 = _mm_set1_epi32(1376312589); + const __m128i MaskValue4 = _mm_set1_epi32(0x7fffffff); + const __m128 f1073741824 = _mm_set_ps1( 1073741824.0f ); + + const __m128i Seed4 = _mm_mullo_epi32( _mm_mullo_epi32( _mm_set1_epi32( m_Seed ), YScale4 ), YScale4 ); + + const __m128i ScaledY4 = _mm_mullo_epi32( Y4, YScale4 ); + const __m128i n4 = _mm_add_epi32( _mm_add_epi32( X4, ScaledY4 ), Seed4 ); + const __m128i nn4 = _mm_slli_epi32( n4, 13 ); + const __m128i nnn4 = _mm_xor_si128( nn4, n4 ); + + const __m128i StepA4 = _mm_mullo_epi32( nnn4, nnn4 ); + const __m128i StepAA4 = _mm_add_epi32( _mm_mullo_epi32( StepA4, i15731 ), i789221 ); + const __m128i StepB4 = _mm_add_epi32( _mm_mullo_epi32( nnn4, StepAA4 ), i1376312589 ); + const __m128i StepC4 = _mm_and_si128( StepB4, MaskValue4 ); + const __m128 StepD4 = _mm_div_ps( _mm_cvtepi32_ps( StepC4 ), f1073741824 ); + const __m128 Result4 = _mm_sub_ps( One4, StepD4 ); + + return Result4; +} +#endif + + +/*************** + * Interpolated (and 1 smoothed) noise in 1-dimension + **/ +float cNoise::LinearNoise1D( float a_X ) const +{ + int BaseX = FAST_FLOOR( a_X ); + float FracX = (a_X) - BaseX; + return LinearInterpolate( IntNoise( BaseX ), IntNoise( BaseX+1 ), FracX); +} + +float cNoise::CosineNoise1D( float a_X ) const +{ + int BaseX = FAST_FLOOR( a_X ); + float FracX = (a_X) - BaseX; + return CosineInterpolate( IntNoise( BaseX ), IntNoise( BaseX+1 ), FracX); +} + +float cNoise::CubicNoise1D( float a_X ) const +{ + int BaseX = FAST_FLOOR( a_X ); + float FracX = (a_X) - BaseX; + return CubicInterpolate( IntNoise( BaseX-1 ), IntNoise( BaseX ), IntNoise( BaseX+1 ), IntNoise( BaseX+2 ), FracX); +} + +float cNoise::SmoothNoise1D( int a_X ) const +{ + return IntNoise(a_X)/2 + IntNoise(a_X-1)/4 + IntNoise(a_X+1)/4; +} + +/****************** + * Interpolated (and 1 smoothed) noise in 2-dimensions + **/ +float cNoise::LinearNoise2D( float a_X, float a_Y ) const +{ + const int BaseX = FAST_FLOOR( a_X ); + const int BaseY = FAST_FLOOR( a_Y ); + + const float tl = IntNoise2D( BaseX, BaseY ); + const float tr = IntNoise2D( BaseX+1, BaseY ); + const float bl = IntNoise2D( BaseX, BaseY+1 ); + const float br = IntNoise2D( BaseX+1, BaseY+1 ); + + const float FracX = (a_X) - BaseX; + const float interp1 = LinearInterpolate( tl, tr, FracX ); + const float interp2 = LinearInterpolate( bl, br, FracX ); + + const float FracY = (a_Y) - BaseY; + return LinearInterpolate( interp1, interp2, FracY ); +} + +float cNoise::CosineNoise2D( float a_X, float a_Y ) const +{ + const int BaseX = FAST_FLOOR( a_X ); + const int BaseY = FAST_FLOOR( a_Y ); + + const float tl = IntNoise2D( BaseX, BaseY ); + const float tr = IntNoise2D( BaseX+1, BaseY ); + const float bl = IntNoise2D( BaseX, BaseY+1 ); + const float br = IntNoise2D( BaseX+1, BaseY+1 ); + + const float FracX = (a_X) - BaseX; + const float interp1 = CosineInterpolate( tl, tr, FracX ); + const float interp2 = CosineInterpolate( bl, br, FracX ); + + const float FracY = (a_Y) - BaseY; + return CosineInterpolate( interp1, interp2, FracY ); +} + + + + + +float cNoise::CubicNoise2D( float a_X, float a_Y ) const +{ + const int BaseX = FAST_FLOOR( a_X ); + const int BaseY = FAST_FLOOR( a_Y ); + + const float points[4][4] = + { + IntNoise2D( BaseX-1, BaseY-1 ), IntNoise2D( BaseX, BaseY-1 ), IntNoise2D( BaseX+1, BaseY-1 ), IntNoise2D( BaseX+2, BaseY-1 ), + IntNoise2D( BaseX-1, BaseY ), IntNoise2D( BaseX, BaseY ), IntNoise2D( BaseX+1, BaseY ), IntNoise2D( BaseX+2, BaseY ), + IntNoise2D( BaseX-1, BaseY+1 ), IntNoise2D( BaseX, BaseY+1 ), IntNoise2D( BaseX+1, BaseY+1 ), IntNoise2D( BaseX+2, BaseY+1 ), + IntNoise2D( BaseX-1, BaseY+2 ), IntNoise2D( BaseX, BaseY+2 ), IntNoise2D( BaseX+1, BaseY+2 ), IntNoise2D( BaseX+2, BaseY+2 ), + }; + + const float FracX = (a_X) - BaseX; + const float interp1 = CubicInterpolate( points[0][0], points[0][1], points[0][2], points[0][3], FracX ); + const float interp2 = CubicInterpolate( points[1][0], points[1][1], points[1][2], points[1][3], FracX ); + const float interp3 = CubicInterpolate( points[2][0], points[2][1], points[2][2], points[2][3], FracX ); + const float interp4 = CubicInterpolate( points[3][0], points[3][1], points[3][2], points[3][3], FracX ); + + + const float FracY = (a_Y) - BaseY; + return CubicInterpolate( interp1, interp2, interp3, interp4, FracY ); +} + + + + + +#if NOISE_USE_SSE +float cNoise::SSE_CubicNoise2D( float a_X, float a_Y ) const +{ + const int BaseX = FAST_FLOOR( a_X ); + const int BaseY = FAST_FLOOR( a_Y ); + + __m128 points4[4] = { + SSE_IntNoise2D( BaseX-1, BaseY-1, BaseX-1, BaseY, BaseX-1, BaseY+1, BaseX-1, BaseY+2 ), + SSE_IntNoise2D( BaseX, BaseY-1, BaseX, BaseY, BaseX, BaseY+1, BaseX, BaseY+2 ), + SSE_IntNoise2D( BaseX+1, BaseY-1, BaseX+1, BaseY, BaseX+1, BaseY+1, BaseX+1, BaseY+2 ), + SSE_IntNoise2D( BaseX+2, BaseY-1, BaseX+2, BaseY, BaseX+2, BaseY+1, BaseX+2, BaseY+2 ), + }; + + const float FracX = (a_X) - BaseX; + union { __m128 p4; float p[4]; } + AllInterp = { CubicInterpolate4( points4[0], points4[1], points4[2], points4[3], FracX ) }; + + const float FracY = (a_Y) - BaseY; + return CubicInterpolate( AllInterp.p[0], AllInterp.p[1], AllInterp.p[2], AllInterp.p[3], FracY ); +} +#endif + +/****************** + * Interpolated (and 1 smoothed) noise in 3-dimensions + **/ +float cNoise::CosineNoise3D( float a_X, float a_Y, float a_Z ) const +{ + const int BaseX = FAST_FLOOR( a_X ); + const int BaseY = FAST_FLOOR( a_Y ); + const int BaseZ = FAST_FLOOR( a_Z ); + + const float ftl = IntNoise3D( BaseX, BaseY, BaseZ ); + const float ftr = IntNoise3D( BaseX+1, BaseY, BaseZ ); + const float fbl = IntNoise3D( BaseX, BaseY+1, BaseZ ); + const float fbr = IntNoise3D( BaseX+1, BaseY+1, BaseZ ); + + const float btl = IntNoise3D( BaseX, BaseY, BaseZ+1 ); + const float btr = IntNoise3D( BaseX+1, BaseY, BaseZ+1 ); + const float bbl = IntNoise3D( BaseX, BaseY+1, BaseZ+1 ); + const float bbr = IntNoise3D( BaseX+1, BaseY+1, BaseZ+1 ); + + const float FracX = (a_X) - BaseX; + const float finterp1 = CosineInterpolate( ftl, ftr, FracX ); + const float finterp2 = CosineInterpolate( fbl, fbr, FracX ); + const float binterp1 = CosineInterpolate( btl, btr, FracX ); + const float binterp2 = CosineInterpolate( bbl, bbr, FracX ); + + const float FracY = (a_Y) - BaseY; + const float interp1 = CosineInterpolate( finterp1, finterp2, FracY ); + const float interp2 = CosineInterpolate( binterp1, binterp2, FracY ); + + const float FracZ = (a_Z) - BaseZ; + return CosineInterpolate( interp1, interp2, FracZ ); +} + +float cNoise::CubicNoise3D( float a_X, float a_Y, float a_Z ) const +{ + const int BaseX = FAST_FLOOR( a_X ); + const int BaseY = FAST_FLOOR( a_Y ); + const int BaseZ = FAST_FLOOR( a_Z ); + + const float points1[4][4] = { + IntNoise3D( BaseX-1, BaseY-1, BaseZ-1 ), IntNoise3D( BaseX, BaseY-1, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY-1, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY-1, BaseZ-1 ), + IntNoise3D( BaseX-1, BaseY, BaseZ-1 ), IntNoise3D( BaseX, BaseY, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY, BaseZ-1 ), + IntNoise3D( BaseX-1, BaseY+1, BaseZ-1 ), IntNoise3D( BaseX, BaseY+1, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY+1, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY+1, BaseZ-1 ), + IntNoise3D( BaseX-1, BaseY+2, BaseZ-1 ), IntNoise3D( BaseX, BaseY+2, BaseZ-1 ), IntNoise3D( BaseX+1, BaseY+2, BaseZ-1 ), IntNoise3D( BaseX+2, BaseY+2, BaseZ-1 ), + }; + + const float FracX = (a_X) - BaseX; + const float x1interp1 = CubicInterpolate( points1[0][0], points1[0][1], points1[0][2], points1[0][3], FracX ); + const float x1interp2 = CubicInterpolate( points1[1][0], points1[1][1], points1[1][2], points1[1][3], FracX ); + const float x1interp3 = CubicInterpolate( points1[2][0], points1[2][1], points1[2][2], points1[2][3], FracX ); + const float x1interp4 = CubicInterpolate( points1[3][0], points1[3][1], points1[3][2], points1[3][3], FracX ); + + const float points2[4][4] = { + IntNoise3D( BaseX-1, BaseY-1, BaseZ ), IntNoise3D( BaseX, BaseY-1, BaseZ ), IntNoise3D( BaseX+1, BaseY-1, BaseZ ), IntNoise3D( BaseX+2, BaseY-1, BaseZ ), + IntNoise3D( BaseX-1, BaseY, BaseZ ), IntNoise3D( BaseX, BaseY, BaseZ ), IntNoise3D( BaseX+1, BaseY, BaseZ ), IntNoise3D( BaseX+2, BaseY, BaseZ ), + IntNoise3D( BaseX-1, BaseY+1, BaseZ ), IntNoise3D( BaseX, BaseY+1, BaseZ ), IntNoise3D( BaseX+1, BaseY+1, BaseZ ), IntNoise3D( BaseX+2, BaseY+1, BaseZ ), + IntNoise3D( BaseX-1, BaseY+2, BaseZ ), IntNoise3D( BaseX, BaseY+2, BaseZ ), IntNoise3D( BaseX+1, BaseY+2, BaseZ ), IntNoise3D( BaseX+2, BaseY+2, BaseZ ), + }; + + const float x2interp1 = CubicInterpolate( points2[0][0], points2[0][1], points2[0][2], points2[0][3], FracX ); + const float x2interp2 = CubicInterpolate( points2[1][0], points2[1][1], points2[1][2], points2[1][3], FracX ); + const float x2interp3 = CubicInterpolate( points2[2][0], points2[2][1], points2[2][2], points2[2][3], FracX ); + const float x2interp4 = CubicInterpolate( points2[3][0], points2[3][1], points2[3][2], points2[3][3], FracX ); + + const float points3[4][4] = { + IntNoise3D( BaseX-1, BaseY-1, BaseZ+1 ), IntNoise3D( BaseX, BaseY-1, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY-1, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY-1, BaseZ+1 ), + IntNoise3D( BaseX-1, BaseY, BaseZ+1 ), IntNoise3D( BaseX, BaseY, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY, BaseZ+1 ), + IntNoise3D( BaseX-1, BaseY+1, BaseZ+1 ), IntNoise3D( BaseX, BaseY+1, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY+1, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY+1, BaseZ+1 ), + IntNoise3D( BaseX-1, BaseY+2, BaseZ+1 ), IntNoise3D( BaseX, BaseY+2, BaseZ+1 ), IntNoise3D( BaseX+1, BaseY+2, BaseZ+1 ), IntNoise3D( BaseX+2, BaseY+2, BaseZ+1 ), + }; + + const float x3interp1 = CubicInterpolate( points3[0][0], points3[0][1], points3[0][2], points3[0][3], FracX ); + const float x3interp2 = CubicInterpolate( points3[1][0], points3[1][1], points3[1][2], points3[1][3], FracX ); + const float x3interp3 = CubicInterpolate( points3[2][0], points3[2][1], points3[2][2], points3[2][3], FracX ); + const float x3interp4 = CubicInterpolate( points3[3][0], points3[3][1], points3[3][2], points3[3][3], FracX ); + + const float points4[4][4] = { + IntNoise3D( BaseX-1, BaseY-1, BaseZ+2 ), IntNoise3D( BaseX, BaseY-1, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY-1, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY-1, BaseZ+2 ), + IntNoise3D( BaseX-1, BaseY, BaseZ+2 ), IntNoise3D( BaseX, BaseY, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY, BaseZ+2 ), + IntNoise3D( BaseX-1, BaseY+1, BaseZ+2 ), IntNoise3D( BaseX, BaseY+1, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY+1, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY+1, BaseZ+2 ), + IntNoise3D( BaseX-1, BaseY+2, BaseZ+2 ), IntNoise3D( BaseX, BaseY+2, BaseZ+2 ), IntNoise3D( BaseX+1, BaseY+2, BaseZ+2 ), IntNoise3D( BaseX+2, BaseY+2, BaseZ+2 ), + }; + + const float x4interp1 = CubicInterpolate( points4[0][0], points4[0][1], points4[0][2], points4[0][3], FracX ); + const float x4interp2 = CubicInterpolate( points4[1][0], points4[1][1], points4[1][2], points4[1][3], FracX ); + const float x4interp3 = CubicInterpolate( points4[2][0], points4[2][1], points4[2][2], points4[2][3], FracX ); + const float x4interp4 = CubicInterpolate( points4[3][0], points4[3][1], points4[3][2], points4[3][3], FracX ); + + const float FracY = (a_Y) - BaseY; + const float yinterp1 = CubicInterpolate( x1interp1, x1interp2, x1interp3, x1interp4, FracY ); + const float yinterp2 = CubicInterpolate( x2interp1, x2interp2, x2interp3, x2interp4, FracY ); + const float yinterp3 = CubicInterpolate( x3interp1, x3interp2, x3interp3, x3interp4, FracY ); + const float yinterp4 = CubicInterpolate( x4interp1, x4interp2, x4interp3, x4interp4, FracY ); + + const float FracZ = (a_Z) - BaseZ; + return CubicInterpolate( yinterp1, yinterp2, yinterp3, yinterp4, FracZ ); +} + +/****************** + * Private + **/ + +#if NOISE_USE_SSE +__m128 cNoise::CubicInterpolate4( const __m128 & a_A, const __m128 & a_B, const __m128 & a_C, const __m128 & a_D, float a_Pct ) const +{ + const __m128 P = _mm_sub_ps( _mm_sub_ps( a_D, a_C ), _mm_sub_ps( a_A, a_B ) ); + const __m128 Q = _mm_sub_ps( _mm_sub_ps( a_A, a_B ), P ); + const __m128 R = _mm_sub_ps( a_C, a_A ); + + const __m128 Pct = _mm_set_ps1( a_Pct ); + const __m128 Pct2 = _mm_mul_ps( Pct, Pct ); + const __m128 Pct3 = _mm_mul_ps( Pct2, Pct ); + + return _mm_add_ps( _mm_add_ps( _mm_add_ps( _mm_mul_ps(P, Pct3), _mm_mul_ps( Q, Pct2 ) ), _mm_mul_ps( R, Pct ) ), a_B ); +} +#endif + +#if NOISE_USE_INLINE +# include "cNoise.inc" #endif
\ No newline at end of file diff --git a/source/cNoise.h b/source/cNoise.h index 2169e0a13..ddee427ad 100644 --- a/source/cNoise.h +++ b/source/cNoise.h @@ -1,81 +1,81 @@ -#pragma once
-
-// Some settings
-#define NOISE_USE_INLINE 1
-#define NOISE_USE_SSE 0
-
-// Do not touch
-#if NOISE_USE_INLINE
- #ifdef _MSC_VER
- #define __NOISE_INLINE__ __forceinline
- #else
- #define __NOISE_INLINE__ inline
- #endif // _MSC_VER
-#else
- #define __NOISE_INLINE__
-#endif
-
-#if NOISE_USE_SSE
-# include <emmintrin.h>
-#endif
-
-
-
-
-
-class cNoise
-{
-public:
- cNoise( unsigned int a_Seed );
- ~cNoise();
-
-#if NOISE_USE_SSE
- __m128 SSE_IntNoise2D( int a_X1, int a_Y1, int a_X2, int a_Y2, int a_X3, int a_Y3, int a_X4, int a_Y4 ) const;
-#endif
-
- __NOISE_INLINE__ float IntNoise( int a_X ) const;
- __NOISE_INLINE__ float IntNoise2D( int a_X, int a_Y ) const;
- __NOISE_INLINE__ float IntNoise3D( int a_X, int a_Y, int a_Z ) const;
-
- // Note: These functions have a mod8-irregular chance - each of the mod8 remainders has different chance of occurrence. Divide by 8 to rectify.
- __NOISE_INLINE__ int IntNoise1DInt( int a_X ) const;
- __NOISE_INLINE__ int IntNoise2DInt( int a_X, int a_Y ) const;
- __NOISE_INLINE__ int IntNoise3DInt( int a_X, int a_Y, int a_Z ) const;
-
- float LinearNoise1D( float a_X ) const;
- float CosineNoise1D( float a_X ) const;
- float CubicNoise1D( float a_X ) const;
- float SmoothNoise1D( int a_X ) const;
-
- float LinearNoise2D( float a_X, float a_Y ) const;
- float CosineNoise2D( float a_X, float a_Y ) const;
- float CubicNoise2D( float a_X, float a_Y ) const;
- float SSE_CubicNoise2D( float a_X, float a_Y ) const;
-
- float CosineNoise3D( float a_X, float a_Y, float a_Z ) const;
- float CubicNoise3D( float a_X, float a_Y, float a_Z ) const;
-
- void SetSeed( unsigned int a_Seed ) { m_Seed = a_Seed; }
-private:
- __NOISE_INLINE__ float CubicInterpolate( float a_A, float a_B, float a_C, float a_D, float a_Pct ) const;
- __NOISE_INLINE__ float CosineInterpolate( float a_A, float a_B, float a_Pct ) const;
- __NOISE_INLINE__ float LinearInterpolate( float a_A, float a_B, float a_Pct ) const;
-
-#if NOISE_USE_SSE
- __m128 CubicInterpolate4( const __m128 & a_A, const __m128 & a_B, const __m128 & a_C, const __m128 & a_D, float a_Pct ) const;
-#endif
-
- unsigned int m_Seed;
-};
-
-
-
-
-
-#if NOISE_USE_INLINE
-# include "cNoise.inc"
-#endif
-
-
-
-
+#pragma once + +// Some settings +#define NOISE_USE_INLINE 1 +#define NOISE_USE_SSE 0 + +// Do not touch +#if NOISE_USE_INLINE + #ifdef _MSC_VER + #define __NOISE_INLINE__ __forceinline + #else + #define __NOISE_INLINE__ inline + #endif // _MSC_VER +#else + #define __NOISE_INLINE__ +#endif + +#if NOISE_USE_SSE +# include <emmintrin.h> +#endif + + + + + +class cNoise +{ +public: + cNoise( unsigned int a_Seed ); + ~cNoise(); + +#if NOISE_USE_SSE + __m128 SSE_IntNoise2D( int a_X1, int a_Y1, int a_X2, int a_Y2, int a_X3, int a_Y3, int a_X4, int a_Y4 ) const; +#endif + + __NOISE_INLINE__ float IntNoise( int a_X ) const; + __NOISE_INLINE__ float IntNoise2D( int a_X, int a_Y ) const; + __NOISE_INLINE__ float IntNoise3D( int a_X, int a_Y, int a_Z ) const; + + // Note: These functions have a mod8-irregular chance - each of the mod8 remainders has different chance of occurrence. Divide by 8 to rectify. + __NOISE_INLINE__ int IntNoise1DInt( int a_X ) const; + __NOISE_INLINE__ int IntNoise2DInt( int a_X, int a_Y ) const; + __NOISE_INLINE__ int IntNoise3DInt( int a_X, int a_Y, int a_Z ) const; + + float LinearNoise1D( float a_X ) const; + float CosineNoise1D( float a_X ) const; + float CubicNoise1D( float a_X ) const; + float SmoothNoise1D( int a_X ) const; + + float LinearNoise2D( float a_X, float a_Y ) const; + float CosineNoise2D( float a_X, float a_Y ) const; + float CubicNoise2D( float a_X, float a_Y ) const; + float SSE_CubicNoise2D( float a_X, float a_Y ) const; + + float CosineNoise3D( float a_X, float a_Y, float a_Z ) const; + float CubicNoise3D( float a_X, float a_Y, float a_Z ) const; + + void SetSeed( unsigned int a_Seed ) { m_Seed = a_Seed; } +private: + __NOISE_INLINE__ float CubicInterpolate( float a_A, float a_B, float a_C, float a_D, float a_Pct ) const; + __NOISE_INLINE__ float CosineInterpolate( float a_A, float a_B, float a_Pct ) const; + __NOISE_INLINE__ float LinearInterpolate( float a_A, float a_B, float a_Pct ) const; + +#if NOISE_USE_SSE + __m128 CubicInterpolate4( const __m128 & a_A, const __m128 & a_B, const __m128 & a_C, const __m128 & a_D, float a_Pct ) const; +#endif + + unsigned int m_Seed; +}; + + + + + +#if NOISE_USE_INLINE +# include "cNoise.inc" +#endif + + + + diff --git a/source/cPassiveAggressiveMonster.cpp b/source/cPassiveAggressiveMonster.cpp index 09e7b6a25..946ef86e0 100644 --- a/source/cPassiveAggressiveMonster.cpp +++ b/source/cPassiveAggressiveMonster.cpp @@ -1,38 +1,38 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPassiveAggressiveMonster.h"
-
-#include "cPlayer.h"
-
-
-
-
-
-cPassiveAggressiveMonster::cPassiveAggressiveMonster()
-{
- m_EMPersonality = PASSIVE;
-}
-
-cPassiveAggressiveMonster::~cPassiveAggressiveMonster()
-{
-}
-
-void cPassiveAggressiveMonster::TakeDamage(int a_Damage, cEntity* a_Instigator)
-{
- cMonster::TakeDamage(a_Damage, a_Instigator);
- if(m_Target->GetEntityType() == cEntity::eEntityType_Player)
- {
- cPlayer * Player = (cPlayer *) m_Target;
- if(Player->GetGameMode() != 1)
- {
- m_EMState = CHASING;
- }
- }
-
-}
-
-void cPassiveAggressiveMonster::EventSeePlayer(cEntity *a_Entity)
-{
- return cMonster::EventSeePlayer(a_Entity);
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPassiveAggressiveMonster.h" + +#include "cPlayer.h" + + + + + +cPassiveAggressiveMonster::cPassiveAggressiveMonster() +{ + m_EMPersonality = PASSIVE; +} + +cPassiveAggressiveMonster::~cPassiveAggressiveMonster() +{ +} + +void cPassiveAggressiveMonster::TakeDamage(int a_Damage, cEntity* a_Instigator) +{ + cMonster::TakeDamage(a_Damage, a_Instigator); + if(m_Target->GetEntityType() == cEntity::eEntityType_Player) + { + cPlayer * Player = (cPlayer *) m_Target; + if(Player->GetGameMode() != 1) + { + m_EMState = CHASING; + } + } + +} + +void cPassiveAggressiveMonster::EventSeePlayer(cEntity *a_Entity) +{ + return cMonster::EventSeePlayer(a_Entity); }
\ No newline at end of file diff --git a/source/cPassiveMonster.cpp b/source/cPassiveMonster.cpp index ad6da16f7..7a4bc6979 100644 --- a/source/cPassiveMonster.cpp +++ b/source/cPassiveMonster.cpp @@ -1,46 +1,46 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPassiveMonster.h"
-#include "MersenneTwister.h"
-
-
-
-
-
-cPassiveMonster::cPassiveMonster()
-{
- m_EMPersonality = PASSIVE;
-}
-
-cPassiveMonster::~cPassiveMonster()
-{
-}
-
-void cPassiveMonster::TakeDamage(int a_Damage, cEntity* a_Instigator)
-{
- cMonster::TakeDamage(a_Damage, a_Instigator);
- if(a_Instigator != this)
- m_EMState = ESCAPING;
-}
-
-void cPassiveMonster::Tick(float a_Dt)
-{
- cMonster::Tick(a_Dt);
-
- m_SeePlayerInterval += a_Dt;
-
- if(m_SeePlayerInterval > 1)
- {
- MTRand r1;
- int rem = r1.randInt() % 3 + 1; //check most of the time but miss occasionally
-
- m_SeePlayerInterval = 0.0;
- if(rem >= 2) {
- if(m_EMState == ESCAPING)
- {
- CheckEventLostPlayer();
- }
- }
- }
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPassiveMonster.h" +#include "MersenneTwister.h" + + + + + +cPassiveMonster::cPassiveMonster() +{ + m_EMPersonality = PASSIVE; +} + +cPassiveMonster::~cPassiveMonster() +{ +} + +void cPassiveMonster::TakeDamage(int a_Damage, cEntity* a_Instigator) +{ + cMonster::TakeDamage(a_Damage, a_Instigator); + if(a_Instigator != this) + m_EMState = ESCAPING; +} + +void cPassiveMonster::Tick(float a_Dt) +{ + cMonster::Tick(a_Dt); + + m_SeePlayerInterval += a_Dt; + + if(m_SeePlayerInterval > 1) + { + MTRand r1; + int rem = r1.randInt() % 3 + 1; //check most of the time but miss occasionally + + m_SeePlayerInterval = 0.0; + if(rem >= 2) { + if(m_EMState == ESCAPING) + { + CheckEventLostPlayer(); + } + } + } }
\ No newline at end of file diff --git a/source/cPawn.cpp b/source/cPawn.cpp index 986d8904c..0037e56e4 100644 --- a/source/cPawn.cpp +++ b/source/cPawn.cpp @@ -1,252 +1,252 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPawn.h"
-#include "cRoot.h"
-#include "cServer.h"
-#include "cWorld.h"
-#include "cPlayer.h"
-#include "cPluginManager.h"
-#include "Vector3d.h"
-#include "BlockID.h"
-
-#include "Defines.h"
-
-#include "packets/cPacket_TeleportEntity.h"
-#include "packets/cPacket_EntityStatus.h"
-#include "packets/cPacket_Metadata.h"
-
-
-
-
-
-CLASS_DEFINITION( cPawn, cEntity )
-
-
-
-
-
-cPawn::cPawn()
- : cEntity( 0, 0, 0 )
- , m_LastPosX( 0.0 )
- , m_LastPosY( 0.0 )
- , m_LastPosZ( 0.0 )
- , m_TimeLastTeleportPacket( 0.f )
- , m_bBurnable(true)
- , m_MetaData(NORMAL)
- , m_FireDamageInterval(0.f)
- , m_BurnPeriod(0.f)
-{
- SetMaxHealth(20);
- SetMaxFoodLevel(125);
-}
-
-
-
-
-
-cPawn::~cPawn()
-{
-
-}
-
-
-
-
-
-void cPawn::Heal( int a_Health )
-{
- (void)a_Health;
-}
-
-
-
-
-
-void cPawn::TakeDamage( int a_Damage, cEntity* a_Instigator )
-{
- TakeDamageInfo TDI;
- TDI.Damage = a_Damage;
- TDI.Instigator = a_Instigator;
- cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_TAKE_DAMAGE, 2, this, &TDI );
-
- if( TDI.Damage == 0 ) return;
- if( m_Health <= 0 ) return; // Can't take damage if already dead
-
- m_Health -= (short)TDI.Damage;
- if( m_Health < 0 ) m_Health = 0;
-
- cPacket_EntityStatus Status;
- Status.m_UniqueID = GetUniqueID();
- Status.m_Status = cPacket_EntityStatus::STATUS_TAKEDAMAGE;
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, Status);
-
- if (m_Health <= 0)
- {
- KilledBy( TDI.Instigator );
- }
-}
-
-
-
-
-
-void cPawn::KilledBy( cEntity* a_Killer )
-{
- m_Health = 0;
-
- if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_KILLED, 2, this, a_Killer ) )
- {
- return; // Give plugins a chance to 'unkill' the pawn.
- }
-
- cPacket_EntityStatus Status;
- Status.m_UniqueID = GetUniqueID();
- Status.m_Status = cPacket_EntityStatus::STATUS_DIE;
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, Status);
-}
-
-
-
-
-
-void cPawn::TeleportToEntity( cEntity* a_Entity )
-{
- TeleportTo( a_Entity->GetPosX(), a_Entity->GetPosY(), a_Entity->GetPosZ() );
-}
-
-
-
-
-
-void cPawn::TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ )
-{
- SetPosition( a_PosX, a_PosY, a_PosZ );
-
- cPacket_TeleportEntity TeleportEntity( this );
-
- cRoot::Get()->GetServer()->Broadcast( TeleportEntity );
-}
-
-
-
-
-
-void cPawn::Tick(float a_Dt)
-{
- CheckMetaDataBurn(); //Check to see if pawn should burn based on block they are on
-
- if (GetMetaData() == BURNING)
- {
- InStateBurning(a_Dt);
- }
-}
-
-
-
-
-
-
-void cPawn::SetMetaData(MetaData a_MetaData)
-{
- //Broadcast new status to clients in the chunk
- m_MetaData = a_MetaData;
- cPacket_Metadata md(a_MetaData, GetUniqueID());
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, md);
-}
-
-
-
-
-
-//----Change Entity MetaData
-void cPawn::CheckMetaDataBurn()
-{
- char Block = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y, (int) m_Pos.z);
- char BlockAbove = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y + 1, (int) m_Pos.z);
- char BlockBelow = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y - 1, (int) m_Pos.z);
-
- if (
- (GetMetaData() == BURNING) &&
- (IsBlockWater(Block) || IsBlockWater(BlockAbove) || IsBlockWater(BlockBelow))
- )
- {
- SetMetaData(NORMAL);
- }
- else if (
- m_bBurnable &&
- (GetMetaData() != BURNING) &&
- (
- IsBlockLava(Block) || (Block == E_BLOCK_FIRE) ||
- IsBlockLava(BlockAbove) || (BlockAbove == E_BLOCK_FIRE) ||
- IsBlockLava(BlockBelow) || (BlockBelow == E_BLOCK_FIRE)
- )
- )
- {
- SetMetaData(BURNING);
- }
-}
-
-
-
-
-
-//What to do if On fire
-void cPawn::InStateBurning(float a_Dt)
-{
- m_FireDamageInterval += a_Dt;
- char Block = GetWorld()->GetBlock( (int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z );
- char BlockAbove = GetWorld()->GetBlock( (int)m_Pos.x, (int)m_Pos.y + 1, (int)m_Pos.z );
- if (m_FireDamageInterval > 800)
- {
-
- m_FireDamageInterval = 0;
- TakeDamage(1, this);
-
- m_BurnPeriod++;
- if (IsBlockLava(Block) || Block == E_BLOCK_FIRE
- || IsBlockLava(BlockAbove) || BlockAbove == E_BLOCK_FIRE)
- {
- m_BurnPeriod = 0;
- TakeDamage(6, this);
- }
- else
- {
- TakeDamage(1, this);
- }
-
- if (m_BurnPeriod > 7)
- {
- SetMetaData(NORMAL);
- m_BurnPeriod = 0;
- }
- }
-}
-
-
-
-
-
-void cPawn::SetMaxHealth(short a_MaxHealth)
-{
- this->m_MaxHealth = a_MaxHealth;
-
- //Reset health
- m_Health = a_MaxHealth;
-}
-
-
-
-
-
-void cPawn::SetMaxFoodLevel(short a_MaxFoodLevel)
-{
- m_MaxFoodLevel = a_MaxFoodLevel;
-
- //Reset food level
- m_FoodLevel = a_MaxFoodLevel;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPawn.h" +#include "cRoot.h" +#include "cServer.h" +#include "cWorld.h" +#include "cPlayer.h" +#include "cPluginManager.h" +#include "Vector3d.h" +#include "BlockID.h" + +#include "Defines.h" + +#include "packets/cPacket_TeleportEntity.h" +#include "packets/cPacket_EntityStatus.h" +#include "packets/cPacket_Metadata.h" + + + + + +CLASS_DEFINITION( cPawn, cEntity ) + + + + + +cPawn::cPawn() + : cEntity( 0, 0, 0 ) + , m_LastPosX( 0.0 ) + , m_LastPosY( 0.0 ) + , m_LastPosZ( 0.0 ) + , m_TimeLastTeleportPacket( 0.f ) + , m_bBurnable(true) + , m_MetaData(NORMAL) + , m_FireDamageInterval(0.f) + , m_BurnPeriod(0.f) +{ + SetMaxHealth(20); + SetMaxFoodLevel(125); +} + + + + + +cPawn::~cPawn() +{ + +} + + + + + +void cPawn::Heal( int a_Health ) +{ + (void)a_Health; +} + + + + + +void cPawn::TakeDamage( int a_Damage, cEntity* a_Instigator ) +{ + TakeDamageInfo TDI; + TDI.Damage = a_Damage; + TDI.Instigator = a_Instigator; + cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_TAKE_DAMAGE, 2, this, &TDI ); + + if( TDI.Damage == 0 ) return; + if( m_Health <= 0 ) return; // Can't take damage if already dead + + m_Health -= (short)TDI.Damage; + if( m_Health < 0 ) m_Health = 0; + + cPacket_EntityStatus Status; + Status.m_UniqueID = GetUniqueID(); + Status.m_Status = cPacket_EntityStatus::STATUS_TAKEDAMAGE; + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, Status); + + if (m_Health <= 0) + { + KilledBy( TDI.Instigator ); + } +} + + + + + +void cPawn::KilledBy( cEntity* a_Killer ) +{ + m_Health = 0; + + if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_KILLED, 2, this, a_Killer ) ) + { + return; // Give plugins a chance to 'unkill' the pawn. + } + + cPacket_EntityStatus Status; + Status.m_UniqueID = GetUniqueID(); + Status.m_Status = cPacket_EntityStatus::STATUS_DIE; + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, Status); +} + + + + + +void cPawn::TeleportToEntity( cEntity* a_Entity ) +{ + TeleportTo( a_Entity->GetPosX(), a_Entity->GetPosY(), a_Entity->GetPosZ() ); +} + + + + + +void cPawn::TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ) +{ + SetPosition( a_PosX, a_PosY, a_PosZ ); + + cPacket_TeleportEntity TeleportEntity( this ); + + cRoot::Get()->GetServer()->Broadcast( TeleportEntity ); +} + + + + + +void cPawn::Tick(float a_Dt) +{ + CheckMetaDataBurn(); //Check to see if pawn should burn based on block they are on + + if (GetMetaData() == BURNING) + { + InStateBurning(a_Dt); + } +} + + + + + + +void cPawn::SetMetaData(MetaData a_MetaData) +{ + //Broadcast new status to clients in the chunk + m_MetaData = a_MetaData; + cPacket_Metadata md(a_MetaData, GetUniqueID()); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, md); +} + + + + + +//----Change Entity MetaData +void cPawn::CheckMetaDataBurn() +{ + char Block = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y, (int) m_Pos.z); + char BlockAbove = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y + 1, (int) m_Pos.z); + char BlockBelow = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y - 1, (int) m_Pos.z); + + if ( + (GetMetaData() == BURNING) && + (IsBlockWater(Block) || IsBlockWater(BlockAbove) || IsBlockWater(BlockBelow)) + ) + { + SetMetaData(NORMAL); + } + else if ( + m_bBurnable && + (GetMetaData() != BURNING) && + ( + IsBlockLava(Block) || (Block == E_BLOCK_FIRE) || + IsBlockLava(BlockAbove) || (BlockAbove == E_BLOCK_FIRE) || + IsBlockLava(BlockBelow) || (BlockBelow == E_BLOCK_FIRE) + ) + ) + { + SetMetaData(BURNING); + } +} + + + + + +//What to do if On fire +void cPawn::InStateBurning(float a_Dt) +{ + m_FireDamageInterval += a_Dt; + char Block = GetWorld()->GetBlock( (int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z ); + char BlockAbove = GetWorld()->GetBlock( (int)m_Pos.x, (int)m_Pos.y + 1, (int)m_Pos.z ); + if (m_FireDamageInterval > 800) + { + + m_FireDamageInterval = 0; + TakeDamage(1, this); + + m_BurnPeriod++; + if (IsBlockLava(Block) || Block == E_BLOCK_FIRE + || IsBlockLava(BlockAbove) || BlockAbove == E_BLOCK_FIRE) + { + m_BurnPeriod = 0; + TakeDamage(6, this); + } + else + { + TakeDamage(1, this); + } + + if (m_BurnPeriod > 7) + { + SetMetaData(NORMAL); + m_BurnPeriod = 0; + } + } +} + + + + + +void cPawn::SetMaxHealth(short a_MaxHealth) +{ + this->m_MaxHealth = a_MaxHealth; + + //Reset health + m_Health = a_MaxHealth; +} + + + + + +void cPawn::SetMaxFoodLevel(short a_MaxFoodLevel) +{ + m_MaxFoodLevel = a_MaxFoodLevel; + + //Reset food level + m_FoodLevel = a_MaxFoodLevel; +} + + + + diff --git a/source/cPawn.h b/source/cPawn.h index 11b59575e..2c4444174 100644 --- a/source/cPawn.h +++ b/source/cPawn.h @@ -1,82 +1,82 @@ -
-#pragma once
-
-#include "cEntity.h"
-
-
-
-
-
-struct TakeDamageInfo //tolua_export
-{ //tolua_export
- int Damage; //tolua_export
- cEntity* Instigator; //tolua_export
-}; //tolua_export
-
-
-
-
-
-class cPawn : public cEntity //tolua_export
-{ //tolua_export
-public:
- CLASS_PROTOTYPE();
-
- cPawn();
- virtual ~cPawn();
-
- virtual void TeleportToEntity( cEntity* a_Entity ); //tolua_export
- virtual void TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ); //tolua_export
-
- virtual void Tick(float a_Dt) override;
-
- void Heal( int a_Health ); //tolua_export
- virtual void TakeDamage( int a_Damage, cEntity* a_Instigator ); //tolua_export
- virtual void KilledBy( cEntity* a_Killer ); //tolua_export
- int GetHealth() { return m_Health; } //tolua_export
-
- enum MetaData {NORMAL, BURNING, CROUCHED, RIDING, SPRINTING, EATING, BLOCKING};
-
- virtual void SetMetaData(MetaData a_MetaData);
- virtual MetaData GetMetaData() { return m_MetaData; }
-
- virtual void InStateBurning(float a_Dt);
-
- virtual void CheckMetaDataBurn();
-
- virtual void SetMaxHealth(short a_MaxHealth);
- virtual short GetMaxHealth() { return m_MaxHealth; }
-
- //virtual void SetMaxFood(short a_MaxFood);
- virtual short GetMaxFood() { return m_MaxFoodLevel / 6; }
- virtual short GetFood() { return m_FoodLevel / 6; }
-
- //virtual void SetMaxFoodSaturation(float a_MaxFoodSaturation);
- virtual float GetMaxFoodSaturation() { return fmod(m_MaxFoodLevel, 6.f); }
- virtual float GetFoodSaturation() { return fmod(m_FoodLevel, 6.f); }
-
- virtual void SetMaxFoodLevel(short a_MaxFoodLevel);
- virtual short GetMaxFoodLevel() { return m_MaxFoodLevel; }
-
-protected:
-
- short m_Health;
- short m_FoodLevel;
- short m_MaxHealth;
- short m_MaxFoodLevel;
-
- bool m_bBurnable;
-
- MetaData m_MetaData;
-
- double m_LastPosX, m_LastPosY, m_LastPosZ;
- float m_TimeLastTeleportPacket;
-
- float m_FireDamageInterval;
- float m_BurnPeriod;
-
-}; //tolua_export
-
-
-
-
+ +#pragma once + +#include "cEntity.h" + + + + + +struct TakeDamageInfo //tolua_export +{ //tolua_export + int Damage; //tolua_export + cEntity* Instigator; //tolua_export +}; //tolua_export + + + + + +class cPawn : public cEntity //tolua_export +{ //tolua_export +public: + CLASS_PROTOTYPE(); + + cPawn(); + virtual ~cPawn(); + + virtual void TeleportToEntity( cEntity* a_Entity ); //tolua_export + virtual void TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ); //tolua_export + + virtual void Tick(float a_Dt) override; + + void Heal( int a_Health ); //tolua_export + virtual void TakeDamage( int a_Damage, cEntity* a_Instigator ); //tolua_export + virtual void KilledBy( cEntity* a_Killer ); //tolua_export + int GetHealth() { return m_Health; } //tolua_export + + enum MetaData {NORMAL, BURNING, CROUCHED, RIDING, SPRINTING, EATING, BLOCKING}; + + virtual void SetMetaData(MetaData a_MetaData); + virtual MetaData GetMetaData() { return m_MetaData; } + + virtual void InStateBurning(float a_Dt); + + virtual void CheckMetaDataBurn(); + + virtual void SetMaxHealth(short a_MaxHealth); + virtual short GetMaxHealth() { return m_MaxHealth; } + + //virtual void SetMaxFood(short a_MaxFood); + virtual short GetMaxFood() { return m_MaxFoodLevel / 6; } + virtual short GetFood() { return m_FoodLevel / 6; } + + //virtual void SetMaxFoodSaturation(float a_MaxFoodSaturation); + virtual float GetMaxFoodSaturation() { return fmod(m_MaxFoodLevel, 6.f); } + virtual float GetFoodSaturation() { return fmod(m_FoodLevel, 6.f); } + + virtual void SetMaxFoodLevel(short a_MaxFoodLevel); + virtual short GetMaxFoodLevel() { return m_MaxFoodLevel; } + +protected: + + short m_Health; + short m_FoodLevel; + short m_MaxHealth; + short m_MaxFoodLevel; + + bool m_bBurnable; + + MetaData m_MetaData; + + double m_LastPosX, m_LastPosY, m_LastPosZ; + float m_TimeLastTeleportPacket; + + float m_FireDamageInterval; + float m_BurnPeriod; + +}; //tolua_export + + + + diff --git a/source/cPickup.cpp b/source/cPickup.cpp index 5b35f215f..2302c56a3 100644 --- a/source/cPickup.cpp +++ b/source/cPickup.cpp @@ -1,316 +1,316 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#ifndef _WIN32
-#include <cstdlib>
-#endif
-
-#include "cPickup.h"
-#include "cClientHandle.h"
-#include "cInventory.h"
-#include "cWorld.h"
-#include "cWaterSimulator.h"
-#include "cServer.h"
-#include "cPlayer.h"
-#include "cPluginManager.h"
-#include "cItem.h"
-#include "cRoot.h"
-#include "cTracer.h"
-
-#include "packets/cPacket_TeleportEntity.h"
-#include "packets/cPacket_PickupSpawn.h"
-#include "packets/cPacket_CollectItem.h"
-
-#include "Vector3d.h"
-#include "Vector3f.h"
-
-
-
-
-
-CLASS_DEFINITION( cPickup, cEntity )
-
-cPickup::~cPickup()
-{
- delete m_Item;
-}
-
-cPickup::cPickup(int a_X, int a_Y, int a_Z, const cItem & a_Item, float a_SpeedX /* = 0.f */, float a_SpeedY /* = 0.f */, float a_SpeedZ /* = 0.f */)
- : cEntity( ((double)(a_X))/32, ((double)(a_Y))/32, ((double)(a_Z))/32 )
- , m_Speed( a_SpeedX, a_SpeedY, a_SpeedZ )
- , m_bOnGround( false )
- , m_bReplicated( false )
- , m_Timer( 0.f )
- , m_Item( new cItem( a_Item ) )
- , m_bCollected( false )
-{
-
- //LOG("New pickup: ID(%i) Amount(%i) Health(%i)", m_Item.m_ItemID, m_Item.m_ItemCount, m_Item.m_ItemHealth );
-
- // Spawn it on clients
- if (!a_Item.IsEmpty())
- {
- std::auto_ptr<cPacket> PickupSpawn(GetSpawnPacket());
- if (PickupSpawn.get() != NULL)
- {
- cRoot::Get()->GetServer()->Broadcast(*(PickupSpawn.get()));
- }
- }
-
- m_EntityType = eEntityType_Pickup;
-}
-
-
-
-
-
-cPickup::cPickup(cPacket_PickupSpawn* a_PickupSpawnPacket)
- : cEntity( ((double)a_PickupSpawnPacket->m_PosX)/32, ((double)a_PickupSpawnPacket->m_PosY)/32, ((double)a_PickupSpawnPacket->m_PosZ)/32 )
- , m_Speed( new Vector3f() )
- , m_ResultingSpeed(new Vector3f())
- , m_WaterSpeed(new Vector3f())
- , m_bOnGround( false )
- , m_bReplicated( false )
- , m_Timer( 0.f )
- , m_bCollected( false )
-{
- a_PickupSpawnPacket->m_UniqueID = m_UniqueID;
-
- m_Item = new cItem();
- m_Item->m_ItemID = (ENUM_ITEM_ID)a_PickupSpawnPacket->m_Item;
- m_Item->m_ItemCount = a_PickupSpawnPacket->m_Count;
- m_Item->m_ItemHealth = 0x0;
-
- m_Speed.x = (float)(a_PickupSpawnPacket->m_Rotation) / 8;
- m_Speed.y = (float)(a_PickupSpawnPacket->m_Pitch) / 8;
- m_Speed.z = (float)(a_PickupSpawnPacket->m_Roll) / 8;
-
- // Spawn it on clients
- if (a_PickupSpawnPacket->m_Item != E_ITEM_EMPTY)
- {
- cRoot::Get()->GetServer()->Broadcast( *a_PickupSpawnPacket );
- }
-
- m_EntityType = eEntityType_Pickup;
-}
-
-
-
-
-
-cPacket * cPickup::GetSpawnPacket(void) const
-{
- if (m_Item->IsEmpty())
- {
- return NULL;
- }
-
- cPacket_PickupSpawn * PickupSpawn = new cPacket_PickupSpawn;
- PickupSpawn->m_UniqueID = m_UniqueID;
- PickupSpawn->m_Item = (short)m_Item->m_ItemID;
- PickupSpawn->m_Count = m_Item->m_ItemCount;
- PickupSpawn->m_Health = m_Item->m_ItemHealth;
- PickupSpawn->m_PosX = (int) (m_Pos.x * 32);
- PickupSpawn->m_PosY = (int) (m_Pos.y * 32);
- PickupSpawn->m_PosZ = (int) (m_Pos.z * 32);
- PickupSpawn->m_Rotation = (char)(m_Speed.x * 8);
- PickupSpawn->m_Pitch = (char)(m_Speed.y * 8);
- PickupSpawn->m_Roll = (char)(m_Speed.z * 8);
- return PickupSpawn;
-}
-
-
-
-
-
-void cPickup::Tick(float a_Dt)
-{
- m_Timer += a_Dt;
- a_Dt = a_Dt / 1000.f;
- if(m_bCollected)
- {
- if(m_Timer > 500.f) // 0.5 second
- {
- Destroy();
- return;
- }
- }
-
- if( m_Timer > 1000*60*5 ) // 5 minutes
- {
- Destroy();
- return;
- }
-
- if( m_Pos.y < 0 ) // Out of this world!
- {
- Destroy();
- return;
- }
-
- if(!m_bCollected)
- {
- HandlePhysics( a_Dt );
- }
-
- if( !m_bReplicated || m_bDirtyPosition )
- {
- MoveToCorrectChunk();
- m_bReplicated = true;
- m_bDirtyPosition = false;
- cPacket_TeleportEntity TeleportEntity( this );
- GetWorld()->BroadcastToChunk( m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity );
- }
-}
-
-
-
-
-
-void cPickup::HandlePhysics(float a_Dt)
-{
- m_ResultingSpeed.Set(0.f, 0.f, 0.f);
- cWorld * World = GetWorld();
-
- if( m_bOnGround ) // check if it's still on the ground
- {
- int BlockX = (m_Pos.x)<0 ? (int)m_Pos.x-1 : (int)m_Pos.x;
- int BlockZ = (m_Pos.z)<0 ? (int)m_Pos.z-1 : (int)m_Pos.z;
- char BlockBelow = World->GetBlock( BlockX, (int)m_Pos.y -1, BlockZ );
- //Not only air, falls through water ;)
- if( BlockBelow == E_BLOCK_AIR || IsBlockWater(BlockBelow))
- {
- m_bOnGround = false;
- }
- char Block = World->GetBlock( BlockX, (int)m_Pos.y - (int)m_bOnGround, BlockZ );
- char BlockIn = World->GetBlock( BlockX, (int)m_Pos.y, BlockZ );
-
- if( IsBlockLava(Block) || Block == E_BLOCK_FIRE
- || IsBlockLava(BlockIn) || BlockIn == E_BLOCK_FIRE)
- {
- m_bCollected = true;
- m_Timer = 0;
- return;
- }
-
- if( BlockIn != E_BLOCK_AIR && !IsBlockWater(BlockIn) ) // If in ground itself, push it out
- {
- m_bOnGround = true;
- m_Pos.y += 0.2;
- m_bReplicated = false;
- }
- m_Speed.x *= 0.7f/(1+a_Dt);
- if( fabs(m_Speed.x) < 0.05 ) m_Speed.x = 0;
- m_Speed.z *= 0.7f/(1+a_Dt);
- if( fabs(m_Speed.z) < 0.05 ) m_Speed.z = 0;
- }
-
-
- //get flowing direction
- Direction WaterDir = World->GetWaterSimulator()->GetFlowingDirection((int) m_Pos.x - 1, (int) m_Pos.y, (int) m_Pos.z - 1);
-
-
- m_WaterSpeed *= 0.9f; //Keep old speed but lower it
-
- switch(WaterDir)
- {
- case X_PLUS:
- m_WaterSpeed.x = 1.f;
- m_bOnGround = false;
- break;
- case X_MINUS:
- m_WaterSpeed.x = -1.f;
- m_bOnGround = false;
- break;
- case Z_PLUS:
- m_WaterSpeed.z = 1.f;
- m_bOnGround = false;
- break;
- case Z_MINUS:
- m_WaterSpeed.z = -1.f;
- m_bOnGround = false;
- break;
-
- default:
- break;
- }
-
- m_ResultingSpeed += m_WaterSpeed;
-
-
- if( !m_bOnGround )
- {
-
- float Gravity = -9.81f*a_Dt;
- m_Speed.y += Gravity;
-
- // Set to hit position
- m_ResultingSpeed += m_Speed;
-
- cTracer Tracer( GetWorld() );
- int Ret = Tracer.Trace( m_Pos, m_Speed, 2 );
- if( Ret ) // Oh noez! we hit something
- {
-
-
- if( (Tracer.RealHit - Vector3f(m_Pos)).SqrLength() <= ( m_ResultingSpeed * a_Dt ).SqrLength() )
- {
- m_bReplicated = false; // It's only interesting to replicate when we actually hit something...
- if( Ret == 1 )
- {
-
- if( Tracer.HitNormal.x != 0.f ) m_Speed.x = 0.f;
- if( Tracer.HitNormal.y != 0.f ) m_Speed.y = 0.f;
- if( Tracer.HitNormal.z != 0.f ) m_Speed.z = 0.f;
-
- if( Tracer.HitNormal.y > 0 ) // means on ground
- {
- m_bOnGround = true;
- }
- }
- m_Pos = Tracer.RealHit;
- m_Pos += Tracer.HitNormal * 0.2f;
-
- }
- else
- m_Pos += m_ResultingSpeed*a_Dt;
- }
- else
- { // We didn't hit anything, so move =]
- m_Pos += m_ResultingSpeed * a_Dt;
- }
- }
- //Usable for debugging
- //SetPosition(m_Pos.x, m_Pos.y, m_Pos.z);
-}
-
-
-
-
-
-bool cPickup::CollectedBy( cPlayer* a_Dest )
-{
- if(m_bCollected) return false; // It's already collected!
- // 800 is to long
- if(m_Timer < 500.f) return false; // Not old enough
-
- if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_COLLECT_ITEM, 2, this, a_Dest ) ) return false;
-
- if( a_Dest->GetInventory().AddItem( *m_Item ) )
- {
- cPacket_CollectItem CollectItem;
- CollectItem.m_CollectedID = m_UniqueID;
- CollectItem.m_CollectorID = a_Dest->GetUniqueID();
- cRoot::Get()->GetServer()->Broadcast( CollectItem );
-
- m_bCollected = true;
- m_Timer = 0;
- return true;
- }
-
- return false;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#ifndef _WIN32 +#include <cstdlib> +#endif + +#include "cPickup.h" +#include "cClientHandle.h" +#include "cInventory.h" +#include "cWorld.h" +#include "cWaterSimulator.h" +#include "cServer.h" +#include "cPlayer.h" +#include "cPluginManager.h" +#include "cItem.h" +#include "cRoot.h" +#include "cTracer.h" + +#include "packets/cPacket_TeleportEntity.h" +#include "packets/cPacket_PickupSpawn.h" +#include "packets/cPacket_CollectItem.h" + +#include "Vector3d.h" +#include "Vector3f.h" + + + + + +CLASS_DEFINITION( cPickup, cEntity ) + +cPickup::~cPickup() +{ + delete m_Item; +} + +cPickup::cPickup(int a_X, int a_Y, int a_Z, const cItem & a_Item, float a_SpeedX /* = 0.f */, float a_SpeedY /* = 0.f */, float a_SpeedZ /* = 0.f */) + : cEntity( ((double)(a_X))/32, ((double)(a_Y))/32, ((double)(a_Z))/32 ) + , m_Speed( a_SpeedX, a_SpeedY, a_SpeedZ ) + , m_bOnGround( false ) + , m_bReplicated( false ) + , m_Timer( 0.f ) + , m_Item( new cItem( a_Item ) ) + , m_bCollected( false ) +{ + + //LOG("New pickup: ID(%i) Amount(%i) Health(%i)", m_Item.m_ItemID, m_Item.m_ItemCount, m_Item.m_ItemHealth ); + + // Spawn it on clients + if (!a_Item.IsEmpty()) + { + std::auto_ptr<cPacket> PickupSpawn(GetSpawnPacket()); + if (PickupSpawn.get() != NULL) + { + cRoot::Get()->GetServer()->Broadcast(*(PickupSpawn.get())); + } + } + + m_EntityType = eEntityType_Pickup; +} + + + + + +cPickup::cPickup(cPacket_PickupSpawn* a_PickupSpawnPacket) + : cEntity( ((double)a_PickupSpawnPacket->m_PosX)/32, ((double)a_PickupSpawnPacket->m_PosY)/32, ((double)a_PickupSpawnPacket->m_PosZ)/32 ) + , m_Speed( new Vector3f() ) + , m_ResultingSpeed(new Vector3f()) + , m_WaterSpeed(new Vector3f()) + , m_bOnGround( false ) + , m_bReplicated( false ) + , m_Timer( 0.f ) + , m_bCollected( false ) +{ + a_PickupSpawnPacket->m_UniqueID = m_UniqueID; + + m_Item = new cItem(); + m_Item->m_ItemID = (ENUM_ITEM_ID)a_PickupSpawnPacket->m_Item; + m_Item->m_ItemCount = a_PickupSpawnPacket->m_Count; + m_Item->m_ItemHealth = 0x0; + + m_Speed.x = (float)(a_PickupSpawnPacket->m_Rotation) / 8; + m_Speed.y = (float)(a_PickupSpawnPacket->m_Pitch) / 8; + m_Speed.z = (float)(a_PickupSpawnPacket->m_Roll) / 8; + + // Spawn it on clients + if (a_PickupSpawnPacket->m_Item != E_ITEM_EMPTY) + { + cRoot::Get()->GetServer()->Broadcast( *a_PickupSpawnPacket ); + } + + m_EntityType = eEntityType_Pickup; +} + + + + + +cPacket * cPickup::GetSpawnPacket(void) const +{ + if (m_Item->IsEmpty()) + { + return NULL; + } + + cPacket_PickupSpawn * PickupSpawn = new cPacket_PickupSpawn; + PickupSpawn->m_UniqueID = m_UniqueID; + PickupSpawn->m_Item = (short)m_Item->m_ItemID; + PickupSpawn->m_Count = m_Item->m_ItemCount; + PickupSpawn->m_Health = m_Item->m_ItemHealth; + PickupSpawn->m_PosX = (int) (m_Pos.x * 32); + PickupSpawn->m_PosY = (int) (m_Pos.y * 32); + PickupSpawn->m_PosZ = (int) (m_Pos.z * 32); + PickupSpawn->m_Rotation = (char)(m_Speed.x * 8); + PickupSpawn->m_Pitch = (char)(m_Speed.y * 8); + PickupSpawn->m_Roll = (char)(m_Speed.z * 8); + return PickupSpawn; +} + + + + + +void cPickup::Tick(float a_Dt) +{ + m_Timer += a_Dt; + a_Dt = a_Dt / 1000.f; + if(m_bCollected) + { + if(m_Timer > 500.f) // 0.5 second + { + Destroy(); + return; + } + } + + if( m_Timer > 1000*60*5 ) // 5 minutes + { + Destroy(); + return; + } + + if( m_Pos.y < 0 ) // Out of this world! + { + Destroy(); + return; + } + + if(!m_bCollected) + { + HandlePhysics( a_Dt ); + } + + if( !m_bReplicated || m_bDirtyPosition ) + { + MoveToCorrectChunk(); + m_bReplicated = true; + m_bDirtyPosition = false; + cPacket_TeleportEntity TeleportEntity( this ); + GetWorld()->BroadcastToChunk( m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity ); + } +} + + + + + +void cPickup::HandlePhysics(float a_Dt) +{ + m_ResultingSpeed.Set(0.f, 0.f, 0.f); + cWorld * World = GetWorld(); + + if( m_bOnGround ) // check if it's still on the ground + { + int BlockX = (m_Pos.x)<0 ? (int)m_Pos.x-1 : (int)m_Pos.x; + int BlockZ = (m_Pos.z)<0 ? (int)m_Pos.z-1 : (int)m_Pos.z; + char BlockBelow = World->GetBlock( BlockX, (int)m_Pos.y -1, BlockZ ); + //Not only air, falls through water ;) + if( BlockBelow == E_BLOCK_AIR || IsBlockWater(BlockBelow)) + { + m_bOnGround = false; + } + char Block = World->GetBlock( BlockX, (int)m_Pos.y - (int)m_bOnGround, BlockZ ); + char BlockIn = World->GetBlock( BlockX, (int)m_Pos.y, BlockZ ); + + if( IsBlockLava(Block) || Block == E_BLOCK_FIRE + || IsBlockLava(BlockIn) || BlockIn == E_BLOCK_FIRE) + { + m_bCollected = true; + m_Timer = 0; + return; + } + + if( BlockIn != E_BLOCK_AIR && !IsBlockWater(BlockIn) ) // If in ground itself, push it out + { + m_bOnGround = true; + m_Pos.y += 0.2; + m_bReplicated = false; + } + m_Speed.x *= 0.7f/(1+a_Dt); + if( fabs(m_Speed.x) < 0.05 ) m_Speed.x = 0; + m_Speed.z *= 0.7f/(1+a_Dt); + if( fabs(m_Speed.z) < 0.05 ) m_Speed.z = 0; + } + + + //get flowing direction + Direction WaterDir = World->GetWaterSimulator()->GetFlowingDirection((int) m_Pos.x - 1, (int) m_Pos.y, (int) m_Pos.z - 1); + + + m_WaterSpeed *= 0.9f; //Keep old speed but lower it + + switch(WaterDir) + { + case X_PLUS: + m_WaterSpeed.x = 1.f; + m_bOnGround = false; + break; + case X_MINUS: + m_WaterSpeed.x = -1.f; + m_bOnGround = false; + break; + case Z_PLUS: + m_WaterSpeed.z = 1.f; + m_bOnGround = false; + break; + case Z_MINUS: + m_WaterSpeed.z = -1.f; + m_bOnGround = false; + break; + + default: + break; + } + + m_ResultingSpeed += m_WaterSpeed; + + + if( !m_bOnGround ) + { + + float Gravity = -9.81f*a_Dt; + m_Speed.y += Gravity; + + // Set to hit position + m_ResultingSpeed += m_Speed; + + cTracer Tracer( GetWorld() ); + int Ret = Tracer.Trace( m_Pos, m_Speed, 2 ); + if( Ret ) // Oh noez! we hit something + { + + + if( (Tracer.RealHit - Vector3f(m_Pos)).SqrLength() <= ( m_ResultingSpeed * a_Dt ).SqrLength() ) + { + m_bReplicated = false; // It's only interesting to replicate when we actually hit something... + if( Ret == 1 ) + { + + if( Tracer.HitNormal.x != 0.f ) m_Speed.x = 0.f; + if( Tracer.HitNormal.y != 0.f ) m_Speed.y = 0.f; + if( Tracer.HitNormal.z != 0.f ) m_Speed.z = 0.f; + + if( Tracer.HitNormal.y > 0 ) // means on ground + { + m_bOnGround = true; + } + } + m_Pos = Tracer.RealHit; + m_Pos += Tracer.HitNormal * 0.2f; + + } + else + m_Pos += m_ResultingSpeed*a_Dt; + } + else + { // We didn't hit anything, so move =] + m_Pos += m_ResultingSpeed * a_Dt; + } + } + //Usable for debugging + //SetPosition(m_Pos.x, m_Pos.y, m_Pos.z); +} + + + + + +bool cPickup::CollectedBy( cPlayer* a_Dest ) +{ + if(m_bCollected) return false; // It's already collected! + // 800 is to long + if(m_Timer < 500.f) return false; // Not old enough + + if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_COLLECT_ITEM, 2, this, a_Dest ) ) return false; + + if( a_Dest->GetInventory().AddItem( *m_Item ) ) + { + cPacket_CollectItem CollectItem; + CollectItem.m_CollectedID = m_UniqueID; + CollectItem.m_CollectorID = a_Dest->GetUniqueID(); + cRoot::Get()->GetServer()->Broadcast( CollectItem ); + + m_bCollected = true; + m_Timer = 0; + return true; + } + + return false; +} + + + + diff --git a/source/cPickup.h b/source/cPickup.h index 26bce5029..a13767738 100644 --- a/source/cPickup.h +++ b/source/cPickup.h @@ -1,53 +1,53 @@ -
-#pragma once
-
-#include "cEntity.h"
-
-
-
-
-class cPacket_PickupSpawn;
-class cPlayer;
-class cItem;
-
-
-
-
-
-class cPickup : public cEntity //tolua_export
-{ //tolua_export
-public:
- CLASS_PROTOTYPE();
-
- cPickup(int a_X, int a_Y, int a_Z, const cItem & a_Item, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f); //tolua_export
- cPickup(cPacket_PickupSpawn * a_PickupSpawnPacket); //tolua_export
- ~cPickup(); //tolua_export
-
- cItem * GetItem() { return m_Item; } //tolua_export
-
- virtual cPacket * GetSpawnPacket(void) const override;
-
- virtual bool CollectedBy( cPlayer* a_Dest ); //tolua_export
-
- void Tick(float a_Dt);
- void HandlePhysics(float a_Dt);
-
-private:
-
- Vector3f m_Speed;
- Vector3f m_ResultingSpeed; //Can be used to modify the resulting speed for the current tick ;)
-
- Vector3f m_WaterSpeed;
- bool m_bOnGround;
- bool m_bReplicated;
-
- float m_Timer;
-
- cItem* m_Item;
-
- bool m_bCollected;
-}; //tolua_export
-
-
-
-
+ +#pragma once + +#include "cEntity.h" + + + + +class cPacket_PickupSpawn; +class cPlayer; +class cItem; + + + + + +class cPickup : public cEntity //tolua_export +{ //tolua_export +public: + CLASS_PROTOTYPE(); + + cPickup(int a_X, int a_Y, int a_Z, const cItem & a_Item, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f); //tolua_export + cPickup(cPacket_PickupSpawn * a_PickupSpawnPacket); //tolua_export + ~cPickup(); //tolua_export + + cItem * GetItem() { return m_Item; } //tolua_export + + virtual cPacket * GetSpawnPacket(void) const override; + + virtual bool CollectedBy( cPlayer* a_Dest ); //tolua_export + + void Tick(float a_Dt); + void HandlePhysics(float a_Dt); + +private: + + Vector3f m_Speed; + Vector3f m_ResultingSpeed; //Can be used to modify the resulting speed for the current tick ;) + + Vector3f m_WaterSpeed; + bool m_bOnGround; + bool m_bReplicated; + + float m_Timer; + + cItem* m_Item; + + bool m_bCollected; +}; //tolua_export + + + + diff --git a/source/cPig.cpp b/source/cPig.cpp index 2654b41cf..14a713954 100644 --- a/source/cPig.cpp +++ b/source/cPig.cpp @@ -1,51 +1,51 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPig.h"
-
-
-
-
-
-cPig::cPig()
-{
- m_MobType = 90;
- GetMonsterConfig("Pig");
-}
-
-
-
-
-
-cPig::~cPig()
-{
-}
-
-
-
-
-
-bool cPig::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cPig" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
-
-
-
-
-
-void cPig::KilledBy( cEntity* a_Killer )
-{
- cItems Drops;
- AddRandomDropItem(Drops, 0, 2, E_ITEM_RAW_MEAT);
- m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
-
- // TODO: Check for burning state
-
- cMonster::KilledBy( a_Killer );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPig.h" + + + + + +cPig::cPig() +{ + m_MobType = 90; + GetMonsterConfig("Pig"); +} + + + + + +cPig::~cPig() +{ +} + + + + + +bool cPig::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cPig" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cPig::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_RAW_MEAT); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + // TODO: Check for burning state + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cPig.h b/source/cPig.h index 32947c2c1..481aa2969 100644 --- a/source/cPig.h +++ b/source/cPig.h @@ -1,14 +1,14 @@ -#pragma once
-
-#include "cPassiveMonster.h"
-
-class cPig : public cPassiveMonster
-{
-public:
- cPig();
- ~cPig();
-
- virtual bool IsA( const char* a_EntityType );
-
- virtual void KilledBy( cEntity* a_Killer );
-};
+#pragma once + +#include "cPassiveMonster.h" + +class cPig : public cPassiveMonster +{ +public: + cPig(); + ~cPig(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/cPiston.cpp b/source/cPiston.cpp index c89fb5077..8cf463c1b 100644 --- a/source/cPiston.cpp +++ b/source/cPiston.cpp @@ -1,165 +1,165 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPiston.h"
-#include "cRedstone.h"
-#include "ChunkDef.h"
-#include "cPickup.h"
-#include "cBlockToPickup.h"
-#include "cItem.h"
-#include "cRoot.h"
-#include "cClientHandle.h"
-#include "cWorld.h"
-#include "BlockID.h"
-#include "packets/cPacket_BlockAction.h"
-#include "cServer.h"
-
-extern bool g_BlockPistonBreakable[];
-
-#define AddDir( x, y, z, dir, amount ) switch(dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\
- case 2: (z)-=(amount); break; case 3: (z)+=(amount); break;\
- case 4: (x)-=(amount); break; case 5: (x)+=(amount); break; }
-
-
-
-
-
-cPiston::cPiston( cWorld* a_World )
- :m_World ( a_World )
-{
-
-}
-
-unsigned short cPiston::FirstPassthroughBlock( int pistonX, int pistonY, int pistonZ, char pistonmeta ) {
- unsigned short ret;
- pistonmeta &= 7;
- if(pistonmeta >= 6) { // just in case, it shouldn't happen but if it would, it'd case inf loop
- printf("cPiston::FirstPassthroughBlock - piston has invalid meta data!\n");
- return 9001;
- }
- char currBlock;
- for( ret = 0; ret < 24; ret++ ) { // push up to 24 blocks
- AddDir( pistonX, pistonY, pistonZ, pistonmeta, 1 )
- currBlock = m_World->GetBlock( pistonX, pistonY, pistonZ );
- if(currBlock == E_BLOCK_BEDROCK || currBlock == E_BLOCK_OBSIDIAN || currBlock == E_BLOCK_PISTON_EXTENSION ) {return 9001;}
- if(g_BlockPistonBreakable[currBlock]) {return ret;}
- }
- return 9001;
-}
-
-
-
-
-
-void cPiston::ExtendPiston( int pistx, int pisty, int pistz )
-{
- char pistonBlock = m_World->GetBlock( pistx, pisty, pistz );
- char pistonMeta = m_World->GetBlockMeta( pistx, pisty, pistz );
- char isSticky = (char)(pistonBlock == E_BLOCK_STICKY_PISTON) * 8;
- bool recalc = false;
- if ( (pistonMeta & 0x8) == 0x0 ) // only extend if piston is not already extended
- {
- unsigned short dist = FirstPassthroughBlock(pistx, pisty, pistz, pistonMeta);
- if (dist > 9000) return; // too many blocks
-
- AddDir( pistx, pisty, pistz, pistonMeta & 7, dist+1 )
- BLOCKTYPE currBlock = m_World->GetBlock (pistx, pisty, pistz);
- NIBBLETYPE currMeta = m_World->GetBlockMeta(pistx, pisty, pistz);
- if (currBlock != E_BLOCK_AIR)
- {
- cItems PickupItems;
- cBlockToPickup::ToPickup(currBlock, currMeta, E_ITEM_EMPTY, PickupItems);
- m_World->SpawnItemPickups(PickupItems, pistx, pisty, pistz);
- recalc = true;
- }
- int oldx = pistx, oldy = pisty, oldz = pistz;
- char currBlockMeta;
- for (int i = dist+1; i>0; i--)
- {
- AddDir( pistx, pisty, pistz, pistonMeta & 7, -1 )
- currBlock = m_World->GetBlock( pistx, pisty, pistz );
- currBlockMeta = m_World->GetBlockMeta( pistx, pisty, pistz );
- m_World->SetBlock( oldx, oldy, oldz, currBlock, currBlockMeta );
- oldx = pistx;
- oldy = pisty;
- oldz = pistz;
- }
- cPacket_BlockAction Action;
- Action.m_PosX = (int)pistx;
- Action.m_PosY = (short)pisty;
- Action.m_PosZ = (int)pistz;
- Action.m_Byte1 = 0;
- Action.m_Byte2 = pistonMeta;
-
- m_World->BroadcastToChunkOfBlock(pistx, pisty, pistz, &Action);
- m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8 );
-
- int extx = pistx;
- int exty = pisty;
- int extz = pistz;
-
- AddDir( extx, exty, extz, pistonMeta&7, 1 )
-
- m_World->SetBlock( extx, exty, extz, E_BLOCK_PISTON_EXTENSION, isSticky+pistonMeta&7 );
-
- if (recalc) {
- cRedstone Redstone(m_World);
- Redstone.ChangeRedstone( extx, exty, extz, false ); //recalculate redstone around current device.
- Redstone.ChangeRedstone( pistx, pisty, pistz, false ); //recalculate redstone around current device.
- }
- }
-}
-
-
-
-
-
-void cPiston::RetractPiston( int pistx, int pisty, int pistz )
-{
- char pistonBlock = m_World->GetBlock( pistx, pisty, pistz );
- char pistonMeta = m_World->GetBlockMeta( pistx, pisty, pistz );
- if (pistonMeta <= 6) // only retract if piston is not already retracted
- {
- return;
- }
-
- //send blockaction packet
- cPacket_BlockAction Action;
- Action.m_PosX = (int)pistx;
- Action.m_PosY = (short)pisty;
- Action.m_PosZ = (int)pistz;
- Action.m_Byte1 = 1;
- Action.m_Byte2 = pistonMeta & ~(8);
- m_World->BroadcastToChunkOfBlock(pistx, pisty, pistz, &Action );
- m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8) );
-
- AddDir( pistx, pisty, pistz, pistonMeta & 7, 1 )
- if ( m_World->GetBlock( pistx, pisty, pistz ) == E_BLOCK_PISTON_EXTENSION )
- {
- if ( pistonBlock == E_BLOCK_STICKY_PISTON )
- {
- int tempx = pistx, tempy = pisty, tempz = pistz;
- AddDir( tempx, tempy, tempz, pistonMeta & 7, 1 )
- char tempblock = m_World->GetBlock( tempx, tempy, tempz );
- if (
- (tempblock == E_BLOCK_OBSIDIAN) ||
- (tempblock == E_BLOCK_BEDROCK) ||
- (tempblock == E_BLOCK_PISTON_EXTENSION)
- )
- {
- // These cannot be moved by the sticky piston, bail out
- return;
- }
- m_World->SetBlock( pistx, pisty, pistz, tempblock, m_World->GetBlockMeta( tempx, tempy, tempz ) );
- m_World->SetBlock( tempx, tempy, tempz, E_BLOCK_AIR, 0 );
- }
- else
- {
- m_World->SetBlock( pistx, pisty, pistz, E_BLOCK_AIR, 0 );
- }
- }
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPiston.h" +#include "cRedstone.h" +#include "ChunkDef.h" +#include "cPickup.h" +#include "cBlockToPickup.h" +#include "cItem.h" +#include "cRoot.h" +#include "cClientHandle.h" +#include "cWorld.h" +#include "BlockID.h" +#include "packets/cPacket_BlockAction.h" +#include "cServer.h" + +extern bool g_BlockPistonBreakable[]; + +#define AddDir( x, y, z, dir, amount ) switch(dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\ + case 2: (z)-=(amount); break; case 3: (z)+=(amount); break;\ + case 4: (x)-=(amount); break; case 5: (x)+=(amount); break; } + + + + + +cPiston::cPiston( cWorld* a_World ) + :m_World ( a_World ) +{ + +} + +unsigned short cPiston::FirstPassthroughBlock( int pistonX, int pistonY, int pistonZ, char pistonmeta ) { + unsigned short ret; + pistonmeta &= 7; + if(pistonmeta >= 6) { // just in case, it shouldn't happen but if it would, it'd case inf loop + printf("cPiston::FirstPassthroughBlock - piston has invalid meta data!\n"); + return 9001; + } + char currBlock; + for( ret = 0; ret < 24; ret++ ) { // push up to 24 blocks + AddDir( pistonX, pistonY, pistonZ, pistonmeta, 1 ) + currBlock = m_World->GetBlock( pistonX, pistonY, pistonZ ); + if(currBlock == E_BLOCK_BEDROCK || currBlock == E_BLOCK_OBSIDIAN || currBlock == E_BLOCK_PISTON_EXTENSION ) {return 9001;} + if(g_BlockPistonBreakable[currBlock]) {return ret;} + } + return 9001; +} + + + + + +void cPiston::ExtendPiston( int pistx, int pisty, int pistz ) +{ + char pistonBlock = m_World->GetBlock( pistx, pisty, pistz ); + char pistonMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); + char isSticky = (char)(pistonBlock == E_BLOCK_STICKY_PISTON) * 8; + bool recalc = false; + if ( (pistonMeta & 0x8) == 0x0 ) // only extend if piston is not already extended + { + unsigned short dist = FirstPassthroughBlock(pistx, pisty, pistz, pistonMeta); + if (dist > 9000) return; // too many blocks + + AddDir( pistx, pisty, pistz, pistonMeta & 7, dist+1 ) + BLOCKTYPE currBlock = m_World->GetBlock (pistx, pisty, pistz); + NIBBLETYPE currMeta = m_World->GetBlockMeta(pistx, pisty, pistz); + if (currBlock != E_BLOCK_AIR) + { + cItems PickupItems; + cBlockToPickup::ToPickup(currBlock, currMeta, E_ITEM_EMPTY, PickupItems); + m_World->SpawnItemPickups(PickupItems, pistx, pisty, pistz); + recalc = true; + } + int oldx = pistx, oldy = pisty, oldz = pistz; + char currBlockMeta; + for (int i = dist+1; i>0; i--) + { + AddDir( pistx, pisty, pistz, pistonMeta & 7, -1 ) + currBlock = m_World->GetBlock( pistx, pisty, pistz ); + currBlockMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); + m_World->SetBlock( oldx, oldy, oldz, currBlock, currBlockMeta ); + oldx = pistx; + oldy = pisty; + oldz = pistz; + } + cPacket_BlockAction Action; + Action.m_PosX = (int)pistx; + Action.m_PosY = (short)pisty; + Action.m_PosZ = (int)pistz; + Action.m_Byte1 = 0; + Action.m_Byte2 = pistonMeta; + + m_World->BroadcastToChunkOfBlock(pistx, pisty, pistz, &Action); + m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8 ); + + int extx = pistx; + int exty = pisty; + int extz = pistz; + + AddDir( extx, exty, extz, pistonMeta&7, 1 ) + + m_World->SetBlock( extx, exty, extz, E_BLOCK_PISTON_EXTENSION, isSticky+pistonMeta&7 ); + + if (recalc) { + cRedstone Redstone(m_World); + Redstone.ChangeRedstone( extx, exty, extz, false ); //recalculate redstone around current device. + Redstone.ChangeRedstone( pistx, pisty, pistz, false ); //recalculate redstone around current device. + } + } +} + + + + + +void cPiston::RetractPiston( int pistx, int pisty, int pistz ) +{ + char pistonBlock = m_World->GetBlock( pistx, pisty, pistz ); + char pistonMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); + if (pistonMeta <= 6) // only retract if piston is not already retracted + { + return; + } + + //send blockaction packet + cPacket_BlockAction Action; + Action.m_PosX = (int)pistx; + Action.m_PosY = (short)pisty; + Action.m_PosZ = (int)pistz; + Action.m_Byte1 = 1; + Action.m_Byte2 = pistonMeta & ~(8); + m_World->BroadcastToChunkOfBlock(pistx, pisty, pistz, &Action ); + m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8) ); + + AddDir( pistx, pisty, pistz, pistonMeta & 7, 1 ) + if ( m_World->GetBlock( pistx, pisty, pistz ) == E_BLOCK_PISTON_EXTENSION ) + { + if ( pistonBlock == E_BLOCK_STICKY_PISTON ) + { + int tempx = pistx, tempy = pisty, tempz = pistz; + AddDir( tempx, tempy, tempz, pistonMeta & 7, 1 ) + char tempblock = m_World->GetBlock( tempx, tempy, tempz ); + if ( + (tempblock == E_BLOCK_OBSIDIAN) || + (tempblock == E_BLOCK_BEDROCK) || + (tempblock == E_BLOCK_PISTON_EXTENSION) + ) + { + // These cannot be moved by the sticky piston, bail out + return; + } + m_World->SetBlock( pistx, pisty, pistz, tempblock, m_World->GetBlockMeta( tempx, tempy, tempz ) ); + m_World->SetBlock( tempx, tempy, tempz, E_BLOCK_AIR, 0 ); + } + else + { + m_World->SetBlock( pistx, pisty, pistz, E_BLOCK_AIR, 0 ); + } + } +} + + + + diff --git a/source/cPiston.h b/source/cPiston.h index 54111f9d6..d74f0c0a4 100644 --- a/source/cPiston.h +++ b/source/cPiston.h @@ -1,60 +1,60 @@ -
-#pragma once
-
-
-
-
-
-// fwd: "cWorld.h"
-class cWorld;
-
-
-
-
-
-class cPiston
-{
-public:
-
- cPiston( cWorld* a_World );
-
- static char RotationPitchToMetaData( float a_Rotation, float a_Pitch )
- {
- LOG("pre:a_Rotation %f \n",a_Rotation);
- LOG("a_Pitch %f \n",a_Pitch);
-
- if (a_Pitch >= 50.f ){
- return 0x1;
- } else if ( a_Pitch <= -50.f ) {
- return 0x0;
- } else {
-
- a_Rotation += 90 + 45; // So its not aligned with axis
- std::printf("a_Rotation %f \n",a_Rotation);
-
- if( a_Rotation > 360.f ) a_Rotation -= 360.f;
- if( a_Rotation >= 0.f && a_Rotation < 90.f )
- { LOG("1111\n");return 0x4;}
- else if( a_Rotation >= 180 && a_Rotation < 270 )
- { LOG("2222\n");return 0x5;}
- else if( a_Rotation >= 90 && a_Rotation < 180 )
- { LOG("3333\n");return 0x2;}
- else
- { LOG("4444\n");return 0x3;}
- }
- }
-
- void ExtendPiston( int, int, int );
- void RetractPiston( int, int, int );
-
- cWorld* m_World;
-
-private:
- void ChainMove( int, int, int, char, unsigned short * );
- unsigned short FirstPassthroughBlock( int, int, int, char );
-
-};
-
-
-
-
+ +#pragma once + + + + + +// fwd: "cWorld.h" +class cWorld; + + + + + +class cPiston +{ +public: + + cPiston( cWorld* a_World ); + + static char RotationPitchToMetaData( float a_Rotation, float a_Pitch ) + { + LOG("pre:a_Rotation %f \n",a_Rotation); + LOG("a_Pitch %f \n",a_Pitch); + + if (a_Pitch >= 50.f ){ + return 0x1; + } else if ( a_Pitch <= -50.f ) { + return 0x0; + } else { + + a_Rotation += 90 + 45; // So its not aligned with axis + std::printf("a_Rotation %f \n",a_Rotation); + + if( a_Rotation > 360.f ) a_Rotation -= 360.f; + if( a_Rotation >= 0.f && a_Rotation < 90.f ) + { LOG("1111\n");return 0x4;} + else if( a_Rotation >= 180 && a_Rotation < 270 ) + { LOG("2222\n");return 0x5;} + else if( a_Rotation >= 90 && a_Rotation < 180 ) + { LOG("3333\n");return 0x2;} + else + { LOG("4444\n");return 0x3;} + } + } + + void ExtendPiston( int, int, int ); + void RetractPiston( int, int, int ); + + cWorld* m_World; + +private: + void ChainMove( int, int, int, char, unsigned short * ); + unsigned short FirstPassthroughBlock( int, int, int, char ); + +}; + + + + diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp index 60ae9f888..a7159b2cf 100644 --- a/source/cPlayer.cpp +++ b/source/cPlayer.cpp @@ -1,1062 +1,1062 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPlayer.h"
-#include "cServer.h"
-#include "cCreativeInventory.h"
-#include "cSurvivalInventory.h"
-#include "cClientHandle.h"
-#include "cWorld.h"
-#include "cPickup.h"
-#include "cPluginManager.h"
-#include "cWindow.h"
-#include "cBlockEntity.h"
-#include "cGroupManager.h"
-#include "cGroup.h"
-#include "cChatColor.h"
-#include "cItem.h"
-#include "cTracer.h"
-#include "cRoot.h"
-#include "cMakeDir.h"
-#include "cTimer.h"
-#include "MersenneTwister.h"
-
-#include "packets/cPacket_NamedEntitySpawn.h"
-#include "packets/cPacket_EntityLook.h"
-#include "packets/cPacket_TeleportEntity.h"
-#include "packets/cPacket_RelativeEntityMove.h"
-#include "packets/cPacket_RelativeEntityMoveLook.h"
-#include "packets/cPacket_UpdateHealth.h"
-#include "packets/cPacket_Respawn.h"
-#include "packets/cPacket_DestroyEntity.h"
-#include "packets/cPacket_Metadata.h"
-#include "packets/cPacket_Chat.h"
-#include "packets/cPacket_NewInvalidState.h"
-#include "packets/cPacket_BlockAction.h"
-
-#include "Vector3d.h"
-#include "Vector3f.h"
-
-#include "../iniFile/iniFile.h"
-#include <json/json.h>
-
-#define float2int(x) ((x)<0 ? ((int)(x))-1 : (int)(x))
-
-
-
-
-
-CLASS_DEFINITION( cPlayer, cPawn );
-
-
-
-
-
-cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
- : m_GameMode( eGameMode_Survival )
- , m_IP("")
- , m_LastBlockActionTime( 0 )
- , m_LastBlockActionCnt( 0 )
- , m_bVisible( true )
- , m_LastGroundHeight( 0 )
- , m_bTouchGround( false )
- , m_Stance( 0.0 )
- , m_Inventory( 0 )
- , m_CurrentWindow( 0 )
- , m_TimeLastPickupCheck( 0.f )
- , m_Color('-')
- , m_ClientHandle( a_Client )
-{
- LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d",
- a_PlayerName.c_str(), a_Client->GetSocket().GetIPString().c_str(),
- this, GetUniqueID()
- );
- m_EntityType = eEntityType_Player;
- SetMaxHealth(20);
- SetMaxFoodLevel(125);
- m_Inventory = new cSurvivalInventory( this );
- m_CreativeInventory = new cCreativeInventory(this);
- cTimer t1;
- m_LastPlayerListTime = t1.GetNowTime();
-
- m_TimeLastTeleportPacket = cWorld::GetTime();
- m_TimeLastPickupCheck = cWorld::GetTime();
-
- m_PlayerName = a_PlayerName;
- m_bDirtyPosition = true; // So chunks are streamed to player at spawn
-
- if( !LoadFromDisk() )
- {
- m_Inventory->Clear();
- m_CreativeInventory->Clear();
- m_Pos.x = cRoot::Get()->GetDefaultWorld()->GetSpawnX();
- m_Pos.y = cRoot::Get()->GetDefaultWorld()->GetSpawnY();
- m_Pos.z = cRoot::Get()->GetDefaultWorld()->GetSpawnZ();
-
- LOGD("Player \"%s\" is connecting for the first time, spawning at default world spawn {%.2f, %.2f, %.2f}",
- a_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z
- );
- }
-}
-
-
-
-
-
-void cPlayer::Initialize( cWorld* a_World )
-{
- cPawn::Initialize( a_World );
- GetWorld()->AddPlayer( this );
-}
-
-
-
-
-
-cPlayer::~cPlayer(void)
-{
- LOG("Deleting cPlayer \"%s\" at %p, ID %d", m_PlayerName.c_str(), this, GetUniqueID());
-
- SaveToDisk();
-
- m_World->RemovePlayer( this );
-
- m_ClientHandle = NULL;
-
- delete m_Inventory;
- m_Inventory = NULL;
-
- delete m_CreativeInventory;
-
- LOG("Player %p deleted", this);
-}
-
-
-
-
-
-void cPlayer::Destroyed()
-{
- CloseWindow(-1);
- m_ClientHandle = NULL;
-}
-
-
-
-
-
-cPacket * cPlayer::GetSpawnPacket(void) const
-{
- LOGD("cPlayer::GetSpawnPacket for \"%s\" at pos {%.2f, %.2f, %.2f}",
- m_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z
- );
-
- if (!m_bVisible )
- {
- return NULL;
- }
-
- cPacket_NamedEntitySpawn * SpawnPacket = new cPacket_NamedEntitySpawn;
- SpawnPacket->m_UniqueID = m_UniqueID;
- SpawnPacket->m_PlayerName = m_PlayerName;
- SpawnPacket->m_PosX = (int)(m_Pos.x * 32);
- SpawnPacket->m_PosY = (int)(m_Pos.y * 32);
- SpawnPacket->m_PosZ = (int)(m_Pos.z * 32);
- SpawnPacket->m_Rotation = (char)((m_Rot.x / 360.f) * 256);
- SpawnPacket->m_Pitch = (char)((m_Rot.y / 360.f) * 256);
- short ItemID = (short)m_Inventory->GetEquippedItem().m_ItemID;
- SpawnPacket->m_CurrentItem = (ItemID > 0) ? ItemID : 0; // Unlike -1 in inventory, the named entity packet uses 0 for "none"
- return SpawnPacket;
-}
-
-
-
-
-
-void cPlayer::Tick(float a_Dt)
-{
- if (!m_ClientHandle->IsPlaying())
- {
- // We're not yet in the game, ignore everything
- return;
- }
-
- cPawn::Tick(a_Dt);
-
- if (m_bDirtyOrientation && !m_bDirtyPosition)
- {
- cPacket_EntityLook EntityLook(*this);
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityLook, m_ClientHandle );
- cPacket_EntityHeadLook EntityHeadLook(*this);
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityHeadLook, m_ClientHandle);
- m_bDirtyOrientation = false;
- }
- else if (m_bDirtyPosition )
- {
- cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_MOVE, 1, this );
-
- float DiffX = (float)(GetPosX() - m_LastPosX );
- float DiffY = (float)(GetPosY() - m_LastPosY );
- float DiffZ = (float)(GetPosZ() - m_LastPosZ );
- float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ;
- if (
- (SqrDist > 4 * 4) || // 4 blocks is max Relative Move
- (cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds
- )
- {
- //LOG("Teleported %f", sqrtf(SqrDist) );
- cPacket_TeleportEntity TeleportEntity( this );
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity, m_ClientHandle);
- m_TimeLastTeleportPacket = cWorld::GetTime();
- }
- else
- { // Relative move sucks balls! It's always wrong wtf!
- if( m_bDirtyOrientation )
- {
- cPacket_RelativeEntityMoveLook RelativeEntityMoveLook;
- RelativeEntityMoveLook.m_UniqueID = GetUniqueID();
- RelativeEntityMoveLook.m_MoveX = (char)(DiffX*32);
- RelativeEntityMoveLook.m_MoveY = (char)(DiffY*32);
- RelativeEntityMoveLook.m_MoveZ = (char)(DiffZ*32);
- RelativeEntityMoveLook.m_Yaw = (char)((GetRotation()/360.f)*256);
- RelativeEntityMoveLook.m_Pitch = (char)((GetPitch()/360.f)*256);
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMoveLook, m_ClientHandle );
- }
- else
- {
- cPacket_RelativeEntityMove RelativeEntityMove;
- RelativeEntityMove.m_UniqueID = GetUniqueID();
- RelativeEntityMove.m_MoveX = (char)(DiffX*32);
- RelativeEntityMove.m_MoveY = (char)(DiffY*32);
- RelativeEntityMove.m_MoveZ = (char)(DiffZ*32);
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMove, m_ClientHandle );
- }
- }
- m_LastPosX = GetPosX();
- m_LastPosY = GetPosY();
- m_LastPosZ = GetPosZ();
- m_bDirtyPosition = false;
- m_ClientHandle->StreamChunks();
- }
-
- if (m_Health > 0) // make sure player is alive
- {
- m_World->CollectPickupsByPlayer(this);
- }
-
- cTimer t1;
- // Send Player List (Once per m_LastPlayerListTime/1000 ms)
- if (m_LastPlayerListTime + cPlayer::PLAYER_LIST_TIME_MS <= t1.GetNowTime())
- {
- m_World->SendPlayerList(this);
- m_LastPlayerListTime = t1.GetNowTime();
- }
-}
-
-
-
-
-
-void cPlayer::SetTouchGround( bool a_bTouchGround )
-{
- m_bTouchGround = a_bTouchGround;
-
- if( !m_bTouchGround )
- {
- cWorld* World = GetWorld();
- char BlockID = World->GetBlock( float2int(m_Pos.x), float2int(m_Pos.y), float2int(m_Pos.z) );
- if( BlockID != E_BLOCK_AIR )
- {
- m_bTouchGround = true;
- }
- if( BlockID == E_BLOCK_WATER || BlockID == E_BLOCK_STATIONARY_WATER || BlockID == E_BLOCK_LADDER || BlockID == E_BLOCK_TORCH )
- {
- m_LastGroundHeight = (float)m_Pos.y;
- }
- }
-
- if( m_bTouchGround )
- {
- float Dist = (float)(m_LastGroundHeight - m_Pos.y);
- if( Dist > 4.f ) // Player dropped
- {
- int Damage = (int)(Dist - 4.f);
- if( Damage > 0 )
- {
- TakeDamage( Damage, 0 );
- }
- }
-
- m_LastGroundHeight = (float)m_Pos.y;
- }
-}
-
-void cPlayer::Heal( int a_Health )
-{
- if( m_Health < GetMaxHealth() )
- {
- m_Health = (short) MIN(a_Health + m_Health, GetMaxHealth());
-
- cPacket_UpdateHealth Health;
- Health.m_Health = m_Health;
- Health.m_Food = GetFood();
- Health.m_Saturation = GetFoodSaturation();
- m_ClientHandle->Send( Health );
- }
-}
-
-
-
-
-
-bool cPlayer::Feed(short a_Food)
-{
- if (m_FoodLevel >= GetMaxFoodLevel())
- {
- return false;
- }
-
- m_FoodLevel = MIN(a_Food + m_FoodLevel, GetMaxFoodLevel());
-
- cPacket_UpdateHealth Health;
- Health.m_Health = m_Health;
- Health.m_Food = GetFood();
- Health.m_Saturation = GetFoodSaturation();
- m_ClientHandle->Send( Health );
- return true;
-}
-
-
-
-
-
-void cPlayer::TakeDamage( int a_Damage, cEntity* a_Instigator )
-{
- if ( !(m_GameMode == 1) ) {
- cPawn::TakeDamage( a_Damage, a_Instigator );
-
- cPacket_UpdateHealth Health;
- Health.m_Health = m_Health;
- Health.m_Food = GetFood();
- Health.m_Saturation = GetFoodSaturation();
- //TODO: Causes problems sometimes O.o (E.G. Disconnecting when attacked)
- if(m_ClientHandle != 0)
- m_ClientHandle->Send( Health );
- }
-}
-
-
-
-
-
-void cPlayer::KilledBy(cEntity * a_Killer)
-{
- cPawn::KilledBy(a_Killer);
-
- if (m_Health > 0)
- {
- return; // not dead yet =]
- }
-
- m_bVisible = false; // So new clients don't see the player
-
- // Puke out all the items
- cItem* Items = m_Inventory->GetSlots();
- cItems Pickups;
- for (unsigned int i = 1; i < m_Inventory->c_NumSlots; ++i)
- {
- if( !Items[i].IsEmpty() )
- {
- Pickups.push_back(Items[i]);
- }
- Items[i].Empty();
- }
- m_World->SpawnItemPickups(Pickups, m_Pos.x, m_Pos.y, m_Pos.z, 10);
- SaveToDisk(); // Save it, yeah the world is a tough place !
-}
-
-
-
-
-
-void cPlayer::Respawn()
-{
- m_Health = GetMaxHealth();
-
- // Create Respawn player packet
- cPacket_Respawn Packet;
- //Set Gamemode for packet by looking at world's gamemode (Need to check players gamemode.)
- //Packet.m_CreativeMode = (char)GetWorld()->GetGameMode();
- Packet.m_CreativeMode = (char)m_GameMode; //Set GameMode packet based on Player's GameMode;
-
- //Send Packet
- m_ClientHandle->Send( Packet );
-
- //Set non Burning
- SetMetaData(NORMAL);
-
- TeleportTo( GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ() );
-
- SetVisible( true );
-}
-
-double cPlayer::GetEyeHeight()
-{
- return m_Stance;
-}
-
-Vector3d cPlayer::GetEyePosition()
-{
- return Vector3d( m_Pos.x, m_Stance, m_Pos.z );
-}
-
-void cPlayer::OpenWindow( cWindow* a_Window )
-{
- CloseWindow(m_CurrentWindow ? (char)m_CurrentWindow->GetWindowType() : 0);
- a_Window->Open( *this );
- m_CurrentWindow = a_Window;
-}
-
-
-
-
-
-void cPlayer::CloseWindow(char a_WindowType)
-{
- if (a_WindowType == 0)
- {
- // Inventory
- if (
- (m_Inventory->GetWindow()->GetDraggingItem() != NULL) &&
- (m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount > 0)
- )
- {
- LOG("Player holds item! Dropping it...");
- TossItem( true, m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount );
- }
-
- //Drop whats in the crafting slots (1, 2, 3, 4)
- cItems Drops;
- for (int i = 1; i <= 4; i++)
- {
- cItem* Item = m_Inventory->GetSlot( i );
- if (!Item->IsEmpty())
- {
- Drops.push_back(*Item);
- }
- Item->Empty();
- }
- float vX = 0, vY = 0, vZ = 0;
- EulerToVector(-GetRotation(), GetPitch(), vZ, vX, vY);
- vY = -vY*2 + 1.f;
- m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY() + 1.6f, GetPosZ(), vX * 2, vY * 2, vZ * 2);
- }
-
- if (m_CurrentWindow)
- {
- // FIXME: If the player entity is destroyed while having a chest window open, the chest will not close
- if (a_WindowType == 1 && strcmp(m_CurrentWindow->GetWindowTitle().c_str(), "UberChest") == 0) { // Chest
- cBlockEntity *block = m_CurrentWindow->GetOwner()->GetEntity();
- cPacket_BlockAction ChestClose;
- ChestClose.m_PosX = block->GetPosX();
- ChestClose.m_PosY = (short)block->GetPosY();
- ChestClose.m_PosZ = block->GetPosZ();
- ChestClose.m_Byte1 = 1;
- ChestClose.m_Byte2 = 0;
- m_World->Broadcast(ChestClose);
- }
-
- m_CurrentWindow->Close( *this );
- }
- m_CurrentWindow = NULL;
-}
-
-
-
-
-
-void cPlayer::SetLastBlockActionTime()
-{
- if (m_World != NULL)
- {
- m_LastBlockActionTime = m_World->GetTime();
- }
-}
-
-
-
-
-
-void cPlayer::SetLastBlockActionCnt( int a_LastBlockActionCnt )
-{
- m_LastBlockActionCnt = a_LastBlockActionCnt;
-}
-
-
-
-
-
-void cPlayer::SetGameMode( eGameMode a_GameMode )
-{
- if ( (a_GameMode < 2) && (a_GameMode >= 0) )
- {
- if (m_GameMode != a_GameMode)
- {
- cInventory *OldInventory = 0;
- if(m_GameMode == eGameMode_Survival)
- OldInventory = m_Inventory;
- else
- OldInventory = m_CreativeInventory;
-
- m_GameMode = a_GameMode;
- cPacket_NewInvalidState GameModePacket;
- GameModePacket.m_Reason = 3; //GameModeChange
- GameModePacket.m_GameMode = (char)a_GameMode; //GameModeChange
- m_ClientHandle->Send ( GameModePacket );
- GetInventory().SendWholeInventory(m_ClientHandle);
-
- OldInventory->SetEquippedSlot(GetInventory().GetEquippedSlot());
- }
- }
-}
-
-
-
-
-
-void cPlayer::LoginSetGameMode( eGameMode a_GameMode )
-{
- m_GameMode = a_GameMode;
-}
-
-
-
-
-
-void cPlayer::SetIP( std::string a_IP )
-{
- m_IP = a_IP;
-}
-
-
-
-
-
-void cPlayer::SendMessage( const char* a_Message )
-{
- m_ClientHandle->Send( cPacket_Chat( a_Message ) );
-}
-
-
-
-
-
-void cPlayer::TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ )
-{
- SetPosition( a_PosX, a_PosY, a_PosZ );
-
- cPacket_TeleportEntity TeleportEntity( this );
- cRoot::Get()->GetServer()->Broadcast( TeleportEntity, GetClientHandle() );
-
-
- cPacket_PlayerPosition PlayerPosition( this );
-
- m_ClientHandle->Send( PlayerPosition );
-}
-
-
-
-
-
-void cPlayer::MoveTo( const Vector3d & a_NewPos )
-{
- // TODO: should do some checks to see if player is not moving through terrain
- // TODO: Official server refuses position packets too far away from each other, kicking "hacked" clients; we should, too
-
- SetPosition( a_NewPos );
-}
-
-
-
-
-
-void cPlayer::SetVisible( bool a_bVisible )
-{
- if (a_bVisible && !m_bVisible) // Make visible
- {
- m_bVisible = true;
- SpawnOn( NULL ); // Spawn on everybody
- }
- if (!a_bVisible && m_bVisible)
- {
- m_bVisible = false;
- cPacket_DestroyEntity DestroyEntity( this );
- m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, DestroyEntity ); // Destroy on all clients
- }
-}
-
-
-
-
-
-void cPlayer::AddToGroup( const char* a_GroupName )
-{
- cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName );
- m_Groups.push_back( Group );
- LOG("Added %s to group %s", m_PlayerName.c_str(), a_GroupName );
- ResolveGroups();
- ResolvePermissions();
-}
-
-
-
-
-
-bool cPlayer::CanUseCommand( const char* a_Command )
-{
- for( GroupList::iterator itr = m_Groups.begin(); itr != m_Groups.end(); ++itr )
- {
- if( (*itr)->HasCommand( a_Command ) ) return true;
- }
- return false;
-}
-
-
-
-
-
-bool cPlayer::HasPermission( const char* a_Permission )
-{
- AStringVector Split = StringSplit( a_Permission, "." );
- PermissionMap Possibilities = m_ResolvedPermissions;
- // Now search the namespaces
- while( Possibilities.begin() != Possibilities.end() )
- {
- PermissionMap::iterator itr = Possibilities.begin();
- if( itr->second )
- {
- AStringVector OtherSplit = StringSplit( itr->first, "." );
- if( OtherSplit.size() <= Split.size() )
- {
- unsigned int i;
- for( i = 0; i < OtherSplit.size(); ++i )
- {
- if( OtherSplit[i].compare( Split[i] ) != 0 )
- {
- if( OtherSplit[i].compare("*") == 0 ) return true; // WildCard man!! WildCard!
- break;
- }
- }
- if( i == Split.size() ) return true;
- }
- }
- Possibilities.erase( itr );
- }
-
- // Nothing that matched :(
- return false;
-}
-
-
-
-
-
-bool cPlayer::IsInGroup( const char* a_Group )
-{
- for( GroupList::iterator itr = m_ResolvedGroups.begin(); itr != m_ResolvedGroups.end(); ++itr )
- {
- if( strcmp( a_Group, (*itr)->GetName().c_str() ) == 0 )
- return true;
- }
- return false;
-}
-
-
-
-
-
-void cPlayer::ResolvePermissions()
-{
- m_ResolvedPermissions.clear(); // Start with an empty map yo~
-
- // Copy all player specific permissions into the resolved permissions map
- for( PermissionMap::iterator itr = m_Permissions.begin(); itr != m_Permissions.end(); ++itr )
- {
- m_ResolvedPermissions[ itr->first ] = itr->second;
- }
-
- for( GroupList::iterator GroupItr = m_ResolvedGroups.begin(); GroupItr != m_ResolvedGroups.end(); ++GroupItr )
- {
- const cGroup::PermissionMap & Permissions = (*GroupItr)->GetPermissions();
- for( cGroup::PermissionMap::const_iterator itr = Permissions.begin(); itr != Permissions.end(); ++itr )
- {
- m_ResolvedPermissions[ itr->first ] = itr->second;
- }
- }
-}
-
-
-
-
-
-void cPlayer::ResolveGroups()
-{
- // Clear resolved groups first
- m_ResolvedGroups.clear();
-
- // Get a complete resolved list of all groups the player is in
- std::map< cGroup*, bool > AllGroups; // Use a map, because it's faster than iterating through a list to find duplicates
- GroupList ToIterate;
- for( GroupList::iterator GroupItr = m_Groups.begin(); GroupItr != m_Groups.end(); ++GroupItr )
- {
- ToIterate.push_back( *GroupItr );
- }
- while( ToIterate.begin() != ToIterate.end() )
- {
- cGroup* CurrentGroup = *ToIterate.begin();
- if( AllGroups.find( CurrentGroup ) != AllGroups.end() )
- {
- LOGWARNING("ERROR: Player \"%s\" is in the group multiple times (\"%s\"). Please fix your settings in users.ini!",
- m_PlayerName.c_str(), CurrentGroup->GetName().c_str()
- );
- }
- else
- {
- AllGroups[ CurrentGroup ] = true;
- m_ResolvedGroups.push_back( CurrentGroup ); // Add group to resolved list
- const cGroup::GroupList & Inherits = CurrentGroup->GetInherits();
- for( cGroup::GroupList::const_iterator itr = Inherits.begin(); itr != Inherits.end(); ++itr )
- {
- if( AllGroups.find( *itr ) != AllGroups.end() )
- {
- LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", m_PlayerName.c_str(), (*itr)->GetName().c_str() );
- continue;
- }
- ToIterate.push_back( *itr );
- }
- }
- ToIterate.erase( ToIterate.begin() );
- }
-}
-
-
-
-
-
-AString cPlayer::GetColor(void) const
-{
- if ( m_Color != '-' )
- {
- return cChatColor::MakeColor( m_Color );
- }
-
- if ( m_Groups.size() < 1 )
- {
- return cChatColor::White;
- }
-
- return (*m_Groups.begin())->GetColor();
-}
-
-
-
-
-
-void cPlayer::TossItem( bool a_bDraggingItem, int a_Amount /* = 1 */ )
-{
- cItems Drops;
- if (a_bDraggingItem)
- {
- cItem * Item = GetInventory().GetWindow()->GetDraggingItem();
- if (!Item->IsEmpty())
- {
- Drops.push_back(*Item);
- if( Item->m_ItemCount > a_Amount )
- Item->m_ItemCount -= (char)a_Amount;
- else
- Item->Empty();
- }
- }
- else
- {
- // Else drop equipped item
- cItem DroppedItem = GetInventory().GetEquippedItem();
- if (!DroppedItem.IsEmpty())
- {
- DroppedItem.m_ItemCount = 1;
- if (GetInventory().RemoveItem(DroppedItem))
- {
- DroppedItem.m_ItemCount = 1; // RemoveItem decreases the count, so set it to 1 again
- Drops.push_back(DroppedItem);
- }
- }
- }
- float vX = 0, vY = 0, vZ = 0;
- EulerToVector( -GetRotation(), GetPitch(), vZ, vX, vY );
- vY = -vY*2 + 1.f;
- m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY() + 1.6f, GetPosZ(), vX * 2, vY * 2, vZ * 2);
-}
-
-
-
-
-
-bool cPlayer::MoveToWorld( const char* a_WorldName )
-{
- cWorld * World = cRoot::Get()->GetWorld( a_WorldName );
- if ( World )
- {
- /* Remove all links to the old world */
- m_World->RemovePlayer( this );
- m_ClientHandle->RemoveFromAllChunks();
- m_World->RemoveEntityFromChunk(this, m_ChunkX, m_ChunkY, m_ChunkZ);
-
- /* Add player to all the necessary parts of the new world */
- SetWorld( World );
- GetWorld()->AddPlayer( this );
- MoveToCorrectChunk(true);
- GetClientHandle()->StreamChunks();
-
- return true;
- }
-
- return false;
-}
-
-
-
-
-
-void cPlayer::LoadPermissionsFromDisk()
-{
- m_Groups.clear();
- m_Permissions.clear();
-
- cIniFile IniFile("users.ini");
- if( IniFile.ReadFile() )
- {
- std::string Groups = IniFile.GetValue(m_PlayerName, "Groups", "");
- if( Groups.size() > 0 )
- {
- AStringVector Split = StringSplit( Groups, "," );
- for( unsigned int i = 0; i < Split.size(); i++ )
- {
- AddToGroup( Split[i].c_str() );
- }
- }
- else
- {
- AddToGroup("Default");
- }
-
- m_Color = IniFile.GetValue(m_PlayerName, "Color", "-")[0];
- }
- else
- {
- LOGWARN("WARNING: Failed to read ini file users.ini");
- AddToGroup("Default");
- }
- ResolvePermissions();
-}
-
-
-
-
-bool cPlayer::LoadFromDisk()
-{
- LoadPermissionsFromDisk();
-
- // Log player permissions, cause it's what the cool kids do
- LOGINFO("Player %s has permissions:", m_PlayerName.c_str() );
- for( PermissionMap::iterator itr = m_ResolvedPermissions.begin(); itr != m_ResolvedPermissions.end(); ++itr )
- {
- if( itr->second ) LOGINFO("%s", itr->first.c_str() );
- }
-
- AString SourceFile;
- Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() );
-
- cFile f;
- if (!f.Open(SourceFile, cFile::fmRead))
- {
- return false;
- }
-
- AString buffer;
- if (f.ReadRestOfFile(buffer) != f.GetSize())
- {
- LOGERROR("ERROR READING FROM FILE \"%s\"", SourceFile.c_str());
- return false;
- }
- f.Close();
-
- Json::Value root;
- Json::Reader reader;
- if (!reader.parse(buffer, root, false))
- {
- LOGERROR("ERROR WHILE PARSING JSON FROM FILE %s", SourceFile.c_str());
- }
-
- Json::Value & JSON_PlayerPosition = root["position"];
- if( JSON_PlayerPosition.size() == 3 )
- {
- m_Pos.x = JSON_PlayerPosition[(unsigned int)0].asDouble();
- m_Pos.y = JSON_PlayerPosition[(unsigned int)1].asDouble();
- m_Pos.z = JSON_PlayerPosition[(unsigned int)2].asDouble();
- }
-
- Json::Value & JSON_PlayerRotation = root["rotation"];
- if( JSON_PlayerRotation.size() == 3 )
- {
- m_Rot.x = (float)JSON_PlayerRotation[(unsigned int)0].asDouble();
- m_Rot.y = (float)JSON_PlayerRotation[(unsigned int)1].asDouble();
- m_Rot.z = (float)JSON_PlayerRotation[(unsigned int)2].asDouble();
- }
-
- m_Health = (short)root.get("health", 0 ).asInt();
- m_FoodLevel = (short)root.get("food", 0 ).asInt();
- m_Inventory->LoadFromJson(root["inventory"]);
- m_CreativeInventory->LoadFromJson(root["creativeinventory"]);
-
- m_LoadedWorldName = root.get("world", "world").asString();
-
- LOGD("Player \"%s\" was read from file, spawning at {%.2f, %.2f, %.2f} in world \"%s\"",
- m_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z, m_LoadedWorldName.c_str()
- );
-
- return true;
-}
-
-
-
-
-
-bool cPlayer::SaveToDisk()
-{
- cMakeDir::MakeDir("players");
-
- // create the JSON data
- Json::Value JSON_PlayerPosition;
- JSON_PlayerPosition.append( Json::Value( m_Pos.x ) );
- JSON_PlayerPosition.append( Json::Value( m_Pos.y ) );
- JSON_PlayerPosition.append( Json::Value( m_Pos.z ) );
-
- Json::Value JSON_PlayerRotation;
- JSON_PlayerRotation.append( Json::Value( m_Rot.x ) );
- JSON_PlayerRotation.append( Json::Value( m_Rot.y ) );
- JSON_PlayerRotation.append( Json::Value( m_Rot.z ) );
-
- Json::Value JSON_Inventory;
- m_Inventory->SaveToJson( JSON_Inventory );
-
- Json::Value JSON_CreativeInventory;
- m_CreativeInventory->SaveToJson( JSON_CreativeInventory );
-
- Json::Value root;
- root["position"] = JSON_PlayerPosition;
- root["rotation"] = JSON_PlayerRotation;
- root["inventory"] = JSON_Inventory;
- root["creativeinventory"] = JSON_CreativeInventory;
- root["health"] = m_Health;
- root["food"] = m_FoodLevel;
- root["world"] = GetWorld()->GetName();
-
- Json::StyledWriter writer;
- std::string JsonData = writer.write( root );
-
- AString SourceFile;
- Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() );
-
- cFile f;
- if (!f.Open(SourceFile, cFile::fmWrite))
- {
- LOGERROR("ERROR WRITING PLAYER \"%s\" TO FILE \"%s\" - cannot open file", m_PlayerName.c_str(), SourceFile.c_str());
- return false;
- }
- if (f.Write(JsonData.c_str(), JsonData.size()) != (int)JsonData.size())
- {
- LOGERROR("ERROR WRITING PLAYER JSON TO FILE \"%s\"", SourceFile.c_str());
- return false;
- }
- return true;
-}
-
-
-
-
-
-cPlayer::StringList cPlayer::GetResolvedPermissions()
-{
- StringList Permissions;
-
- const PermissionMap& ResolvedPermissions = m_ResolvedPermissions;
- for( PermissionMap::const_iterator itr = ResolvedPermissions.begin(); itr != ResolvedPermissions.end(); ++itr )
- {
- if( itr->second ) Permissions.push_back( itr->first );
- }
-
- return Permissions;
-}
-
-
-
-
-
-void cPlayer::UseEquippedItem()
-{
- if(GetGameMode() != 1) //No damage in creative
- {
- if (GetInventory().GetEquippedItem().DamageItem())
- {
- LOG("Player %s Broke ID: %i", GetClientHandle()->GetUsername().c_str(), GetInventory().GetEquippedItem().m_ItemID);
- GetInventory().RemoveItem( GetInventory().GetEquippedItem());
- }
- }
-}
-
-
-
-
-
-bool cPlayer::EatItem(int a_ItemType)
-{
- // TODO: Handle hunger
- switch (a_ItemType)
- {
- case E_ITEM_APPLE: return Feed(24); // 2 food bars
- case E_ITEM_GOLDEN_APPLE: return Feed(60); // 5 food
- case E_ITEM_MUSHROOM_SOUP: return Feed(48); // 4 food
- case E_ITEM_BREAD: return Feed(30); // 2.5 food
- case E_ITEM_RAW_MEAT: return Feed(18); // 1.5 food
- case E_ITEM_COOKED_MEAT: return Feed(48); // 4 food
- case E_ITEM_RAW_FISH: return Feed(12); // 1 food
- case E_ITEM_COOKED_FISH: return Feed(30); // 2.5 food
- case E_ITEM_COOKED_CHICKEN: return Feed(36); // 3 food
- case E_ITEM_RAW_BEEF: return Feed(18); // 1.5 food
- case E_ITEM_STEAK: return Feed(48); // 4 food
- case E_ITEM_RAW_CHICKEN:
- {
- if (!Feed(12)) // 1 food
- {
- return false;
- }
- // TODO: A random chance to get food-poisoned
- return true;
- }
-
- case E_ITEM_ROTTEN_FLESH:
- {
- if (!Feed(24))
- {
- return false;
- }
- // TODO: Food-poisoning
- return true;
- }
- }
- return false;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPlayer.h" +#include "cServer.h" +#include "cCreativeInventory.h" +#include "cSurvivalInventory.h" +#include "cClientHandle.h" +#include "cWorld.h" +#include "cPickup.h" +#include "cPluginManager.h" +#include "cWindow.h" +#include "cBlockEntity.h" +#include "cGroupManager.h" +#include "cGroup.h" +#include "cChatColor.h" +#include "cItem.h" +#include "cTracer.h" +#include "cRoot.h" +#include "cMakeDir.h" +#include "cTimer.h" +#include "MersenneTwister.h" + +#include "packets/cPacket_NamedEntitySpawn.h" +#include "packets/cPacket_EntityLook.h" +#include "packets/cPacket_TeleportEntity.h" +#include "packets/cPacket_RelativeEntityMove.h" +#include "packets/cPacket_RelativeEntityMoveLook.h" +#include "packets/cPacket_UpdateHealth.h" +#include "packets/cPacket_Respawn.h" +#include "packets/cPacket_DestroyEntity.h" +#include "packets/cPacket_Metadata.h" +#include "packets/cPacket_Chat.h" +#include "packets/cPacket_NewInvalidState.h" +#include "packets/cPacket_BlockAction.h" + +#include "Vector3d.h" +#include "Vector3f.h" + +#include "../iniFile/iniFile.h" +#include <json/json.h> + +#define float2int(x) ((x)<0 ? ((int)(x))-1 : (int)(x)) + + + + + +CLASS_DEFINITION( cPlayer, cPawn ); + + + + + +cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) + : m_GameMode( eGameMode_Survival ) + , m_IP("") + , m_LastBlockActionTime( 0 ) + , m_LastBlockActionCnt( 0 ) + , m_bVisible( true ) + , m_LastGroundHeight( 0 ) + , m_bTouchGround( false ) + , m_Stance( 0.0 ) + , m_Inventory( 0 ) + , m_CurrentWindow( 0 ) + , m_TimeLastPickupCheck( 0.f ) + , m_Color('-') + , m_ClientHandle( a_Client ) +{ + LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d", + a_PlayerName.c_str(), a_Client->GetSocket().GetIPString().c_str(), + this, GetUniqueID() + ); + m_EntityType = eEntityType_Player; + SetMaxHealth(20); + SetMaxFoodLevel(125); + m_Inventory = new cSurvivalInventory( this ); + m_CreativeInventory = new cCreativeInventory(this); + cTimer t1; + m_LastPlayerListTime = t1.GetNowTime(); + + m_TimeLastTeleportPacket = cWorld::GetTime(); + m_TimeLastPickupCheck = cWorld::GetTime(); + + m_PlayerName = a_PlayerName; + m_bDirtyPosition = true; // So chunks are streamed to player at spawn + + if( !LoadFromDisk() ) + { + m_Inventory->Clear(); + m_CreativeInventory->Clear(); + m_Pos.x = cRoot::Get()->GetDefaultWorld()->GetSpawnX(); + m_Pos.y = cRoot::Get()->GetDefaultWorld()->GetSpawnY(); + m_Pos.z = cRoot::Get()->GetDefaultWorld()->GetSpawnZ(); + + LOGD("Player \"%s\" is connecting for the first time, spawning at default world spawn {%.2f, %.2f, %.2f}", + a_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z + ); + } +} + + + + + +void cPlayer::Initialize( cWorld* a_World ) +{ + cPawn::Initialize( a_World ); + GetWorld()->AddPlayer( this ); +} + + + + + +cPlayer::~cPlayer(void) +{ + LOG("Deleting cPlayer \"%s\" at %p, ID %d", m_PlayerName.c_str(), this, GetUniqueID()); + + SaveToDisk(); + + m_World->RemovePlayer( this ); + + m_ClientHandle = NULL; + + delete m_Inventory; + m_Inventory = NULL; + + delete m_CreativeInventory; + + LOG("Player %p deleted", this); +} + + + + + +void cPlayer::Destroyed() +{ + CloseWindow(-1); + m_ClientHandle = NULL; +} + + + + + +cPacket * cPlayer::GetSpawnPacket(void) const +{ + LOGD("cPlayer::GetSpawnPacket for \"%s\" at pos {%.2f, %.2f, %.2f}", + m_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z + ); + + if (!m_bVisible ) + { + return NULL; + } + + cPacket_NamedEntitySpawn * SpawnPacket = new cPacket_NamedEntitySpawn; + SpawnPacket->m_UniqueID = m_UniqueID; + SpawnPacket->m_PlayerName = m_PlayerName; + SpawnPacket->m_PosX = (int)(m_Pos.x * 32); + SpawnPacket->m_PosY = (int)(m_Pos.y * 32); + SpawnPacket->m_PosZ = (int)(m_Pos.z * 32); + SpawnPacket->m_Rotation = (char)((m_Rot.x / 360.f) * 256); + SpawnPacket->m_Pitch = (char)((m_Rot.y / 360.f) * 256); + short ItemID = (short)m_Inventory->GetEquippedItem().m_ItemID; + SpawnPacket->m_CurrentItem = (ItemID > 0) ? ItemID : 0; // Unlike -1 in inventory, the named entity packet uses 0 for "none" + return SpawnPacket; +} + + + + + +void cPlayer::Tick(float a_Dt) +{ + if (!m_ClientHandle->IsPlaying()) + { + // We're not yet in the game, ignore everything + return; + } + + cPawn::Tick(a_Dt); + + if (m_bDirtyOrientation && !m_bDirtyPosition) + { + cPacket_EntityLook EntityLook(*this); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityLook, m_ClientHandle ); + cPacket_EntityHeadLook EntityHeadLook(*this); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityHeadLook, m_ClientHandle); + m_bDirtyOrientation = false; + } + else if (m_bDirtyPosition ) + { + cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_MOVE, 1, this ); + + float DiffX = (float)(GetPosX() - m_LastPosX ); + float DiffY = (float)(GetPosY() - m_LastPosY ); + float DiffZ = (float)(GetPosZ() - m_LastPosZ ); + float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ; + if ( + (SqrDist > 4 * 4) || // 4 blocks is max Relative Move + (cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds + ) + { + //LOG("Teleported %f", sqrtf(SqrDist) ); + cPacket_TeleportEntity TeleportEntity( this ); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity, m_ClientHandle); + m_TimeLastTeleportPacket = cWorld::GetTime(); + } + else + { // Relative move sucks balls! It's always wrong wtf! + if( m_bDirtyOrientation ) + { + cPacket_RelativeEntityMoveLook RelativeEntityMoveLook; + RelativeEntityMoveLook.m_UniqueID = GetUniqueID(); + RelativeEntityMoveLook.m_MoveX = (char)(DiffX*32); + RelativeEntityMoveLook.m_MoveY = (char)(DiffY*32); + RelativeEntityMoveLook.m_MoveZ = (char)(DiffZ*32); + RelativeEntityMoveLook.m_Yaw = (char)((GetRotation()/360.f)*256); + RelativeEntityMoveLook.m_Pitch = (char)((GetPitch()/360.f)*256); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMoveLook, m_ClientHandle ); + } + else + { + cPacket_RelativeEntityMove RelativeEntityMove; + RelativeEntityMove.m_UniqueID = GetUniqueID(); + RelativeEntityMove.m_MoveX = (char)(DiffX*32); + RelativeEntityMove.m_MoveY = (char)(DiffY*32); + RelativeEntityMove.m_MoveZ = (char)(DiffZ*32); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMove, m_ClientHandle ); + } + } + m_LastPosX = GetPosX(); + m_LastPosY = GetPosY(); + m_LastPosZ = GetPosZ(); + m_bDirtyPosition = false; + m_ClientHandle->StreamChunks(); + } + + if (m_Health > 0) // make sure player is alive + { + m_World->CollectPickupsByPlayer(this); + } + + cTimer t1; + // Send Player List (Once per m_LastPlayerListTime/1000 ms) + if (m_LastPlayerListTime + cPlayer::PLAYER_LIST_TIME_MS <= t1.GetNowTime()) + { + m_World->SendPlayerList(this); + m_LastPlayerListTime = t1.GetNowTime(); + } +} + + + + + +void cPlayer::SetTouchGround( bool a_bTouchGround ) +{ + m_bTouchGround = a_bTouchGround; + + if( !m_bTouchGround ) + { + cWorld* World = GetWorld(); + char BlockID = World->GetBlock( float2int(m_Pos.x), float2int(m_Pos.y), float2int(m_Pos.z) ); + if( BlockID != E_BLOCK_AIR ) + { + m_bTouchGround = true; + } + if( BlockID == E_BLOCK_WATER || BlockID == E_BLOCK_STATIONARY_WATER || BlockID == E_BLOCK_LADDER || BlockID == E_BLOCK_TORCH ) + { + m_LastGroundHeight = (float)m_Pos.y; + } + } + + if( m_bTouchGround ) + { + float Dist = (float)(m_LastGroundHeight - m_Pos.y); + if( Dist > 4.f ) // Player dropped + { + int Damage = (int)(Dist - 4.f); + if( Damage > 0 ) + { + TakeDamage( Damage, 0 ); + } + } + + m_LastGroundHeight = (float)m_Pos.y; + } +} + +void cPlayer::Heal( int a_Health ) +{ + if( m_Health < GetMaxHealth() ) + { + m_Health = (short) MIN(a_Health + m_Health, GetMaxHealth()); + + cPacket_UpdateHealth Health; + Health.m_Health = m_Health; + Health.m_Food = GetFood(); + Health.m_Saturation = GetFoodSaturation(); + m_ClientHandle->Send( Health ); + } +} + + + + + +bool cPlayer::Feed(short a_Food) +{ + if (m_FoodLevel >= GetMaxFoodLevel()) + { + return false; + } + + m_FoodLevel = MIN(a_Food + m_FoodLevel, GetMaxFoodLevel()); + + cPacket_UpdateHealth Health; + Health.m_Health = m_Health; + Health.m_Food = GetFood(); + Health.m_Saturation = GetFoodSaturation(); + m_ClientHandle->Send( Health ); + return true; +} + + + + + +void cPlayer::TakeDamage( int a_Damage, cEntity* a_Instigator ) +{ + if ( !(m_GameMode == 1) ) { + cPawn::TakeDamage( a_Damage, a_Instigator ); + + cPacket_UpdateHealth Health; + Health.m_Health = m_Health; + Health.m_Food = GetFood(); + Health.m_Saturation = GetFoodSaturation(); + //TODO: Causes problems sometimes O.o (E.G. Disconnecting when attacked) + if(m_ClientHandle != 0) + m_ClientHandle->Send( Health ); + } +} + + + + + +void cPlayer::KilledBy(cEntity * a_Killer) +{ + cPawn::KilledBy(a_Killer); + + if (m_Health > 0) + { + return; // not dead yet =] + } + + m_bVisible = false; // So new clients don't see the player + + // Puke out all the items + cItem* Items = m_Inventory->GetSlots(); + cItems Pickups; + for (unsigned int i = 1; i < m_Inventory->c_NumSlots; ++i) + { + if( !Items[i].IsEmpty() ) + { + Pickups.push_back(Items[i]); + } + Items[i].Empty(); + } + m_World->SpawnItemPickups(Pickups, m_Pos.x, m_Pos.y, m_Pos.z, 10); + SaveToDisk(); // Save it, yeah the world is a tough place ! +} + + + + + +void cPlayer::Respawn() +{ + m_Health = GetMaxHealth(); + + // Create Respawn player packet + cPacket_Respawn Packet; + //Set Gamemode for packet by looking at world's gamemode (Need to check players gamemode.) + //Packet.m_CreativeMode = (char)GetWorld()->GetGameMode(); + Packet.m_CreativeMode = (char)m_GameMode; //Set GameMode packet based on Player's GameMode; + + //Send Packet + m_ClientHandle->Send( Packet ); + + //Set non Burning + SetMetaData(NORMAL); + + TeleportTo( GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ() ); + + SetVisible( true ); +} + +double cPlayer::GetEyeHeight() +{ + return m_Stance; +} + +Vector3d cPlayer::GetEyePosition() +{ + return Vector3d( m_Pos.x, m_Stance, m_Pos.z ); +} + +void cPlayer::OpenWindow( cWindow* a_Window ) +{ + CloseWindow(m_CurrentWindow ? (char)m_CurrentWindow->GetWindowType() : 0); + a_Window->Open( *this ); + m_CurrentWindow = a_Window; +} + + + + + +void cPlayer::CloseWindow(char a_WindowType) +{ + if (a_WindowType == 0) + { + // Inventory + if ( + (m_Inventory->GetWindow()->GetDraggingItem() != NULL) && + (m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount > 0) + ) + { + LOG("Player holds item! Dropping it..."); + TossItem( true, m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount ); + } + + //Drop whats in the crafting slots (1, 2, 3, 4) + cItems Drops; + for (int i = 1; i <= 4; i++) + { + cItem* Item = m_Inventory->GetSlot( i ); + if (!Item->IsEmpty()) + { + Drops.push_back(*Item); + } + Item->Empty(); + } + float vX = 0, vY = 0, vZ = 0; + EulerToVector(-GetRotation(), GetPitch(), vZ, vX, vY); + vY = -vY*2 + 1.f; + m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY() + 1.6f, GetPosZ(), vX * 2, vY * 2, vZ * 2); + } + + if (m_CurrentWindow) + { + // FIXME: If the player entity is destroyed while having a chest window open, the chest will not close + if (a_WindowType == 1 && strcmp(m_CurrentWindow->GetWindowTitle().c_str(), "UberChest") == 0) { // Chest + cBlockEntity *block = m_CurrentWindow->GetOwner()->GetEntity(); + cPacket_BlockAction ChestClose; + ChestClose.m_PosX = block->GetPosX(); + ChestClose.m_PosY = (short)block->GetPosY(); + ChestClose.m_PosZ = block->GetPosZ(); + ChestClose.m_Byte1 = 1; + ChestClose.m_Byte2 = 0; + m_World->Broadcast(ChestClose); + } + + m_CurrentWindow->Close( *this ); + } + m_CurrentWindow = NULL; +} + + + + + +void cPlayer::SetLastBlockActionTime() +{ + if (m_World != NULL) + { + m_LastBlockActionTime = m_World->GetTime(); + } +} + + + + + +void cPlayer::SetLastBlockActionCnt( int a_LastBlockActionCnt ) +{ + m_LastBlockActionCnt = a_LastBlockActionCnt; +} + + + + + +void cPlayer::SetGameMode( eGameMode a_GameMode ) +{ + if ( (a_GameMode < 2) && (a_GameMode >= 0) ) + { + if (m_GameMode != a_GameMode) + { + cInventory *OldInventory = 0; + if(m_GameMode == eGameMode_Survival) + OldInventory = m_Inventory; + else + OldInventory = m_CreativeInventory; + + m_GameMode = a_GameMode; + cPacket_NewInvalidState GameModePacket; + GameModePacket.m_Reason = 3; //GameModeChange + GameModePacket.m_GameMode = (char)a_GameMode; //GameModeChange + m_ClientHandle->Send ( GameModePacket ); + GetInventory().SendWholeInventory(m_ClientHandle); + + OldInventory->SetEquippedSlot(GetInventory().GetEquippedSlot()); + } + } +} + + + + + +void cPlayer::LoginSetGameMode( eGameMode a_GameMode ) +{ + m_GameMode = a_GameMode; +} + + + + + +void cPlayer::SetIP( std::string a_IP ) +{ + m_IP = a_IP; +} + + + + + +void cPlayer::SendMessage( const char* a_Message ) +{ + m_ClientHandle->Send( cPacket_Chat( a_Message ) ); +} + + + + + +void cPlayer::TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ) +{ + SetPosition( a_PosX, a_PosY, a_PosZ ); + + cPacket_TeleportEntity TeleportEntity( this ); + cRoot::Get()->GetServer()->Broadcast( TeleportEntity, GetClientHandle() ); + + + cPacket_PlayerPosition PlayerPosition( this ); + + m_ClientHandle->Send( PlayerPosition ); +} + + + + + +void cPlayer::MoveTo( const Vector3d & a_NewPos ) +{ + // TODO: should do some checks to see if player is not moving through terrain + // TODO: Official server refuses position packets too far away from each other, kicking "hacked" clients; we should, too + + SetPosition( a_NewPos ); +} + + + + + +void cPlayer::SetVisible( bool a_bVisible ) +{ + if (a_bVisible && !m_bVisible) // Make visible + { + m_bVisible = true; + SpawnOn( NULL ); // Spawn on everybody + } + if (!a_bVisible && m_bVisible) + { + m_bVisible = false; + cPacket_DestroyEntity DestroyEntity( this ); + m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, DestroyEntity ); // Destroy on all clients + } +} + + + + + +void cPlayer::AddToGroup( const char* a_GroupName ) +{ + cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName ); + m_Groups.push_back( Group ); + LOG("Added %s to group %s", m_PlayerName.c_str(), a_GroupName ); + ResolveGroups(); + ResolvePermissions(); +} + + + + + +bool cPlayer::CanUseCommand( const char* a_Command ) +{ + for( GroupList::iterator itr = m_Groups.begin(); itr != m_Groups.end(); ++itr ) + { + if( (*itr)->HasCommand( a_Command ) ) return true; + } + return false; +} + + + + + +bool cPlayer::HasPermission( const char* a_Permission ) +{ + AStringVector Split = StringSplit( a_Permission, "." ); + PermissionMap Possibilities = m_ResolvedPermissions; + // Now search the namespaces + while( Possibilities.begin() != Possibilities.end() ) + { + PermissionMap::iterator itr = Possibilities.begin(); + if( itr->second ) + { + AStringVector OtherSplit = StringSplit( itr->first, "." ); + if( OtherSplit.size() <= Split.size() ) + { + unsigned int i; + for( i = 0; i < OtherSplit.size(); ++i ) + { + if( OtherSplit[i].compare( Split[i] ) != 0 ) + { + if( OtherSplit[i].compare("*") == 0 ) return true; // WildCard man!! WildCard! + break; + } + } + if( i == Split.size() ) return true; + } + } + Possibilities.erase( itr ); + } + + // Nothing that matched :( + return false; +} + + + + + +bool cPlayer::IsInGroup( const char* a_Group ) +{ + for( GroupList::iterator itr = m_ResolvedGroups.begin(); itr != m_ResolvedGroups.end(); ++itr ) + { + if( strcmp( a_Group, (*itr)->GetName().c_str() ) == 0 ) + return true; + } + return false; +} + + + + + +void cPlayer::ResolvePermissions() +{ + m_ResolvedPermissions.clear(); // Start with an empty map yo~ + + // Copy all player specific permissions into the resolved permissions map + for( PermissionMap::iterator itr = m_Permissions.begin(); itr != m_Permissions.end(); ++itr ) + { + m_ResolvedPermissions[ itr->first ] = itr->second; + } + + for( GroupList::iterator GroupItr = m_ResolvedGroups.begin(); GroupItr != m_ResolvedGroups.end(); ++GroupItr ) + { + const cGroup::PermissionMap & Permissions = (*GroupItr)->GetPermissions(); + for( cGroup::PermissionMap::const_iterator itr = Permissions.begin(); itr != Permissions.end(); ++itr ) + { + m_ResolvedPermissions[ itr->first ] = itr->second; + } + } +} + + + + + +void cPlayer::ResolveGroups() +{ + // Clear resolved groups first + m_ResolvedGroups.clear(); + + // Get a complete resolved list of all groups the player is in + std::map< cGroup*, bool > AllGroups; // Use a map, because it's faster than iterating through a list to find duplicates + GroupList ToIterate; + for( GroupList::iterator GroupItr = m_Groups.begin(); GroupItr != m_Groups.end(); ++GroupItr ) + { + ToIterate.push_back( *GroupItr ); + } + while( ToIterate.begin() != ToIterate.end() ) + { + cGroup* CurrentGroup = *ToIterate.begin(); + if( AllGroups.find( CurrentGroup ) != AllGroups.end() ) + { + LOGWARNING("ERROR: Player \"%s\" is in the group multiple times (\"%s\"). Please fix your settings in users.ini!", + m_PlayerName.c_str(), CurrentGroup->GetName().c_str() + ); + } + else + { + AllGroups[ CurrentGroup ] = true; + m_ResolvedGroups.push_back( CurrentGroup ); // Add group to resolved list + const cGroup::GroupList & Inherits = CurrentGroup->GetInherits(); + for( cGroup::GroupList::const_iterator itr = Inherits.begin(); itr != Inherits.end(); ++itr ) + { + if( AllGroups.find( *itr ) != AllGroups.end() ) + { + LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", m_PlayerName.c_str(), (*itr)->GetName().c_str() ); + continue; + } + ToIterate.push_back( *itr ); + } + } + ToIterate.erase( ToIterate.begin() ); + } +} + + + + + +AString cPlayer::GetColor(void) const +{ + if ( m_Color != '-' ) + { + return cChatColor::MakeColor( m_Color ); + } + + if ( m_Groups.size() < 1 ) + { + return cChatColor::White; + } + + return (*m_Groups.begin())->GetColor(); +} + + + + + +void cPlayer::TossItem( bool a_bDraggingItem, int a_Amount /* = 1 */ ) +{ + cItems Drops; + if (a_bDraggingItem) + { + cItem * Item = GetInventory().GetWindow()->GetDraggingItem(); + if (!Item->IsEmpty()) + { + Drops.push_back(*Item); + if( Item->m_ItemCount > a_Amount ) + Item->m_ItemCount -= (char)a_Amount; + else + Item->Empty(); + } + } + else + { + // Else drop equipped item + cItem DroppedItem = GetInventory().GetEquippedItem(); + if (!DroppedItem.IsEmpty()) + { + DroppedItem.m_ItemCount = 1; + if (GetInventory().RemoveItem(DroppedItem)) + { + DroppedItem.m_ItemCount = 1; // RemoveItem decreases the count, so set it to 1 again + Drops.push_back(DroppedItem); + } + } + } + float vX = 0, vY = 0, vZ = 0; + EulerToVector( -GetRotation(), GetPitch(), vZ, vX, vY ); + vY = -vY*2 + 1.f; + m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY() + 1.6f, GetPosZ(), vX * 2, vY * 2, vZ * 2); +} + + + + + +bool cPlayer::MoveToWorld( const char* a_WorldName ) +{ + cWorld * World = cRoot::Get()->GetWorld( a_WorldName ); + if ( World ) + { + /* Remove all links to the old world */ + m_World->RemovePlayer( this ); + m_ClientHandle->RemoveFromAllChunks(); + m_World->RemoveEntityFromChunk(this, m_ChunkX, m_ChunkY, m_ChunkZ); + + /* Add player to all the necessary parts of the new world */ + SetWorld( World ); + GetWorld()->AddPlayer( this ); + MoveToCorrectChunk(true); + GetClientHandle()->StreamChunks(); + + return true; + } + + return false; +} + + + + + +void cPlayer::LoadPermissionsFromDisk() +{ + m_Groups.clear(); + m_Permissions.clear(); + + cIniFile IniFile("users.ini"); + if( IniFile.ReadFile() ) + { + std::string Groups = IniFile.GetValue(m_PlayerName, "Groups", ""); + if( Groups.size() > 0 ) + { + AStringVector Split = StringSplit( Groups, "," ); + for( unsigned int i = 0; i < Split.size(); i++ ) + { + AddToGroup( Split[i].c_str() ); + } + } + else + { + AddToGroup("Default"); + } + + m_Color = IniFile.GetValue(m_PlayerName, "Color", "-")[0]; + } + else + { + LOGWARN("WARNING: Failed to read ini file users.ini"); + AddToGroup("Default"); + } + ResolvePermissions(); +} + + + + +bool cPlayer::LoadFromDisk() +{ + LoadPermissionsFromDisk(); + + // Log player permissions, cause it's what the cool kids do + LOGINFO("Player %s has permissions:", m_PlayerName.c_str() ); + for( PermissionMap::iterator itr = m_ResolvedPermissions.begin(); itr != m_ResolvedPermissions.end(); ++itr ) + { + if( itr->second ) LOGINFO("%s", itr->first.c_str() ); + } + + AString SourceFile; + Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() ); + + cFile f; + if (!f.Open(SourceFile, cFile::fmRead)) + { + return false; + } + + AString buffer; + if (f.ReadRestOfFile(buffer) != f.GetSize()) + { + LOGERROR("ERROR READING FROM FILE \"%s\"", SourceFile.c_str()); + return false; + } + f.Close(); + + Json::Value root; + Json::Reader reader; + if (!reader.parse(buffer, root, false)) + { + LOGERROR("ERROR WHILE PARSING JSON FROM FILE %s", SourceFile.c_str()); + } + + Json::Value & JSON_PlayerPosition = root["position"]; + if( JSON_PlayerPosition.size() == 3 ) + { + m_Pos.x = JSON_PlayerPosition[(unsigned int)0].asDouble(); + m_Pos.y = JSON_PlayerPosition[(unsigned int)1].asDouble(); + m_Pos.z = JSON_PlayerPosition[(unsigned int)2].asDouble(); + } + + Json::Value & JSON_PlayerRotation = root["rotation"]; + if( JSON_PlayerRotation.size() == 3 ) + { + m_Rot.x = (float)JSON_PlayerRotation[(unsigned int)0].asDouble(); + m_Rot.y = (float)JSON_PlayerRotation[(unsigned int)1].asDouble(); + m_Rot.z = (float)JSON_PlayerRotation[(unsigned int)2].asDouble(); + } + + m_Health = (short)root.get("health", 0 ).asInt(); + m_FoodLevel = (short)root.get("food", 0 ).asInt(); + m_Inventory->LoadFromJson(root["inventory"]); + m_CreativeInventory->LoadFromJson(root["creativeinventory"]); + + m_LoadedWorldName = root.get("world", "world").asString(); + + LOGD("Player \"%s\" was read from file, spawning at {%.2f, %.2f, %.2f} in world \"%s\"", + m_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z, m_LoadedWorldName.c_str() + ); + + return true; +} + + + + + +bool cPlayer::SaveToDisk() +{ + cMakeDir::MakeDir("players"); + + // create the JSON data + Json::Value JSON_PlayerPosition; + JSON_PlayerPosition.append( Json::Value( m_Pos.x ) ); + JSON_PlayerPosition.append( Json::Value( m_Pos.y ) ); + JSON_PlayerPosition.append( Json::Value( m_Pos.z ) ); + + Json::Value JSON_PlayerRotation; + JSON_PlayerRotation.append( Json::Value( m_Rot.x ) ); + JSON_PlayerRotation.append( Json::Value( m_Rot.y ) ); + JSON_PlayerRotation.append( Json::Value( m_Rot.z ) ); + + Json::Value JSON_Inventory; + m_Inventory->SaveToJson( JSON_Inventory ); + + Json::Value JSON_CreativeInventory; + m_CreativeInventory->SaveToJson( JSON_CreativeInventory ); + + Json::Value root; + root["position"] = JSON_PlayerPosition; + root["rotation"] = JSON_PlayerRotation; + root["inventory"] = JSON_Inventory; + root["creativeinventory"] = JSON_CreativeInventory; + root["health"] = m_Health; + root["food"] = m_FoodLevel; + root["world"] = GetWorld()->GetName(); + + Json::StyledWriter writer; + std::string JsonData = writer.write( root ); + + AString SourceFile; + Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() ); + + cFile f; + if (!f.Open(SourceFile, cFile::fmWrite)) + { + LOGERROR("ERROR WRITING PLAYER \"%s\" TO FILE \"%s\" - cannot open file", m_PlayerName.c_str(), SourceFile.c_str()); + return false; + } + if (f.Write(JsonData.c_str(), JsonData.size()) != (int)JsonData.size()) + { + LOGERROR("ERROR WRITING PLAYER JSON TO FILE \"%s\"", SourceFile.c_str()); + return false; + } + return true; +} + + + + + +cPlayer::StringList cPlayer::GetResolvedPermissions() +{ + StringList Permissions; + + const PermissionMap& ResolvedPermissions = m_ResolvedPermissions; + for( PermissionMap::const_iterator itr = ResolvedPermissions.begin(); itr != ResolvedPermissions.end(); ++itr ) + { + if( itr->second ) Permissions.push_back( itr->first ); + } + + return Permissions; +} + + + + + +void cPlayer::UseEquippedItem() +{ + if(GetGameMode() != 1) //No damage in creative + { + if (GetInventory().GetEquippedItem().DamageItem()) + { + LOG("Player %s Broke ID: %i", GetClientHandle()->GetUsername().c_str(), GetInventory().GetEquippedItem().m_ItemID); + GetInventory().RemoveItem( GetInventory().GetEquippedItem()); + } + } +} + + + + + +bool cPlayer::EatItem(int a_ItemType) +{ + // TODO: Handle hunger + switch (a_ItemType) + { + case E_ITEM_APPLE: return Feed(24); // 2 food bars + case E_ITEM_GOLDEN_APPLE: return Feed(60); // 5 food + case E_ITEM_MUSHROOM_SOUP: return Feed(48); // 4 food + case E_ITEM_BREAD: return Feed(30); // 2.5 food + case E_ITEM_RAW_MEAT: return Feed(18); // 1.5 food + case E_ITEM_COOKED_MEAT: return Feed(48); // 4 food + case E_ITEM_RAW_FISH: return Feed(12); // 1 food + case E_ITEM_COOKED_FISH: return Feed(30); // 2.5 food + case E_ITEM_COOKED_CHICKEN: return Feed(36); // 3 food + case E_ITEM_RAW_BEEF: return Feed(18); // 1.5 food + case E_ITEM_STEAK: return Feed(48); // 4 food + case E_ITEM_RAW_CHICKEN: + { + if (!Feed(12)) // 1 food + { + return false; + } + // TODO: A random chance to get food-poisoned + return true; + } + + case E_ITEM_ROTTEN_FLESH: + { + if (!Feed(24)) + { + return false; + } + // TODO: Food-poisoning + return true; + } + } + return false; +} + + + + diff --git a/source/cPlayer.h b/source/cPlayer.h index 815c31316..ef85a1d4e 100644 --- a/source/cPlayer.h +++ b/source/cPlayer.h @@ -1,146 +1,146 @@ -
-#pragma once
-
-#include "cPawn.h"
-#include "cSurvivalInventory.h"
-#include "cCreativeInventory.h"
-#include "Defines.h"
-
-
-
-
-
-class cGroup;
-class cWindow;
-class cInventory;
-class cClientHandle;
-
-
-
-
-
-class cPlayer : public cPawn //tolua_export
-{ //tolua_export
-public:
- typedef cPawn super;
- CLASS_PROTOTYPE();
-
- cPlayer(cClientHandle * a_Client, const AString & a_PlayerName);
- virtual ~cPlayer();
-
- virtual void Initialize( cWorld* a_World ); //tolua_export
-
- virtual cPacket * GetSpawnPacket(void) const override;
- virtual void Tick(float a_Dt) override;
-
- void SetTouchGround( bool a_bTouchGround );
- inline void SetStance( const double & a_Stance ) { m_Stance = a_Stance; }
- double GetEyeHeight(); //tolua_export
- Vector3d GetEyePosition(); //tolua_export
- inline bool GetFlying() { return m_bTouchGround; } //tolua_export
- inline const double & GetStance() { return m_Stance; } //tolua_export
- inline cInventory & GetInventory() { if(GetGameMode() == eGameMode_Survival) return *m_Inventory; else return *m_CreativeInventory; } //tolua_export
-
- virtual void TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ); //tolua_export
-
- eGameMode GetGameMode() { return m_GameMode; } //tolua_export
- std::string GetIP() { return m_IP; } //tolua_export
- float GetLastBlockActionTime() { return m_LastBlockActionTime; } //tolua_export
- int GetLastBlockActionCnt() { return m_LastBlockActionCnt; } //tolua_export
- void SetLastBlockActionCnt( int ); //tolua_export
- void SetLastBlockActionTime(); //tolua_export
- void SetGameMode( eGameMode a_GameMode ); //tolua_export
- void LoginSetGameMode( eGameMode a_GameMode );
- void SetIP( std::string a_IP );
-
- // Tries to move to a new position, with collision checks and stuff
- virtual void MoveTo( const Vector3d & a_NewPos ); //tolua_export
-
- cWindow* GetWindow() { return m_CurrentWindow; }
- void OpenWindow( cWindow* a_Window );
- void CloseWindow(char a_WindowType);
-
- cClientHandle * GetClientHandle() { return m_ClientHandle; } //tolua_export
-
- void SendMessage( const char* a_Message ); //tolua_export
-
- const AString & GetName(void) const { return m_PlayerName; } //tolua_export
- void SetName(const AString & a_Name) { m_PlayerName = a_Name; } //tolua_export
-
- typedef std::list< cGroup* > GroupList;
- typedef std::list< std::string > StringList;
- void AddToGroup( const char* a_GroupName ); //tolua_export
- bool CanUseCommand( const char* a_Command ); //tolua_export
- bool HasPermission( const char* a_Permission ); //tolua_export
- const GroupList & GetGroups() { return m_Groups; } // >> EXPORTED IN MANUALBINDINGS <<
- StringList GetResolvedPermissions(); // >> EXPORTED IN MANUALBINDINGS <<
- bool IsInGroup( const char* a_Group ); //tolua_export
-
- AString GetColor(void) const; //tolua_export
-
- void TossItem( bool a_bDraggingItem, int a_Amount = 1 ); //tolua_export
-
- void Heal( int a_Health ); //tolua_export
-
- /// Returns true if any food has been consumed, false if player "full"
- bool Feed(short a_Food);
-
- void TakeDamage( int a_Damage, cEntity* a_Instigator ); //tolua_export
- void KilledBy( cEntity* a_Killer ); //tolua_export
- void Respawn(); //tolua_export
-
- void SetVisible( bool a_bVisible ); //tolua_export
- bool IsVisible() { return m_bVisible; } //tolua_export
-
- bool MoveToWorld( const char* a_WorldName ); //tolua_export
-
- bool SaveToDisk();
- bool LoadFromDisk();
- void LoadPermissionsFromDisk(); //tolua_export
-
- const AString & GetLoadedWorldName() { return m_LoadedWorldName; }
-
- void UseEquippedItem(void);
-
- /// Returns true if the item type is edible && it has been consumed, false otherwise
- bool EatItem(int a_ItemType);
-
-protected:
- virtual void Destroyed();
-
- typedef std::map< std::string, bool > PermissionMap;
- PermissionMap m_ResolvedPermissions;
- PermissionMap m_Permissions;
-
- GroupList m_ResolvedGroups;
- GroupList m_Groups;
-
- std::string m_PlayerName;
- std::string m_LoadedWorldName;
-
- bool m_bVisible;
-
- float m_LastGroundHeight;
- bool m_bTouchGround;
- double m_Stance;
- cSurvivalInventory* m_Inventory;
- cCreativeInventory* m_CreativeInventory;
- cWindow* m_CurrentWindow;
-
- float m_TimeLastPickupCheck;
-
- void ResolvePermissions();
-
- void ResolveGroups();
- char m_Color;
-
- float m_LastBlockActionTime;
- int m_LastBlockActionCnt;
- eGameMode m_GameMode;
- std::string m_IP;
-
- long long m_LastPlayerListTime;
- static const unsigned short PLAYER_LIST_TIME_MS = 1000; // 1000 = once per second
-
- cClientHandle* m_ClientHandle;
-}; //tolua_export
+ +#pragma once + +#include "cPawn.h" +#include "cSurvivalInventory.h" +#include "cCreativeInventory.h" +#include "Defines.h" + + + + + +class cGroup; +class cWindow; +class cInventory; +class cClientHandle; + + + + + +class cPlayer : public cPawn //tolua_export +{ //tolua_export +public: + typedef cPawn super; + CLASS_PROTOTYPE(); + + cPlayer(cClientHandle * a_Client, const AString & a_PlayerName); + virtual ~cPlayer(); + + virtual void Initialize( cWorld* a_World ); //tolua_export + + virtual cPacket * GetSpawnPacket(void) const override; + virtual void Tick(float a_Dt) override; + + void SetTouchGround( bool a_bTouchGround ); + inline void SetStance( const double & a_Stance ) { m_Stance = a_Stance; } + double GetEyeHeight(); //tolua_export + Vector3d GetEyePosition(); //tolua_export + inline bool GetFlying() { return m_bTouchGround; } //tolua_export + inline const double & GetStance() { return m_Stance; } //tolua_export + inline cInventory & GetInventory() { if(GetGameMode() == eGameMode_Survival) return *m_Inventory; else return *m_CreativeInventory; } //tolua_export + + virtual void TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ); //tolua_export + + eGameMode GetGameMode() { return m_GameMode; } //tolua_export + std::string GetIP() { return m_IP; } //tolua_export + float GetLastBlockActionTime() { return m_LastBlockActionTime; } //tolua_export + int GetLastBlockActionCnt() { return m_LastBlockActionCnt; } //tolua_export + void SetLastBlockActionCnt( int ); //tolua_export + void SetLastBlockActionTime(); //tolua_export + void SetGameMode( eGameMode a_GameMode ); //tolua_export + void LoginSetGameMode( eGameMode a_GameMode ); + void SetIP( std::string a_IP ); + + // Tries to move to a new position, with collision checks and stuff + virtual void MoveTo( const Vector3d & a_NewPos ); //tolua_export + + cWindow* GetWindow() { return m_CurrentWindow; } + void OpenWindow( cWindow* a_Window ); + void CloseWindow(char a_WindowType); + + cClientHandle * GetClientHandle() { return m_ClientHandle; } //tolua_export + + void SendMessage( const char* a_Message ); //tolua_export + + const AString & GetName(void) const { return m_PlayerName; } //tolua_export + void SetName(const AString & a_Name) { m_PlayerName = a_Name; } //tolua_export + + typedef std::list< cGroup* > GroupList; + typedef std::list< std::string > StringList; + void AddToGroup( const char* a_GroupName ); //tolua_export + bool CanUseCommand( const char* a_Command ); //tolua_export + bool HasPermission( const char* a_Permission ); //tolua_export + const GroupList & GetGroups() { return m_Groups; } // >> EXPORTED IN MANUALBINDINGS << + StringList GetResolvedPermissions(); // >> EXPORTED IN MANUALBINDINGS << + bool IsInGroup( const char* a_Group ); //tolua_export + + AString GetColor(void) const; //tolua_export + + void TossItem( bool a_bDraggingItem, int a_Amount = 1 ); //tolua_export + + void Heal( int a_Health ); //tolua_export + + /// Returns true if any food has been consumed, false if player "full" + bool Feed(short a_Food); + + void TakeDamage( int a_Damage, cEntity* a_Instigator ); //tolua_export + void KilledBy( cEntity* a_Killer ); //tolua_export + void Respawn(); //tolua_export + + void SetVisible( bool a_bVisible ); //tolua_export + bool IsVisible() { return m_bVisible; } //tolua_export + + bool MoveToWorld( const char* a_WorldName ); //tolua_export + + bool SaveToDisk(); + bool LoadFromDisk(); + void LoadPermissionsFromDisk(); //tolua_export + + const AString & GetLoadedWorldName() { return m_LoadedWorldName; } + + void UseEquippedItem(void); + + /// Returns true if the item type is edible && it has been consumed, false otherwise + bool EatItem(int a_ItemType); + +protected: + virtual void Destroyed(); + + typedef std::map< std::string, bool > PermissionMap; + PermissionMap m_ResolvedPermissions; + PermissionMap m_Permissions; + + GroupList m_ResolvedGroups; + GroupList m_Groups; + + std::string m_PlayerName; + std::string m_LoadedWorldName; + + bool m_bVisible; + + float m_LastGroundHeight; + bool m_bTouchGround; + double m_Stance; + cSurvivalInventory* m_Inventory; + cCreativeInventory* m_CreativeInventory; + cWindow* m_CurrentWindow; + + float m_TimeLastPickupCheck; + + void ResolvePermissions(); + + void ResolveGroups(); + char m_Color; + + float m_LastBlockActionTime; + int m_LastBlockActionCnt; + eGameMode m_GameMode; + std::string m_IP; + + long long m_LastPlayerListTime; + static const unsigned short PLAYER_LIST_TIME_MS = 1000; // 1000 = once per second + + cClientHandle* m_ClientHandle; +}; //tolua_export diff --git a/source/cPlugin.cpp b/source/cPlugin.cpp index aa8dab01e..61471d8f0 100644 --- a/source/cPlugin.cpp +++ b/source/cPlugin.cpp @@ -1,84 +1,84 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPlugin.h"
-
-
-
-
-
-cPlugin::cPlugin()
- : m_Version( 0 )
- , m_Language( E_CPP )
- , m_bCanBindCommands( false )
-{
-}
-
-cPlugin::~cPlugin()
-{
-}
-
-// bool cPlugin::Initialize()
-// {
-// LOG("cPlugin::Initialize()");
-// return false;
-// }
-
-void cPlugin::Tick(float a_Dt)
-{
- (void)a_Dt;
-}
-
-bool cPlugin::OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player )
-{
- (void)a_PacketData;
- (void)a_Player;
- return false;
-}
-
-bool cPlugin::OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player )
-{
- (void)a_Pickup;
- (void)a_Player;
- return false;
-}
-
-bool cPlugin::OnDisconnect(const AString & a_Reason, cPlayer* a_Player )
-{
- (void)a_Reason;
- (void)a_Player;
- return false;
-}
-
-bool cPlugin::OnChat( const char* a_Chat, cPlayer* a_Player )
-{
- (void)a_Chat;
- (void)a_Player;
- return false;
-}
-
-bool cPlugin::OnLogin( cPacket_Login* a_PacketData )
-{
- (void)a_PacketData;
- return false;
-}
-
-void cPlugin::OnPlayerSpawn( cPlayer* a_Player )
-{
- (void)a_Player;
-}
-
-bool cPlugin::OnPlayerJoin( cPlayer* a_Player )
-{
- (void)a_Player;
- return false;
-}
-
-void cPlugin::AddCommand( std::string & a_Command, std::string & a_Description, std::string & a_Permission )
-{
- CommandStruct Command;
- Command.Command = a_Command;
- Command.Description = a_Description;
- Command.Permission = a_Permission;
- m_Commands.push_back( Command );
-}
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPlugin.h" + + + + + +cPlugin::cPlugin() + : m_Version( 0 ) + , m_Language( E_CPP ) + , m_bCanBindCommands( false ) +{ +} + +cPlugin::~cPlugin() +{ +} + +// bool cPlugin::Initialize() +// { +// LOG("cPlugin::Initialize()"); +// return false; +// } + +void cPlugin::Tick(float a_Dt) +{ + (void)a_Dt; +} + +bool cPlugin::OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) +{ + (void)a_PacketData; + (void)a_Player; + return false; +} + +bool cPlugin::OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player ) +{ + (void)a_Pickup; + (void)a_Player; + return false; +} + +bool cPlugin::OnDisconnect(const AString & a_Reason, cPlayer* a_Player ) +{ + (void)a_Reason; + (void)a_Player; + return false; +} + +bool cPlugin::OnChat( const char* a_Chat, cPlayer* a_Player ) +{ + (void)a_Chat; + (void)a_Player; + return false; +} + +bool cPlugin::OnLogin( cPacket_Login* a_PacketData ) +{ + (void)a_PacketData; + return false; +} + +void cPlugin::OnPlayerSpawn( cPlayer* a_Player ) +{ + (void)a_Player; +} + +bool cPlugin::OnPlayerJoin( cPlayer* a_Player ) +{ + (void)a_Player; + return false; +} + +void cPlugin::AddCommand( std::string & a_Command, std::string & a_Description, std::string & a_Permission ) +{ + CommandStruct Command; + Command.Command = a_Command; + Command.Description = a_Description; + Command.Permission = a_Permission; + m_Commands.push_back( Command ); +} diff --git a/source/cPlugin.h b/source/cPlugin.h index 4c72b300e..4d32396e8 100644 --- a/source/cPlugin.h +++ b/source/cPlugin.h @@ -1,113 +1,113 @@ -
-#pragma once
-
-#include "cItem.h"
-
-class cPacket_BlockPlace;
-class cPacket_PickupSpawn;
-class cPacket_EntityEquipment;
-class cPacket_Disconnect;
-class cPacket_Chat;
-class cPacket_BlockDig;
-class cPacket_Login;
-class cClientHandle;
-class cPlayer;
-class cPickup;
-class cItem;
-class cEntity;
-class cPawn;
-class cWorld;
-class cLuaChunk;
-struct TakeDamageInfo;
-
-// fwd: cPlayer.h
-class cPlayer;
-
-// fwd: CraftingRecipes.h
-class cCraftingGrid;
-class cCraftingRecipe;
-
-
-
-
-
-// tolua_begin
-class cPlugin
-{
-public:
- cPlugin();
- virtual ~cPlugin();
-
- virtual void OnDisable() {}
- virtual bool Initialize() = 0;
-
- // Called each tick
- virtual void Tick(float a_Dt);
-
- /**
- * On all these functions, return true if you want to override default behavior
- * You can also return false, so default behavior is used, but with changed PacketData
- **/
- virtual bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player );
- virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player );
- virtual bool OnBlockPlace (cPacket_BlockPlace* a_PacketData, cPlayer* a_Player );
- virtual bool OnBlockDig (cPacket_BlockDig * a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) { (void)a_PacketData; (void)a_Player; (void)a_PickupItem; return false; }
- virtual bool OnChat (const char * a_Chat, cPlayer* a_Player );
- virtual bool OnLogin (cPacket_Login* a_PacketData );
- virtual void OnPlayerSpawn (cPlayer* a_Player );
- virtual bool OnPlayerJoin (cPlayer* a_Player );
- virtual void OnPlayerMove (cPlayer* a_Player ) { (void)a_Player; }
- virtual void OnTakeDamage (cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) { (void)a_Pawn; (void)a_TakeDamageInfo; }
- virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) { (void)a_Killed; (void)a_Killer; return false; }
- virtual void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) {}
- virtual bool OnChunkGenerating (int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) { return false; }
- virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) {return false; }
- virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) {return false; }
- virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) {return false; }
- virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups) {return false; }
-
- // Accessors
- const char* GetName() const { return m_Name.c_str(); }
- void SetName( const char* a_Name ) { m_Name = a_Name; }
-
- int GetVersion() const { return m_Version; }
- void SetVersion( int a_Version ) { m_Version = a_Version; }
-
- struct CommandStruct
- {
- std::string Command;
- std::string Description;
- std::string Permission;
- };
-
- void AddCommand( std::string & a_Command, std::string & a_Description, std::string & a_Permission );
- // tolua_end
- typedef bool (FuncCommandHandler)( std::string & a_Command, std::vector< std::string > & a_Split );
- void BindCommand( FuncCommandHandler* a_Function, std::string & a_Command ); // >> EXPORTED IN MANUALBINDINGS <<
- const std::vector< CommandStruct > & GetCommands() const { return m_Commands; } // >> EXPORTED IN MANUALBINDINGS <<
-
-
- /* This should not be exposed to scripting languages */
- enum PluginLanguage
- {
- E_CPP,
- E_LUA,
- E_SQUIRREL,
- };
- PluginLanguage GetLanguage() { return m_Language; }
- void SetLanguage( PluginLanguage a_Language ) { m_Language = a_Language; }
-
- bool CanBindCommands() { return m_bCanBindCommands; }
-private:
- friend class cPluginManager;
- bool m_bCanBindCommands; // Only changed by cPluginManager
-
- PluginLanguage m_Language;
- std::vector< CommandStruct > m_Commands;
- std::string m_Name;
- int m_Version;
-}; //tolua_export
-
-
-
-
+ +#pragma once + +#include "cItem.h" + +class cPacket_BlockPlace; +class cPacket_PickupSpawn; +class cPacket_EntityEquipment; +class cPacket_Disconnect; +class cPacket_Chat; +class cPacket_BlockDig; +class cPacket_Login; +class cClientHandle; +class cPlayer; +class cPickup; +class cItem; +class cEntity; +class cPawn; +class cWorld; +class cLuaChunk; +struct TakeDamageInfo; + +// fwd: cPlayer.h +class cPlayer; + +// fwd: CraftingRecipes.h +class cCraftingGrid; +class cCraftingRecipe; + + + + + +// tolua_begin +class cPlugin +{ +public: + cPlugin(); + virtual ~cPlugin(); + + virtual void OnDisable() {} + virtual bool Initialize() = 0; + + // Called each tick + virtual void Tick(float a_Dt); + + /** + * On all these functions, return true if you want to override default behavior + * You can also return false, so default behavior is used, but with changed PacketData + **/ + virtual bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ); + virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ); + virtual bool OnBlockPlace (cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ); + virtual bool OnBlockDig (cPacket_BlockDig * a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) { (void)a_PacketData; (void)a_Player; (void)a_PickupItem; return false; } + virtual bool OnChat (const char * a_Chat, cPlayer* a_Player ); + virtual bool OnLogin (cPacket_Login* a_PacketData ); + virtual void OnPlayerSpawn (cPlayer* a_Player ); + virtual bool OnPlayerJoin (cPlayer* a_Player ); + virtual void OnPlayerMove (cPlayer* a_Player ) { (void)a_Player; } + virtual void OnTakeDamage (cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) { (void)a_Pawn; (void)a_TakeDamageInfo; } + virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) { (void)a_Killed; (void)a_Killer; return false; } + virtual void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) {} + virtual bool OnChunkGenerating (int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) { return false; } + virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) {return false; } + virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) {return false; } + virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) {return false; } + virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups) {return false; } + + // Accessors + const char* GetName() const { return m_Name.c_str(); } + void SetName( const char* a_Name ) { m_Name = a_Name; } + + int GetVersion() const { return m_Version; } + void SetVersion( int a_Version ) { m_Version = a_Version; } + + struct CommandStruct + { + std::string Command; + std::string Description; + std::string Permission; + }; + + void AddCommand( std::string & a_Command, std::string & a_Description, std::string & a_Permission ); + // tolua_end + typedef bool (FuncCommandHandler)( std::string & a_Command, std::vector< std::string > & a_Split ); + void BindCommand( FuncCommandHandler* a_Function, std::string & a_Command ); // >> EXPORTED IN MANUALBINDINGS << + const std::vector< CommandStruct > & GetCommands() const { return m_Commands; } // >> EXPORTED IN MANUALBINDINGS << + + + /* This should not be exposed to scripting languages */ + enum PluginLanguage + { + E_CPP, + E_LUA, + E_SQUIRREL, + }; + PluginLanguage GetLanguage() { return m_Language; } + void SetLanguage( PluginLanguage a_Language ) { m_Language = a_Language; } + + bool CanBindCommands() { return m_bCanBindCommands; } +private: + friend class cPluginManager; + bool m_bCanBindCommands; // Only changed by cPluginManager + + PluginLanguage m_Language; + std::vector< CommandStruct > m_Commands; + std::string m_Name; + int m_Version; +}; //tolua_export + + + + diff --git a/source/cPluginManager.cpp b/source/cPluginManager.cpp index 19518bc9b..c686c9976 100644 --- a/source/cPluginManager.cpp +++ b/source/cPluginManager.cpp @@ -1,749 +1,749 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPluginManager.h"
-#include "cPlugin.h"
-#include "cPlugin_Lua.h"
-#include "cPlugin_NewLua.h"
-#include "cWebAdmin.h"
-#include "cItem.h"
-#include "cRoot.h"
-#include "cLuaCommandBinder.h"
-#include "../iniFile/iniFile.h"
-#include "tolua++.h"
-
-#include "SquirrelBindings.h"
-#if USE_SQUIRREL
- #pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus
- #include <sqplus/sqplus.h>
- #pragma warning(default:4100;default:4127;default:4510;default:4610;default:4244;default:4512)
-#endif
-
-
-
-
-
-cPluginManager* cPluginManager::GetPluginManager()
-{
- LOGWARN("WARNING: Using deprecated function cPluginManager::GetPluginManager() use cRoot::Get()->GetPluginManager() instead!");
- return cRoot::Get()->GetPluginManager();
-}
-
-
-
-
-
-cPluginManager::cPluginManager()
- : m_LuaCommandBinder( new cLuaCommandBinder() )
- , m_bReloadPlugins(false)
-{
-}
-
-
-
-
-
-cPluginManager::~cPluginManager()
-{
- UnloadPluginsNow();
-
- delete m_LuaCommandBinder;
-}
-
-
-
-
-
-void cPluginManager::ReloadPlugins()
-{
- m_bReloadPlugins = true;
-}
-
-
-
-
-
-void cPluginManager::ReloadPluginsNow()
-{
- LOG("Loading plugins");
- m_bReloadPlugins = false;
- UnloadPluginsNow();
-
- #if USE_SQUIRREL
- if( !SquirrelBindings::IsBound ) // Can only do this once apparently, or we're making ambiguous calls in the script
- {
- SquirrelVM::Init();
- SquirrelBindings::Bind( SquirrelVM::GetVMPtr() );
- }
- #endif // USE_SQUIRREL
-
- cIniFile IniFile("settings.ini");
- if (!IniFile.ReadFile() )
- {
- LOGWARNING("cPluginManager: Can't find settings.ini, so can't load any plugins.");
- }
-
- unsigned int KeyNum = IniFile.FindKey("Plugins");
- unsigned int NumPlugins = IniFile.GetNumValues( KeyNum );
- if( NumPlugins > 0 )
- {
- for(unsigned int i = 0; i < NumPlugins; i++)
- {
- AString ValueName = IniFile.GetValueName(KeyNum, i );
- if( ValueName.compare("Plugin") == 0 ) // It's a Lua plugin
- {
- AString PluginFile = IniFile.GetValue(KeyNum, i );
- if( !PluginFile.empty() )
- {
- // allow for comma separated plugin list
- // degrades and works fine for the plugin
- // per line
- AStringVector split = StringSplit( PluginFile, "," );
- for (unsigned int j = 0; j < split.size(); j++)
- {
- cPlugin_Lua* Plugin = new cPlugin_Lua( (split[j] + AString(".lua") ).c_str() );
- if( !AddLuaPlugin( Plugin ) )
- {
- delete Plugin;
- }
- }
- }
- }
- else if( ValueName.compare("NewPlugin") == 0 ) // New plugin style
- {
- AString PluginFile = IniFile.GetValue(KeyNum, i );
- if( !PluginFile.empty() )
- {
- cPlugin_NewLua* Plugin = new cPlugin_NewLua( PluginFile.c_str() );
- if( !AddPlugin( Plugin ) )
- {
- delete Plugin;
- }
- }
- }
-
- #if USE_SQUIRREL
- else if( ValueName.compare("Squirrel") == 0 ) // Squirrel plugin
- {
- AString PluginFile = IniFile.GetValue(KeyNum, i );
- if( !PluginFile.empty() )
- {
- LOGINFO("Loading Squirrel plugin: %s", PluginFile.c_str() );
- try
- {
- SquirrelObject SquirrelScript = SquirrelVM::CompileScript( (AString("Plugins/") + PluginFile + ".nut").c_str() );
- try
- {
- SquirrelVM::RunScript( SquirrelScript );
- }
- catch (SquirrelError & e)
- {
- LOGERROR("SquirrelScript error: %s, %s\n", e.desc, "SquirrelVM::RunScript");
- }
- }
- catch (SquirrelError & e)
- {
- LOGERROR("SquirrelScript error: %s, %s\n", e.desc, "SquirrelVM::CompileScript");
- }
- }
- }
- #endif // USE_SQUIRREL
-
- }
- }
-
- if( GetNumPlugins() == 0 )
- {
- LOG("No plugins loaded");
- }
- else
- {
- LOG("Loaded %i plugin(s)", GetNumPlugins() );
- }
-}
-
-
-
-
-
-void cPluginManager::Tick(float a_Dt)
-{
- if( m_bReloadPlugins )
- {
- ReloadPluginsNow();
- }
-
- HookMap::iterator Plugins = m_Hooks.find( E_PLUGIN_TICK );
- if( Plugins != m_Hooks.end() )
- {
- for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
- {
- (*itr)->Tick( a_Dt );
- }
- }
-}
-
-
-
-
-
-bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...)
-{
- HookMap::iterator Plugins = m_Hooks.find( a_Hook );
-
- // Special case for chat hook, since you can also bind commands (bound commands don't use chat hook)
- if (a_Hook == HOOK_CHAT)
- {
- if (a_NumArgs != 2)
- {
- return false;
- }
- va_list argptr;
- va_start( argptr, a_NumArgs);
- const char * Message = va_arg(argptr, const char* );
- cPlayer * Player = va_arg(argptr, cPlayer * );
- va_end (argptr);
-
- if (m_LuaCommandBinder->HandleCommand( std::string( Message ), Player))
- {
- return true;
- }
-
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
-
- for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
- {
- if ((*itr)->OnChat(Message, Player))
- {
- return true;
- }
- }
- return false;
- }
-
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
-
- switch( a_Hook )
- {
- case HOOK_COLLECT_ITEM:
- {
- if( a_NumArgs != 2 ) break;
- va_list argptr;
- va_start( argptr, a_NumArgs);
- cPickup* Pickup = va_arg(argptr, cPickup* );
- cPlayer* Player = va_arg(argptr, cPlayer* );
- va_end (argptr);
- for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
- {
- if( (*itr)->OnCollectItem( Pickup, Player ) )
- return true;
- }
- break;
- }
-
- case HOOK_BLOCK_DIG:
- {
- if( a_NumArgs != 2 ) break;
- va_list argptr;
- va_start( argptr, a_NumArgs);
- cPacket_BlockDig* Packet = va_arg(argptr, cPacket_BlockDig* );
- cPlayer* Player = va_arg(argptr, cPlayer* );
- cItem* Item = va_arg( argptr, cItem* );
- va_end (argptr);
- for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
- {
- if( (*itr)->OnBlockDig( Packet, Player, Item ) )
- return true;
- }
- break;
- }
-
- case HOOK_BLOCK_PLACE:
- {
- if( a_NumArgs != 2 ) break;
- va_list argptr;
- va_start( argptr, a_NumArgs);
- cPacket_BlockPlace* Packet = va_arg(argptr, cPacket_BlockPlace* );
- cPlayer* Player = va_arg(argptr, cPlayer* );
- va_end (argptr);
- for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
- {
- if( (*itr)->OnBlockPlace( Packet, Player ) )
- return true;
- }
- break;
- }
-
- case HOOK_DISCONNECT:
- {
- if( a_NumArgs != 2 ) break;
- va_list argptr;
- va_start( argptr, a_NumArgs);
- const char* Reason = va_arg(argptr, const char* );
- cPlayer* Player = va_arg(argptr, cPlayer* );
- va_end (argptr);
- for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
- {
- if( (*itr)->OnDisconnect( Reason, Player ) )
- return true;
- }
- break;
- }
-
- case HOOK_LOGIN:
- {
- if( a_NumArgs != 1 ) break;
- va_list argptr;
- va_start( argptr, a_NumArgs);
- cPacket_Login* Packet = va_arg(argptr, cPacket_Login* );
- va_end (argptr);
- for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
- {
- if( (*itr)->OnLogin( Packet ) )
- return true;
- }
- break;
- }
-
- case HOOK_PLAYER_JOIN:
- {
- if( a_NumArgs != 1 ) break;
- va_list argptr;
- va_start( argptr, a_NumArgs);
- cPlayer* Player = va_arg(argptr, cPlayer* );
- va_end (argptr);
- for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
- {
- if( (*itr)->OnPlayerJoin( Player ) )
- return true;
- }
- break;
- }
-
- case HOOK_PLAYER_MOVE:
- {
- if( a_NumArgs != 1 ) break;
- va_list argptr;
- va_start( argptr, a_NumArgs);
- cPlayer* Player = va_arg(argptr, cPlayer* );
- va_end (argptr);
- for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
- {
- (*itr)->OnPlayerMove( Player );
- }
- break;
- }
-
- case HOOK_TAKE_DAMAGE:
- {
- if( a_NumArgs != 2 ) break;
- va_list argptr;
- va_start( argptr, a_NumArgs);
- cPawn* Pawn = va_arg(argptr, cPawn* );
- TakeDamageInfo* TDI = va_arg(argptr, TakeDamageInfo* );
- va_end (argptr);
- for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
- {
- (*itr)->OnTakeDamage( Pawn, TDI );
- }
- break;
- }
-
- case HOOK_KILLED:
- {
- if( a_NumArgs != 2 ) break;
- va_list argptr;
- va_start( argptr, a_NumArgs);
- cPawn* Killed = va_arg(argptr, cPawn* );
- cEntity* Killer = va_arg(argptr, cEntity* );
- va_end (argptr);
- for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
- {
- if( (*itr)->OnKilled( Killed, Killer ) )
- return true;
- }
- break;
- }
-
- case HOOK_CHUNK_GENERATED:
- {
- if (a_NumArgs != 3)
- {
- break;
- }
- va_list argptr;
- va_start( argptr, a_NumArgs);
- cWorld * World = va_arg(argptr, cWorld *);
- int ChunkX = va_arg(argptr, int);
- int ChunkZ = va_arg(argptr, int);
- va_end (argptr);
- for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
- {
- (*itr)->OnChunkGenerated(World, ChunkX, ChunkZ);
- }
- break;
- }
-
- case HOOK_CHUNK_GENERATING:
- {
- if (a_NumArgs != 3)
- {
- break;
- }
- va_list argptr;
- va_start( argptr, a_NumArgs);
- int ChunkX = va_arg(argptr, int);
- int ChunkZ = va_arg(argptr, int);
- cLuaChunk * LuaChunk = va_arg(argptr, cLuaChunk *);
- va_end (argptr);
- for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
- {
- if ((*itr)->OnChunkGenerating(ChunkX, ChunkZ, LuaChunk))
- {
- return true;
- }
- }
- break;
- }
-
- default:
- {
- LOGWARNING("cPluginManager: Calling Unknown hook: %i", a_Hook );
- ASSERT(!"Calling an unknown hook");
- break;
- }
- } // switch (a_Hook)
- return false;
-}
-
-
-
-
-
-bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
-{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PRE_CRAFTING);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
- for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
- {
- if ((*itr)->OnPreCrafting(a_Player, a_Grid, a_Recipe))
- {
- return true;
- }
- }
- return false;
-}
-
-
-
-
-
-bool cPluginManager::CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
-{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_CRAFTING_NO_RECIPE);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
- for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
- {
- if ((*itr)->OnCraftingNoRecipe(a_Player, a_Grid, a_Recipe))
- {
- return true;
- }
- }
- return false;
-}
-
-
-
-
-
-bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
-{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
- for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
- {
- if ((*itr)->OnPostCrafting(a_Player, a_Grid, a_Recipe))
- {
- return true;
- }
- }
- return false;
-}
-
-
-
-
-
-bool cPluginManager::CallHookBlockToPickup(
- BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta,
- const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups
-)
-{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
- for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
- {
- if ((*itr)->OnBlockToPickup(a_BlockType, a_BlockMeta, a_Player, a_EquippedItem, a_Pickups))
- {
- return true;
- }
- }
- return false;
-}
-
-
-
-
-
-cPlugin* cPluginManager::GetPlugin( const char* a_Plugin ) const
-{
- for( PluginList::const_iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr )
- {
- if (strcmp((*itr)->GetName(), a_Plugin) == 0 )
- {
- return *itr;
- }
- }
- return 0;
-}
-
-
-
-
-
-const cPluginManager::PluginList & cPluginManager::GetAllPlugins() const
-{
- return m_Plugins;
-}
-
-
-
-
-
-void cPluginManager::UnloadPluginsNow()
-{
- m_Hooks.clear();
-
- while( m_LuaPlugins.size() > 0 )
- {
- cPlugin_Lua* LuaPlugin = *m_LuaPlugins.begin();
- if( LuaPlugin )
- {
- cWebAdmin* WebAdmin = cRoot::Get()->GetWebAdmin();
- if( WebAdmin ) WebAdmin->RemovePlugin( LuaPlugin->GetLuaState() );
- delete LuaPlugin;
- }
- m_LuaPlugins.remove( LuaPlugin );
- }
-
- while( m_Plugins.size() > 0 )
- {
- RemovePlugin( *m_Plugins.begin(), true );
- }
-
- //SquirrelVM::Shutdown(); // This breaks shit
-}
-
-
-
-
-
-void cPluginManager::RemoveHooks( cPlugin* a_Plugin )
-{
- m_Hooks[ E_PLUGIN_TICK].remove ( a_Plugin );
- m_Hooks[ E_PLUGIN_CHAT].remove ( a_Plugin );
- m_Hooks[ E_PLUGIN_COLLECT_ITEM].remove ( a_Plugin );
- m_Hooks[ E_PLUGIN_BLOCK_DIG].remove ( a_Plugin );
- m_Hooks[ E_PLUGIN_BLOCK_PLACE].remove ( a_Plugin );
- m_Hooks[ E_PLUGIN_DISCONNECT].remove ( a_Plugin );
- m_Hooks[ E_PLUGIN_HANDSHAKE].remove ( a_Plugin );
- m_Hooks[ E_PLUGIN_LOGIN].remove ( a_Plugin );
- m_Hooks[ E_PLUGIN_PLAYER_SPAWN].remove ( a_Plugin );
- m_Hooks[ E_PLUGIN_PLAYER_JOIN].remove ( a_Plugin );
- m_Hooks[ E_PLUGIN_PLAYER_MOVE].remove ( a_Plugin );
- m_Hooks[ E_PLUGIN_TAKE_DAMAGE].remove ( a_Plugin );
- m_Hooks[ E_PLUGIN_KILLED].remove ( a_Plugin );
- m_Hooks[ E_PLUGIN_CHUNK_GENERATED ].remove ( a_Plugin );
- m_Hooks[ E_PLUGIN_CHUNK_GENERATING ].remove( a_Plugin );
- m_Hooks[ E_PLUGIN_BLOCK_TO_DROPS ].remove ( a_Plugin );
-}
-
-
-
-
-
-void cPluginManager::RemovePlugin( cPlugin* a_Plugin, bool a_bDelete /* = false */ )
-{
- if( a_bDelete )
- {
- m_LuaCommandBinder->RemoveBindingsForPlugin( a_Plugin );
- m_Plugins.remove( a_Plugin );
- RemoveHooks( a_Plugin );
- a_Plugin->OnDisable();
- if( a_Plugin->GetLanguage() != cPlugin::E_SQUIRREL ) // Squirrel needs to clean it up himself!
- {
- delete a_Plugin;
- }
- }
- else
- {
- for( LuaPluginList::iterator itr = m_LuaPlugins.begin(); itr != m_LuaPlugins.end(); ++itr )
- {
- (*itr)->RemovePlugin( a_Plugin );
- }
- }
-}
-
-
-
-
-
-bool cPluginManager::AddPlugin( cPlugin* a_Plugin )
-{
- a_Plugin->m_bCanBindCommands = true;
- if( a_Plugin->Initialize() )
- {
- m_Plugins.remove( a_Plugin );
- m_Plugins.push_back( a_Plugin );
- return true;
- }
-
- a_Plugin->m_bCanBindCommands = false;
- RemoveHooks( a_Plugin ); // Undo any damage the Initialize() might have done
- return false;
-}
-
-
-
-
-
-bool cPluginManager::AddPlugin( lua_State* a_LuaState, cPlugin* a_Plugin )
-{
- a_Plugin->SetLanguage( cPlugin::E_LUA );
- cPlugin_Lua* LuaPlugin = GetLuaPlugin( a_LuaState );
- if( LuaPlugin == NULL )
- {
- lua_Debug ar;
- lua_getstack(a_LuaState, 1, &ar);
- lua_getinfo(a_LuaState, "nSl", &ar);
- LOGERROR("ERROR: Trying to add an 'old style' plugin from within a 'new style' plugin.\nIn file: %s at line: %i", ar.source, ar.currentline);
- }
- a_Plugin->m_bCanBindCommands = true;
- if( LuaPlugin && a_Plugin->Initialize() )
- {
- m_Plugins.remove( a_Plugin );
- m_Plugins.push_back( a_Plugin );
- LuaPlugin->AddPlugin( a_Plugin );
- return true;
- }
-
- a_Plugin->m_bCanBindCommands = false;
- return false;
-}
-
-
-
-
-
-bool cPluginManager::AddLuaPlugin( cPlugin_Lua* a_Plugin )
-{
- m_LuaPlugins.push_back( a_Plugin ); // It HAS to be in here before calling Initialize, so it can be found by AddPlugin()
- if(a_Plugin->Initialize() )
- {
- return true;
- }
- LOG(">>>>>>> Could not initialize a plugin! ");
- m_LuaPlugins.remove( a_Plugin );
- return false;
-}
-
-
-
-
-
-void cPluginManager::RemoveLuaPlugin( std::string a_FileName )
-{
- for( LuaPluginList::iterator itr = m_LuaPlugins.begin(); itr != m_LuaPlugins.end(); ++itr )
- {
- if( (*itr)->GetFileName() == a_FileName )
- {
- cPlugin_Lua* Plugin = *itr;
- m_LuaPlugins.remove( Plugin );
- delete Plugin;
- return;
- }
- }
-}
-
-
-
-
-
-cPlugin_Lua* cPluginManager::GetLuaPlugin( lua_State* a_State )
-{
- for( LuaPluginList::iterator itr = m_LuaPlugins.begin(); itr != m_LuaPlugins.end(); ++itr )
- {
- if( (*itr)->GetLuaState() == a_State )
- {
- return *itr;
- }
- }
- return NULL;
-}
-
-
-
-
-
-void cPluginManager::AddHook( cPlugin* a_Plugin, PluginHook a_Hook )
-{
- if( !a_Plugin )
- {
- LOGWARN("Called cPluginManager::AddHook while a_Plugin is NULL");
- return;
- }
- PluginList & Plugins = m_Hooks[ a_Hook ];
- Plugins.remove( a_Plugin );
- Plugins.push_back( a_Plugin );
-}
-
-
-
-
-
-unsigned int cPluginManager::GetNumPlugins() const
-{
- return m_Plugins.size();
-}
-
-
-
-
-
-bool cPluginManager::HasPlugin( cPlugin* a_Plugin ) const
-{
- for( PluginList::const_iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr )
- {
- if( *itr == a_Plugin )
- return true;
- }
- return false;
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPluginManager.h" +#include "cPlugin.h" +#include "cPlugin_Lua.h" +#include "cPlugin_NewLua.h" +#include "cWebAdmin.h" +#include "cItem.h" +#include "cRoot.h" +#include "cLuaCommandBinder.h" +#include "../iniFile/iniFile.h" +#include "tolua++.h" + +#include "SquirrelBindings.h" +#if USE_SQUIRREL + #pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus + #include <sqplus/sqplus.h> + #pragma warning(default:4100;default:4127;default:4510;default:4610;default:4244;default:4512) +#endif + + + + + +cPluginManager* cPluginManager::GetPluginManager() +{ + LOGWARN("WARNING: Using deprecated function cPluginManager::GetPluginManager() use cRoot::Get()->GetPluginManager() instead!"); + return cRoot::Get()->GetPluginManager(); +} + + + + + +cPluginManager::cPluginManager() + : m_LuaCommandBinder( new cLuaCommandBinder() ) + , m_bReloadPlugins(false) +{ +} + + + + + +cPluginManager::~cPluginManager() +{ + UnloadPluginsNow(); + + delete m_LuaCommandBinder; +} + + + + + +void cPluginManager::ReloadPlugins() +{ + m_bReloadPlugins = true; +} + + + + + +void cPluginManager::ReloadPluginsNow() +{ + LOG("Loading plugins"); + m_bReloadPlugins = false; + UnloadPluginsNow(); + + #if USE_SQUIRREL + if( !SquirrelBindings::IsBound ) // Can only do this once apparently, or we're making ambiguous calls in the script + { + SquirrelVM::Init(); + SquirrelBindings::Bind( SquirrelVM::GetVMPtr() ); + } + #endif // USE_SQUIRREL + + cIniFile IniFile("settings.ini"); + if (!IniFile.ReadFile() ) + { + LOGWARNING("cPluginManager: Can't find settings.ini, so can't load any plugins."); + } + + unsigned int KeyNum = IniFile.FindKey("Plugins"); + unsigned int NumPlugins = IniFile.GetNumValues( KeyNum ); + if( NumPlugins > 0 ) + { + for(unsigned int i = 0; i < NumPlugins; i++) + { + AString ValueName = IniFile.GetValueName(KeyNum, i ); + if( ValueName.compare("Plugin") == 0 ) // It's a Lua plugin + { + AString PluginFile = IniFile.GetValue(KeyNum, i ); + if( !PluginFile.empty() ) + { + // allow for comma separated plugin list + // degrades and works fine for the plugin + // per line + AStringVector split = StringSplit( PluginFile, "," ); + for (unsigned int j = 0; j < split.size(); j++) + { + cPlugin_Lua* Plugin = new cPlugin_Lua( (split[j] + AString(".lua") ).c_str() ); + if( !AddLuaPlugin( Plugin ) ) + { + delete Plugin; + } + } + } + } + else if( ValueName.compare("NewPlugin") == 0 ) // New plugin style + { + AString PluginFile = IniFile.GetValue(KeyNum, i ); + if( !PluginFile.empty() ) + { + cPlugin_NewLua* Plugin = new cPlugin_NewLua( PluginFile.c_str() ); + if( !AddPlugin( Plugin ) ) + { + delete Plugin; + } + } + } + + #if USE_SQUIRREL + else if( ValueName.compare("Squirrel") == 0 ) // Squirrel plugin + { + AString PluginFile = IniFile.GetValue(KeyNum, i ); + if( !PluginFile.empty() ) + { + LOGINFO("Loading Squirrel plugin: %s", PluginFile.c_str() ); + try + { + SquirrelObject SquirrelScript = SquirrelVM::CompileScript( (AString("Plugins/") + PluginFile + ".nut").c_str() ); + try + { + SquirrelVM::RunScript( SquirrelScript ); + } + catch (SquirrelError & e) + { + LOGERROR("SquirrelScript error: %s, %s\n", e.desc, "SquirrelVM::RunScript"); + } + } + catch (SquirrelError & e) + { + LOGERROR("SquirrelScript error: %s, %s\n", e.desc, "SquirrelVM::CompileScript"); + } + } + } + #endif // USE_SQUIRREL + + } + } + + if( GetNumPlugins() == 0 ) + { + LOG("No plugins loaded"); + } + else + { + LOG("Loaded %i plugin(s)", GetNumPlugins() ); + } +} + + + + + +void cPluginManager::Tick(float a_Dt) +{ + if( m_bReloadPlugins ) + { + ReloadPluginsNow(); + } + + HookMap::iterator Plugins = m_Hooks.find( E_PLUGIN_TICK ); + if( Plugins != m_Hooks.end() ) + { + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + (*itr)->Tick( a_Dt ); + } + } +} + + + + + +bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...) +{ + HookMap::iterator Plugins = m_Hooks.find( a_Hook ); + + // Special case for chat hook, since you can also bind commands (bound commands don't use chat hook) + if (a_Hook == HOOK_CHAT) + { + if (a_NumArgs != 2) + { + return false; + } + va_list argptr; + va_start( argptr, a_NumArgs); + const char * Message = va_arg(argptr, const char* ); + cPlayer * Player = va_arg(argptr, cPlayer * ); + va_end (argptr); + + if (m_LuaCommandBinder->HandleCommand( std::string( Message ), Player)) + { + return true; + } + + if (Plugins == m_Hooks.end()) + { + return false; + } + + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnChat(Message, Player)) + { + return true; + } + } + return false; + } + + if (Plugins == m_Hooks.end()) + { + return false; + } + + switch( a_Hook ) + { + case HOOK_COLLECT_ITEM: + { + if( a_NumArgs != 2 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPickup* Pickup = va_arg(argptr, cPickup* ); + cPlayer* Player = va_arg(argptr, cPlayer* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + if( (*itr)->OnCollectItem( Pickup, Player ) ) + return true; + } + break; + } + + case HOOK_BLOCK_DIG: + { + if( a_NumArgs != 2 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPacket_BlockDig* Packet = va_arg(argptr, cPacket_BlockDig* ); + cPlayer* Player = va_arg(argptr, cPlayer* ); + cItem* Item = va_arg( argptr, cItem* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + if( (*itr)->OnBlockDig( Packet, Player, Item ) ) + return true; + } + break; + } + + case HOOK_BLOCK_PLACE: + { + if( a_NumArgs != 2 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPacket_BlockPlace* Packet = va_arg(argptr, cPacket_BlockPlace* ); + cPlayer* Player = va_arg(argptr, cPlayer* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + if( (*itr)->OnBlockPlace( Packet, Player ) ) + return true; + } + break; + } + + case HOOK_DISCONNECT: + { + if( a_NumArgs != 2 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + const char* Reason = va_arg(argptr, const char* ); + cPlayer* Player = va_arg(argptr, cPlayer* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + if( (*itr)->OnDisconnect( Reason, Player ) ) + return true; + } + break; + } + + case HOOK_LOGIN: + { + if( a_NumArgs != 1 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPacket_Login* Packet = va_arg(argptr, cPacket_Login* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + if( (*itr)->OnLogin( Packet ) ) + return true; + } + break; + } + + case HOOK_PLAYER_JOIN: + { + if( a_NumArgs != 1 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPlayer* Player = va_arg(argptr, cPlayer* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + if( (*itr)->OnPlayerJoin( Player ) ) + return true; + } + break; + } + + case HOOK_PLAYER_MOVE: + { + if( a_NumArgs != 1 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPlayer* Player = va_arg(argptr, cPlayer* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + (*itr)->OnPlayerMove( Player ); + } + break; + } + + case HOOK_TAKE_DAMAGE: + { + if( a_NumArgs != 2 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPawn* Pawn = va_arg(argptr, cPawn* ); + TakeDamageInfo* TDI = va_arg(argptr, TakeDamageInfo* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + (*itr)->OnTakeDamage( Pawn, TDI ); + } + break; + } + + case HOOK_KILLED: + { + if( a_NumArgs != 2 ) break; + va_list argptr; + va_start( argptr, a_NumArgs); + cPawn* Killed = va_arg(argptr, cPawn* ); + cEntity* Killer = va_arg(argptr, cEntity* ); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + if( (*itr)->OnKilled( Killed, Killer ) ) + return true; + } + break; + } + + case HOOK_CHUNK_GENERATED: + { + if (a_NumArgs != 3) + { + break; + } + va_list argptr; + va_start( argptr, a_NumArgs); + cWorld * World = va_arg(argptr, cWorld *); + int ChunkX = va_arg(argptr, int); + int ChunkZ = va_arg(argptr, int); + va_end (argptr); + for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) + { + (*itr)->OnChunkGenerated(World, ChunkX, ChunkZ); + } + break; + } + + case HOOK_CHUNK_GENERATING: + { + if (a_NumArgs != 3) + { + break; + } + va_list argptr; + va_start( argptr, a_NumArgs); + int ChunkX = va_arg(argptr, int); + int ChunkZ = va_arg(argptr, int); + cLuaChunk * LuaChunk = va_arg(argptr, cLuaChunk *); + va_end (argptr); + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnChunkGenerating(ChunkX, ChunkZ, LuaChunk)) + { + return true; + } + } + break; + } + + default: + { + LOGWARNING("cPluginManager: Calling Unknown hook: %i", a_Hook ); + ASSERT(!"Calling an unknown hook"); + break; + } + } // switch (a_Hook) + return false; +} + + + + + +bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_PRE_CRAFTING); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnPreCrafting(a_Player, a_Grid, a_Recipe)) + { + return true; + } + } + return false; +} + + + + + +bool cPluginManager::CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_CRAFTING_NO_RECIPE); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnCraftingNoRecipe(a_Player, a_Grid, a_Recipe)) + { + return true; + } + } + return false; +} + + + + + +bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnPostCrafting(a_Player, a_Grid, a_Recipe)) + { + return true; + } + } + return false; +} + + + + + +bool cPluginManager::CallHookBlockToPickup( + BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, + const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups +) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnBlockToPickup(a_BlockType, a_BlockMeta, a_Player, a_EquippedItem, a_Pickups)) + { + return true; + } + } + return false; +} + + + + + +cPlugin* cPluginManager::GetPlugin( const char* a_Plugin ) const +{ + for( PluginList::const_iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr ) + { + if (strcmp((*itr)->GetName(), a_Plugin) == 0 ) + { + return *itr; + } + } + return 0; +} + + + + + +const cPluginManager::PluginList & cPluginManager::GetAllPlugins() const +{ + return m_Plugins; +} + + + + + +void cPluginManager::UnloadPluginsNow() +{ + m_Hooks.clear(); + + while( m_LuaPlugins.size() > 0 ) + { + cPlugin_Lua* LuaPlugin = *m_LuaPlugins.begin(); + if( LuaPlugin ) + { + cWebAdmin* WebAdmin = cRoot::Get()->GetWebAdmin(); + if( WebAdmin ) WebAdmin->RemovePlugin( LuaPlugin->GetLuaState() ); + delete LuaPlugin; + } + m_LuaPlugins.remove( LuaPlugin ); + } + + while( m_Plugins.size() > 0 ) + { + RemovePlugin( *m_Plugins.begin(), true ); + } + + //SquirrelVM::Shutdown(); // This breaks shit +} + + + + + +void cPluginManager::RemoveHooks( cPlugin* a_Plugin ) +{ + m_Hooks[ E_PLUGIN_TICK].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_CHAT].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_COLLECT_ITEM].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_BLOCK_DIG].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_BLOCK_PLACE].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_DISCONNECT].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_HANDSHAKE].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_LOGIN].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_PLAYER_SPAWN].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_PLAYER_JOIN].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_PLAYER_MOVE].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_TAKE_DAMAGE].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_KILLED].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_CHUNK_GENERATED ].remove ( a_Plugin ); + m_Hooks[ E_PLUGIN_CHUNK_GENERATING ].remove( a_Plugin ); + m_Hooks[ E_PLUGIN_BLOCK_TO_DROPS ].remove ( a_Plugin ); +} + + + + + +void cPluginManager::RemovePlugin( cPlugin* a_Plugin, bool a_bDelete /* = false */ ) +{ + if( a_bDelete ) + { + m_LuaCommandBinder->RemoveBindingsForPlugin( a_Plugin ); + m_Plugins.remove( a_Plugin ); + RemoveHooks( a_Plugin ); + a_Plugin->OnDisable(); + if( a_Plugin->GetLanguage() != cPlugin::E_SQUIRREL ) // Squirrel needs to clean it up himself! + { + delete a_Plugin; + } + } + else + { + for( LuaPluginList::iterator itr = m_LuaPlugins.begin(); itr != m_LuaPlugins.end(); ++itr ) + { + (*itr)->RemovePlugin( a_Plugin ); + } + } +} + + + + + +bool cPluginManager::AddPlugin( cPlugin* a_Plugin ) +{ + a_Plugin->m_bCanBindCommands = true; + if( a_Plugin->Initialize() ) + { + m_Plugins.remove( a_Plugin ); + m_Plugins.push_back( a_Plugin ); + return true; + } + + a_Plugin->m_bCanBindCommands = false; + RemoveHooks( a_Plugin ); // Undo any damage the Initialize() might have done + return false; +} + + + + + +bool cPluginManager::AddPlugin( lua_State* a_LuaState, cPlugin* a_Plugin ) +{ + a_Plugin->SetLanguage( cPlugin::E_LUA ); + cPlugin_Lua* LuaPlugin = GetLuaPlugin( a_LuaState ); + if( LuaPlugin == NULL ) + { + lua_Debug ar; + lua_getstack(a_LuaState, 1, &ar); + lua_getinfo(a_LuaState, "nSl", &ar); + LOGERROR("ERROR: Trying to add an 'old style' plugin from within a 'new style' plugin.\nIn file: %s at line: %i", ar.source, ar.currentline); + } + a_Plugin->m_bCanBindCommands = true; + if( LuaPlugin && a_Plugin->Initialize() ) + { + m_Plugins.remove( a_Plugin ); + m_Plugins.push_back( a_Plugin ); + LuaPlugin->AddPlugin( a_Plugin ); + return true; + } + + a_Plugin->m_bCanBindCommands = false; + return false; +} + + + + + +bool cPluginManager::AddLuaPlugin( cPlugin_Lua* a_Plugin ) +{ + m_LuaPlugins.push_back( a_Plugin ); // It HAS to be in here before calling Initialize, so it can be found by AddPlugin() + if(a_Plugin->Initialize() ) + { + return true; + } + LOG(">>>>>>> Could not initialize a plugin! "); + m_LuaPlugins.remove( a_Plugin ); + return false; +} + + + + + +void cPluginManager::RemoveLuaPlugin( std::string a_FileName ) +{ + for( LuaPluginList::iterator itr = m_LuaPlugins.begin(); itr != m_LuaPlugins.end(); ++itr ) + { + if( (*itr)->GetFileName() == a_FileName ) + { + cPlugin_Lua* Plugin = *itr; + m_LuaPlugins.remove( Plugin ); + delete Plugin; + return; + } + } +} + + + + + +cPlugin_Lua* cPluginManager::GetLuaPlugin( lua_State* a_State ) +{ + for( LuaPluginList::iterator itr = m_LuaPlugins.begin(); itr != m_LuaPlugins.end(); ++itr ) + { + if( (*itr)->GetLuaState() == a_State ) + { + return *itr; + } + } + return NULL; +} + + + + + +void cPluginManager::AddHook( cPlugin* a_Plugin, PluginHook a_Hook ) +{ + if( !a_Plugin ) + { + LOGWARN("Called cPluginManager::AddHook while a_Plugin is NULL"); + return; + } + PluginList & Plugins = m_Hooks[ a_Hook ]; + Plugins.remove( a_Plugin ); + Plugins.push_back( a_Plugin ); +} + + + + + +unsigned int cPluginManager::GetNumPlugins() const +{ + return m_Plugins.size(); +} + + + + + +bool cPluginManager::HasPlugin( cPlugin* a_Plugin ) const +{ + for( PluginList::const_iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr ) + { + if( *itr == a_Plugin ) + return true; + } + return false; }
\ No newline at end of file diff --git a/source/cPluginManager.h b/source/cPluginManager.h index 59191ecc3..e9010ebd9 100644 --- a/source/cPluginManager.h +++ b/source/cPluginManager.h @@ -1,121 +1,121 @@ -
-#pragma once
-
-#include "cItem.h"
-
-struct lua_State;
-class cLuaCommandBinder;
-class cPlugin;
-class cPlugin_Lua;
-
-// fwd: cPlayer.h
-class cPlayer;
-
-// fwd: CraftingRecipes.h
-class cCraftingGrid;
-class cCraftingRecipe;
-
-
-
-
-
-class cPluginManager //tolua_export
-{ //tolua_export
-public: //tolua_export
-
- // Called each tick
- virtual void Tick(float a_Dt);
-
- // tolua_begin
- enum PluginHook
- {
- HOOK_TICK,
- HOOK_CHAT,
- HOOK_COLLECT_ITEM,
- HOOK_BLOCK_DIG,
- HOOK_BLOCK_PLACE,
- HOOK_DISCONNECT,
- HOOK_HANDSHAKE,
- HOOK_LOGIN,
- HOOK_PLAYER_SPAWN,
- HOOK_PLAYER_JOIN,
- HOOK_PLAYER_MOVE,
- HOOK_TAKE_DAMAGE,
- HOOK_KILLED,
- HOOK_CHUNK_GENERATED,
- HOOK_CHUNK_GENERATING,
- HOOK_BLOCK_TO_DROPS,
- HOOK_PRE_CRAFTING, /// cPlayer, cCraftingGrid, cCraftingRecipe
- HOOK_CRAFTING_NO_RECIPE, /// cPlayer, cCraftingGrid, cCraftingRecipe
- HOOK_POST_CRAFTING, /// cPlayer, cCraftingGrid, cCraftingRecipe
- HOOK_BLOCK_TO_PICKUP, /// BlockType, BlockMeta, cPlayer, cItem, cItems
- HOOK_WEATHER_CHANGE,
-
- // E_PLUGIN_ names are obsolete, but are kept for compatibility reasons
- E_PLUGIN_TICK = HOOK_TICK,
- E_PLUGIN_CHAT = HOOK_CHAT,
- E_PLUGIN_COLLECT_ITEM = HOOK_COLLECT_ITEM,
- E_PLUGIN_BLOCK_DIG = HOOK_BLOCK_DIG,
- E_PLUGIN_BLOCK_PLACE = HOOK_BLOCK_PLACE,
- E_PLUGIN_DISCONNECT = HOOK_DISCONNECT,
- E_PLUGIN_HANDSHAKE = HOOK_HANDSHAKE,
- E_PLUGIN_LOGIN = HOOK_LOGIN,
- E_PLUGIN_PLAYER_SPAWN = HOOK_PLAYER_SPAWN,
- E_PLUGIN_PLAYER_JOIN = HOOK_PLAYER_JOIN,
- E_PLUGIN_PLAYER_MOVE = HOOK_PLAYER_MOVE,
- E_PLUGIN_TAKE_DAMAGE = HOOK_TAKE_DAMAGE,
- E_PLUGIN_KILLED = HOOK_KILLED,
- E_PLUGIN_CHUNK_GENERATED = HOOK_CHUNK_GENERATED,
- E_PLUGIN_CHUNK_GENERATING = HOOK_CHUNK_GENERATING,
- E_PLUGIN_BLOCK_TO_DROPS = HOOK_BLOCK_TO_DROPS,
- };
- // tolua_end
-
- static cPluginManager * GetPluginManager(); //tolua_export
-
- typedef std::list< cPlugin * > PluginList;
- cPlugin* GetPlugin( const char* a_Plugin ) const; //tolua_export
- const PluginList & GetAllPlugins() const; // >> EXPORTED IN MANUALBINDINGS <<
-
- void ReloadPlugins(); //tolua_export
- bool AddPlugin( cPlugin* a_Plugin );
- bool AddPlugin( lua_State* a_LuaState, cPlugin* a_Plugin ); //tolua_export
- bool AddLuaPlugin( cPlugin_Lua* a_Plugin );
- void AddHook( cPlugin* a_Plugin, PluginHook a_Hook ); //tolua_export
-
- unsigned int GetNumPlugins() const; //tolua_export
-
- bool CallHook( PluginHook a_Hook, unsigned int a_NumArgs, ... );
-
- bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
- bool CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
- bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
- bool CallHookBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups);
-
- void RemoveHooks( cPlugin* a_Plugin );
- void RemovePlugin( cPlugin* a_Plugin, bool a_bDelete = false ); //tolua_export
- void RemoveLuaPlugin( std::string a_FileName ); //tolua_export
- cPlugin_Lua* GetLuaPlugin( lua_State* a_State ); //tolua_export
-
- cLuaCommandBinder* GetLuaCommandBinder() const { return m_LuaCommandBinder; }
-
- bool HasPlugin( cPlugin* a_Plugin ) const;
-private:
- friend class cRoot;
- cPluginManager();
- ~cPluginManager();
-
- typedef std::list< cPlugin_Lua* > LuaPluginList;
- typedef std::map< cPluginManager::PluginHook, cPluginManager::PluginList > HookMap;
-
- LuaPluginList m_LuaPlugins;
- PluginList m_Plugins;
- HookMap m_Hooks;
-
- void ReloadPluginsNow();
- void UnloadPluginsNow();
-
- cLuaCommandBinder* m_LuaCommandBinder;
-
- bool m_bReloadPlugins;
-}; //tolua_export
+ +#pragma once + +#include "cItem.h" + +struct lua_State; +class cLuaCommandBinder; +class cPlugin; +class cPlugin_Lua; + +// fwd: cPlayer.h +class cPlayer; + +// fwd: CraftingRecipes.h +class cCraftingGrid; +class cCraftingRecipe; + + + + + +class cPluginManager //tolua_export +{ //tolua_export +public: //tolua_export + + // Called each tick + virtual void Tick(float a_Dt); + + // tolua_begin + enum PluginHook + { + HOOK_TICK, + HOOK_CHAT, + HOOK_COLLECT_ITEM, + HOOK_BLOCK_DIG, + HOOK_BLOCK_PLACE, + HOOK_DISCONNECT, + HOOK_HANDSHAKE, + HOOK_LOGIN, + HOOK_PLAYER_SPAWN, + HOOK_PLAYER_JOIN, + HOOK_PLAYER_MOVE, + HOOK_TAKE_DAMAGE, + HOOK_KILLED, + HOOK_CHUNK_GENERATED, + HOOK_CHUNK_GENERATING, + HOOK_BLOCK_TO_DROPS, + HOOK_PRE_CRAFTING, /// cPlayer, cCraftingGrid, cCraftingRecipe + HOOK_CRAFTING_NO_RECIPE, /// cPlayer, cCraftingGrid, cCraftingRecipe + HOOK_POST_CRAFTING, /// cPlayer, cCraftingGrid, cCraftingRecipe + HOOK_BLOCK_TO_PICKUP, /// BlockType, BlockMeta, cPlayer, cItem, cItems + HOOK_WEATHER_CHANGE, + + // E_PLUGIN_ names are obsolete, but are kept for compatibility reasons + E_PLUGIN_TICK = HOOK_TICK, + E_PLUGIN_CHAT = HOOK_CHAT, + E_PLUGIN_COLLECT_ITEM = HOOK_COLLECT_ITEM, + E_PLUGIN_BLOCK_DIG = HOOK_BLOCK_DIG, + E_PLUGIN_BLOCK_PLACE = HOOK_BLOCK_PLACE, + E_PLUGIN_DISCONNECT = HOOK_DISCONNECT, + E_PLUGIN_HANDSHAKE = HOOK_HANDSHAKE, + E_PLUGIN_LOGIN = HOOK_LOGIN, + E_PLUGIN_PLAYER_SPAWN = HOOK_PLAYER_SPAWN, + E_PLUGIN_PLAYER_JOIN = HOOK_PLAYER_JOIN, + E_PLUGIN_PLAYER_MOVE = HOOK_PLAYER_MOVE, + E_PLUGIN_TAKE_DAMAGE = HOOK_TAKE_DAMAGE, + E_PLUGIN_KILLED = HOOK_KILLED, + E_PLUGIN_CHUNK_GENERATED = HOOK_CHUNK_GENERATED, + E_PLUGIN_CHUNK_GENERATING = HOOK_CHUNK_GENERATING, + E_PLUGIN_BLOCK_TO_DROPS = HOOK_BLOCK_TO_DROPS, + }; + // tolua_end + + static cPluginManager * GetPluginManager(); //tolua_export + + typedef std::list< cPlugin * > PluginList; + cPlugin* GetPlugin( const char* a_Plugin ) const; //tolua_export + const PluginList & GetAllPlugins() const; // >> EXPORTED IN MANUALBINDINGS << + + void ReloadPlugins(); //tolua_export + bool AddPlugin( cPlugin* a_Plugin ); + bool AddPlugin( lua_State* a_LuaState, cPlugin* a_Plugin ); //tolua_export + bool AddLuaPlugin( cPlugin_Lua* a_Plugin ); + void AddHook( cPlugin* a_Plugin, PluginHook a_Hook ); //tolua_export + + unsigned int GetNumPlugins() const; //tolua_export + + bool CallHook( PluginHook a_Hook, unsigned int a_NumArgs, ... ); + + bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); + bool CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); + bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); + bool CallHookBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups); + + void RemoveHooks( cPlugin* a_Plugin ); + void RemovePlugin( cPlugin* a_Plugin, bool a_bDelete = false ); //tolua_export + void RemoveLuaPlugin( std::string a_FileName ); //tolua_export + cPlugin_Lua* GetLuaPlugin( lua_State* a_State ); //tolua_export + + cLuaCommandBinder* GetLuaCommandBinder() const { return m_LuaCommandBinder; } + + bool HasPlugin( cPlugin* a_Plugin ) const; +private: + friend class cRoot; + cPluginManager(); + ~cPluginManager(); + + typedef std::list< cPlugin_Lua* > LuaPluginList; + typedef std::map< cPluginManager::PluginHook, cPluginManager::PluginList > HookMap; + + LuaPluginList m_LuaPlugins; + PluginList m_Plugins; + HookMap m_Hooks; + + void ReloadPluginsNow(); + void UnloadPluginsNow(); + + cLuaCommandBinder* m_LuaCommandBinder; + + bool m_bReloadPlugins; +}; //tolua_export diff --git a/source/cPlugin_Lua.cpp b/source/cPlugin_Lua.cpp index d25df0242..a4cf972f4 100644 --- a/source/cPlugin_Lua.cpp +++ b/source/cPlugin_Lua.cpp @@ -1,98 +1,98 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#define LUA_USE_POSIX
-#include "cPlugin_Lua.h"
-#include "cPluginManager.h"
-#include "cRoot.h"
-
-extern "C"
-{
- #include "lualib.h"
-}
-
-#include "tolua++.h"
-#include "Bindings.h"
-#include "ManualBindings.h"
-
-bool report_errors(lua_State* lua, int status)
-{
- if ( status!=0 )
- {
- std::string s = lua_tostring(lua, -1);
- LOGERROR("-- %s", s.c_str() );
- lua_pop(lua, 1);
- return true;
- }
- return false;
-}
-
-cPlugin_Lua::~cPlugin_Lua()
-{
- UnloadPlugins();
- if( m_LuaState )
- {
- lua_close( m_LuaState );
- m_LuaState = 0;
- }
-}
-
-cPlugin_Lua::cPlugin_Lua(const char* a_Plugin)
-: m_LuaState( 0 )
-{
- m_FileName.assign( a_Plugin );
-}
-
-bool cPlugin_Lua::Initialize()
-{
- if( !m_LuaState )
- {
- m_LuaState = lua_open();
- luaL_openlibs( m_LuaState );
- tolua_AllToLua_open(m_LuaState);
- ManualBindings::Bind( m_LuaState );
- }
-
- int s = luaL_loadfile(m_LuaState, (std::string("Plugins/") + m_FileName ).c_str() );
- if( report_errors( m_LuaState, s ) )
- {
- LOGERROR("Can't load plugin %s", m_FileName.c_str() );
- lua_close( m_LuaState );
- m_LuaState = 0;
- return false;
- }
-
- s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0);
- if( report_errors( m_LuaState, s ) )
- {
- LOGERROR("Error in plugin %s", m_FileName.c_str() );
- lua_close( m_LuaState );
- m_LuaState = 0;
- return false;
- }
- return true;
-}
-
-void cPlugin_Lua::AddPlugin( cPlugin* a_Plugin )
-{
- m_Plugins.push_back( a_Plugin );
-}
-
-void cPlugin_Lua::RemovePlugin( cPlugin* a_Plugin )
-{
- m_Plugins.remove( a_Plugin );
- cRoot::Get()->GetPluginManager()->RemovePlugin( a_Plugin, true );
-}
-
-void cPlugin_Lua::UnloadPlugins()
-{
- while( m_Plugins.begin() != m_Plugins.end() )
- {
- RemovePlugin( *m_Plugins.begin() );
- }
-}
-
-lua_State* cPlugin_Lua::GetLuaState()
-{
- return m_LuaState;
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#define LUA_USE_POSIX +#include "cPlugin_Lua.h" +#include "cPluginManager.h" +#include "cRoot.h" + +extern "C" +{ + #include "lualib.h" +} + +#include "tolua++.h" +#include "Bindings.h" +#include "ManualBindings.h" + +bool report_errors(lua_State* lua, int status) +{ + if ( status!=0 ) + { + std::string s = lua_tostring(lua, -1); + LOGERROR("-- %s", s.c_str() ); + lua_pop(lua, 1); + return true; + } + return false; +} + +cPlugin_Lua::~cPlugin_Lua() +{ + UnloadPlugins(); + if( m_LuaState ) + { + lua_close( m_LuaState ); + m_LuaState = 0; + } +} + +cPlugin_Lua::cPlugin_Lua(const char* a_Plugin) +: m_LuaState( 0 ) +{ + m_FileName.assign( a_Plugin ); +} + +bool cPlugin_Lua::Initialize() +{ + if( !m_LuaState ) + { + m_LuaState = lua_open(); + luaL_openlibs( m_LuaState ); + tolua_AllToLua_open(m_LuaState); + ManualBindings::Bind( m_LuaState ); + } + + int s = luaL_loadfile(m_LuaState, (std::string("Plugins/") + m_FileName ).c_str() ); + if( report_errors( m_LuaState, s ) ) + { + LOGERROR("Can't load plugin %s", m_FileName.c_str() ); + lua_close( m_LuaState ); + m_LuaState = 0; + return false; + } + + s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); + if( report_errors( m_LuaState, s ) ) + { + LOGERROR("Error in plugin %s", m_FileName.c_str() ); + lua_close( m_LuaState ); + m_LuaState = 0; + return false; + } + return true; +} + +void cPlugin_Lua::AddPlugin( cPlugin* a_Plugin ) +{ + m_Plugins.push_back( a_Plugin ); +} + +void cPlugin_Lua::RemovePlugin( cPlugin* a_Plugin ) +{ + m_Plugins.remove( a_Plugin ); + cRoot::Get()->GetPluginManager()->RemovePlugin( a_Plugin, true ); +} + +void cPlugin_Lua::UnloadPlugins() +{ + while( m_Plugins.begin() != m_Plugins.end() ) + { + RemovePlugin( *m_Plugins.begin() ); + } +} + +lua_State* cPlugin_Lua::GetLuaState() +{ + return m_LuaState; }
\ No newline at end of file diff --git a/source/cPlugin_Lua.h b/source/cPlugin_Lua.h index 1ce582a29..6e5d027d4 100644 --- a/source/cPlugin_Lua.h +++ b/source/cPlugin_Lua.h @@ -1,32 +1,32 @@ -
-#pragma once
-
-class cPickup;
-class cPlayer;
-class cPacket_BlockPlace;
-class cPacket_BlockDig;
-class cPacket_Login;
-class cPlugin;
-class cPlugin_Lua //tolua_export
-{ //tolua_export
-public:
- cPlugin_Lua(const char* a_Plugin);
- ~cPlugin_Lua();
-
- virtual bool Initialize();
-
- std::string GetFileName() { return m_FileName; } //tolua_export
- typedef struct lua_State lua_State;
- lua_State* GetLuaState();
-
- void AddPlugin( cPlugin* a_Plugin );
- void RemovePlugin( cPlugin* a_Plugin );
-private:
- void UnloadPlugins();
-
- std::string m_FileName;
- lua_State* m_LuaState;
-
- typedef std::list< cPlugin* > PluginList;
- PluginList m_Plugins;
+ +#pragma once + +class cPickup; +class cPlayer; +class cPacket_BlockPlace; +class cPacket_BlockDig; +class cPacket_Login; +class cPlugin; +class cPlugin_Lua //tolua_export +{ //tolua_export +public: + cPlugin_Lua(const char* a_Plugin); + ~cPlugin_Lua(); + + virtual bool Initialize(); + + std::string GetFileName() { return m_FileName; } //tolua_export + typedef struct lua_State lua_State; + lua_State* GetLuaState(); + + void AddPlugin( cPlugin* a_Plugin ); + void RemovePlugin( cPlugin* a_Plugin ); +private: + void UnloadPlugins(); + + std::string m_FileName; + lua_State* m_LuaState; + + typedef std::list< cPlugin* > PluginList; + PluginList m_Plugins; }; //tolua_export
\ No newline at end of file diff --git a/source/cPlugin_NewLua.cpp b/source/cPlugin_NewLua.cpp index ae79ebd3c..92764a368 100644 --- a/source/cPlugin_NewLua.cpp +++ b/source/cPlugin_NewLua.cpp @@ -1,551 +1,551 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#define LUA_USE_POSIX
-#include "cPlugin_NewLua.h"
-#include "cMCLogger.h"
-#include "cWebPlugin_Lua.h"
-#include "LuaItems.h"
-
-extern "C"
-{
-#include "lualib.h"
-}
-
-#include "tolua++.h"
-#include "Bindings.h"
-#include "ManualBindings.h"
-
-#ifdef _WIN32
-// #include "wdirent.h"
-#else
-#include <dirent.h>
-#endif
-
-
-
-
-
-extern bool report_errors(lua_State* lua, int status);
-
-
-
-
-
-cPlugin_NewLua::cPlugin_NewLua( const char* a_PluginName )
- : m_LuaState( 0 )
-{
- m_Directory = a_PluginName;
-}
-
-
-
-
-
-cPlugin_NewLua::~cPlugin_NewLua()
-{
- cCSLock Lock( m_CriticalSection );
- for( WebPluginList::iterator itr = m_WebPlugins.begin(); itr != m_WebPlugins.end(); ++itr )
- {
- delete *itr;
- }
- m_WebPlugins.clear();
-
- if( m_LuaState )
- {
- lua_close( m_LuaState );
- m_LuaState = 0;
- }
-}
-
-
-
-
-
-bool cPlugin_NewLua::Initialize()
-{
- cCSLock Lock( m_CriticalSection );
- if( !m_LuaState )
- {
- m_LuaState = lua_open();
- luaL_openlibs( m_LuaState );
- tolua_AllToLua_open(m_LuaState);
- ManualBindings::Bind( m_LuaState );
- }
-
- std::string PluginPath = std::string("Plugins/") + m_Directory + "/";
-
- // Load all files for this plugin, and execute them
- AStringList Files = GetDirectoryContents(PluginPath.c_str());
- for (AStringList::const_iterator itr = Files.begin(); itr != Files.end(); ++itr)
- {
- if (itr->rfind(".lua") == AString::npos)
- {
- continue;
- }
- AString Path = PluginPath + *itr;
- int s = luaL_loadfile(m_LuaState, Path.c_str() );
- if( report_errors( m_LuaState, s ) )
- {
- LOGERROR("Can't load plugin %s because of an error in file %s", m_Directory.c_str(), Path.c_str() );
- lua_close( m_LuaState );
- m_LuaState = 0;
- return false;
- }
-
- s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0);
- if( report_errors( m_LuaState, s ) )
- {
- LOGERROR("Error in plugin %s in file %s", m_Directory.c_str(), Path.c_str() );
- lua_close( m_LuaState );
- m_LuaState = 0;
- return false;
- }
- } // for itr - Files[]
-
- // Call intialize function
- if( !PushFunction("Initialize") )
- {
- lua_close( m_LuaState );
- m_LuaState = 0;
- return false;
- }
-
- tolua_pushusertype(m_LuaState, this, "cPlugin_NewLua");
-
- if( !CallFunction(1, 1, "Initialize") )
- {
- lua_close( m_LuaState );
- m_LuaState = 0;
- return false;
- }
-
- if( !lua_isboolean( m_LuaState, -1 ) )
- {
- LOGWARN("Error in plugin %s Initialize() must return a boolean value!", m_Directory.c_str() );
- lua_close( m_LuaState );
- m_LuaState = 0;
- return false;
- }
-
- bool bSuccess = (tolua_toboolean( m_LuaState, -1, 0) > 0);
- return bSuccess;
-}
-
-
-
-
-
-void cPlugin_NewLua::OnDisable()
-{
- cCSLock Lock( m_CriticalSection );
- if( !PushFunction("OnDisable", false) ) // false = don't log error if not found
- return;
-
- CallFunction(0, 0, "OnDisable");
-}
-
-
-
-
-
-void cPlugin_NewLua::Tick(float a_Dt)
-{
- cCSLock Lock( m_CriticalSection );
- if( !PushFunction("Tick") )
- return;
-
- tolua_pushnumber( m_LuaState, a_Dt );
-
- CallFunction(1, 0, "Tick");
-}
-
-
-
-
-
-bool cPlugin_NewLua::OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player )
-{
- cCSLock Lock( m_CriticalSection );
- if( !PushFunction("OnCollectItem") )
- return false;
-
- tolua_pushusertype(m_LuaState, a_Pickup, "cPickup");
- tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
-
- if( !CallFunction(2, 1, "OnCollectItem") )
- return false;
-
- bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
- return bRetVal;
-}
-
-
-
-
-
-bool cPlugin_NewLua::OnDisconnect(const AString & a_Reason, cPlayer* a_Player )
-{
- cCSLock Lock( m_CriticalSection );
- if( !PushFunction("OnDisconnect") )
- return false;
-
- tolua_pushstring( m_LuaState, a_Reason.c_str() );
- tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
-
- if( !CallFunction(2, 1, "OnDisconnect") )
- return false;
-
- bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
- return bRetVal;
-}
-
-
-
-
-
-bool cPlugin_NewLua::OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player )
-{
- cCSLock Lock( m_CriticalSection );
- if( !PushFunction("OnBlockPlace") )
- return false;
-
- tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_BlockPlace");
- tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
-
- if( !CallFunction(2, 1, "OnBlockPlace") )
- return false;
-
- bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
- return bRetVal;
-}
-
-
-
-
-
-bool cPlugin_NewLua::OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem )
-{
- cCSLock Lock( m_CriticalSection );
- if( !PushFunction("OnBlockDig") )
- return false;
-
- tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_BlockDig");
- tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
- tolua_pushusertype(m_LuaState, a_PickupItem, "cItem");
-
- if( !CallFunction(3, 1, "OnBlockDig") )
- return false;
-
- bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
- return bRetVal;
-}
-
-
-
-
-
-bool cPlugin_NewLua::OnChat( const char* a_Chat, cPlayer* a_Player )
-{
- cCSLock Lock( m_CriticalSection );
- if( !PushFunction("OnChat") )
- return false;
-
- tolua_pushstring( m_LuaState, a_Chat );
- tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
-
- if( !CallFunction(2, 1, "OnChat") )
- return false;
-
- bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
- return bRetVal;
-}
-
-
-
-
-
-bool cPlugin_NewLua::OnLogin( cPacket_Login* a_PacketData )
-{
- cCSLock Lock( m_CriticalSection );
- if( !PushFunction("OnLogin") )
- return false;
-
- tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_Login");
-
- if( !CallFunction(1, 1, "OnLogin") )
- return false;
-
- bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
- return bRetVal;
-}
-
-
-
-
-
-void cPlugin_NewLua::OnPlayerSpawn( cPlayer* a_Player )
-{
- cCSLock Lock( m_CriticalSection );
- if( !PushFunction("OnPlayerSpawn") )
- return;
-
- tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
-
- CallFunction(1, 0, "OnPlayerSpawn");
-}
-
-
-
-
-
-bool cPlugin_NewLua::OnPlayerJoin( cPlayer* a_Player )
-{
- cCSLock Lock( m_CriticalSection );
- if( !PushFunction("OnPlayerJoin") )
- return false;
-
- tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
-
- if( !CallFunction(1, 1, "OnPlayerJoin") )
- return false;
-
- bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
- return bRetVal;
-}
-
-
-
-
-
-void cPlugin_NewLua::OnPlayerMove( cPlayer* a_Player )
-{
- cCSLock Lock( m_CriticalSection );
- if( !PushFunction("OnPlayerMove") )
- return;
-
- tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
-
- CallFunction(1, 0, "OnPlayerMove");
-}
-
-
-
-
-
-void cPlugin_NewLua::OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo )
-{
- cCSLock Lock( m_CriticalSection );
- if( !PushFunction("OnTakeDamage") )
- return;
-
- tolua_pushusertype(m_LuaState, a_Pawn, "cPawn");
- tolua_pushusertype(m_LuaState, a_TakeDamageInfo, "TakeDamageInfo");
-
- CallFunction(2, 0, "OnTakeDamage");
-}
-
-
-
-
-
-bool cPlugin_NewLua::OnKilled( cPawn* a_Killed, cEntity* a_Killer )
-{
- cCSLock Lock( m_CriticalSection );
- if( !PushFunction("OnKilled") )
- return false;
-
- tolua_pushusertype(m_LuaState, a_Killed, "cPawn");
- tolua_pushusertype(m_LuaState, a_Killer, "cEntity");
-
- if( !CallFunction(2, 1, "OnKilled") )
- return false;
-
- bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
- return bRetVal;
-}
-
-
-
-
-
-void cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ)
-{
- cCSLock Lock(m_CriticalSection);
- if (!PushFunction("OnChunkGenerated"))
- {
- return;
- }
-
- tolua_pushusertype(m_LuaState, a_World, "cWorld");
- tolua_pushnumber (m_LuaState, a_ChunkX);
- tolua_pushnumber (m_LuaState, a_ChunkZ);
-
- CallFunction(3, 0, "OnChunkGenerated");
-}
-
-
-
-
-
-bool cPlugin_NewLua::OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk )
-{
- cCSLock Lock(m_CriticalSection);
- if (!PushFunction("OnChunkGenerating"))
- return false;
-
- tolua_pushnumber (m_LuaState, a_ChunkX);
- tolua_pushnumber (m_LuaState, a_ChunkZ);
- tolua_pushusertype(m_LuaState, a_pLuaChunk, "cLuaChunk");
-
- if( !CallFunction(3, 1, "OnChunkGenerating") )
- return false;
-
- bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
- return bRetVal;
-}
-
-
-
-
-
-bool cPlugin_NewLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
-{
- cCSLock Lock(m_CriticalSection);
- if (!PushFunction("OnPreCrafting"))
- return false;
-
- tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer");
- tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid");
- tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe");
-
- if (!CallFunction(3, 1, "OnPreCrafting"))
- {
- return false;
- }
-
- bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
- return bRetVal;
-}
-
-
-
-
-
-bool cPlugin_NewLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
-{
- cCSLock Lock(m_CriticalSection);
- if (!PushFunction("OnCraftingNoRecipe"))
- return false;
-
- tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer");
- tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid");
- tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe");
-
- if (!CallFunction(3, 1, "OnCraftingNoRecipe"))
- {
- return false;
- }
-
- bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
- return bRetVal;
-}
-
-
-
-
-
-bool cPlugin_NewLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
-{
- cCSLock Lock(m_CriticalSection);
- if (!PushFunction("OnPostCrafting"))
- return false;
-
- tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer");
- tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid");
- tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe");
-
- if (!CallFunction(3, 1, "OnPostCrafting"))
- {
- return false;
- }
-
- bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
- return bRetVal;
-}
-
-
-
-
-
-bool cPlugin_NewLua::OnBlockToPickup(
- BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta,
- const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups
-)
-{
- cLuaItems Pickups(a_Pickups);
- cCSLock Lock(m_CriticalSection);
- if (!PushFunction("OnBlockToPickup"))
- return false;
-
- tolua_pushnumber (m_LuaState, a_BlockType);
- tolua_pushnumber (m_LuaState, a_BlockMeta);
- tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer");
- tolua_pushusertype(m_LuaState, (void *)&a_EquippedItem, "cItem");
- tolua_pushusertype(m_LuaState, (void *)&Pickups, "cLuaItems");
-
- if (!CallFunction(5, 1, "OnBlockToPickup"))
- {
- return false;
- }
-
- bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
- return bRetVal;
-}
-
-
-
-
-
-cWebPlugin_Lua* cPlugin_NewLua::CreateWebPlugin(lua_State* a_LuaState)
-{
- cCSLock Lock( m_CriticalSection );
- if( a_LuaState != m_LuaState )
- {
- LOGERROR("Not allowed to create a WebPlugin from another plugin but your own!");
- return 0;
- }
- cWebPlugin_Lua* WebPlugin = new cWebPlugin_Lua( this );
-
- m_WebPlugins.push_back( WebPlugin );
-
- return WebPlugin;
-}
-
-
-// Helper functions
-bool cPlugin_NewLua::PushFunction( const char* a_FunctionName, bool a_bLogError /* = true */ )
-{
- lua_getglobal(m_LuaState, a_FunctionName);
- if(!lua_isfunction(m_LuaState,-1))
- {
- if( a_bLogError )
- {
- LOGWARN("Error in plugin %s: Could not find function %s()", m_Directory.c_str(), a_FunctionName );
- }
- lua_pop(m_LuaState,1);
- return false;
- }
- return true;
-}
-
-bool cPlugin_NewLua::CallFunction( int a_NumArgs, int a_NumResults, const char* a_FunctionName )
-{
- int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0);
- if( report_errors( m_LuaState, s ) )
- {
- LOGWARN("Error in plugin %s calling function %s()", m_Directory.c_str(), a_FunctionName );
- return false;
- }
- return true;
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#define LUA_USE_POSIX +#include "cPlugin_NewLua.h" +#include "cMCLogger.h" +#include "cWebPlugin_Lua.h" +#include "LuaItems.h" + +extern "C" +{ +#include "lualib.h" +} + +#include "tolua++.h" +#include "Bindings.h" +#include "ManualBindings.h" + +#ifdef _WIN32 +// #include "wdirent.h" +#else +#include <dirent.h> +#endif + + + + + +extern bool report_errors(lua_State* lua, int status); + + + + + +cPlugin_NewLua::cPlugin_NewLua( const char* a_PluginName ) + : m_LuaState( 0 ) +{ + m_Directory = a_PluginName; +} + + + + + +cPlugin_NewLua::~cPlugin_NewLua() +{ + cCSLock Lock( m_CriticalSection ); + for( WebPluginList::iterator itr = m_WebPlugins.begin(); itr != m_WebPlugins.end(); ++itr ) + { + delete *itr; + } + m_WebPlugins.clear(); + + if( m_LuaState ) + { + lua_close( m_LuaState ); + m_LuaState = 0; + } +} + + + + + +bool cPlugin_NewLua::Initialize() +{ + cCSLock Lock( m_CriticalSection ); + if( !m_LuaState ) + { + m_LuaState = lua_open(); + luaL_openlibs( m_LuaState ); + tolua_AllToLua_open(m_LuaState); + ManualBindings::Bind( m_LuaState ); + } + + std::string PluginPath = std::string("Plugins/") + m_Directory + "/"; + + // Load all files for this plugin, and execute them + AStringList Files = GetDirectoryContents(PluginPath.c_str()); + for (AStringList::const_iterator itr = Files.begin(); itr != Files.end(); ++itr) + { + if (itr->rfind(".lua") == AString::npos) + { + continue; + } + AString Path = PluginPath + *itr; + int s = luaL_loadfile(m_LuaState, Path.c_str() ); + if( report_errors( m_LuaState, s ) ) + { + LOGERROR("Can't load plugin %s because of an error in file %s", m_Directory.c_str(), Path.c_str() ); + lua_close( m_LuaState ); + m_LuaState = 0; + return false; + } + + s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); + if( report_errors( m_LuaState, s ) ) + { + LOGERROR("Error in plugin %s in file %s", m_Directory.c_str(), Path.c_str() ); + lua_close( m_LuaState ); + m_LuaState = 0; + return false; + } + } // for itr - Files[] + + // Call intialize function + if( !PushFunction("Initialize") ) + { + lua_close( m_LuaState ); + m_LuaState = 0; + return false; + } + + tolua_pushusertype(m_LuaState, this, "cPlugin_NewLua"); + + if( !CallFunction(1, 1, "Initialize") ) + { + lua_close( m_LuaState ); + m_LuaState = 0; + return false; + } + + if( !lua_isboolean( m_LuaState, -1 ) ) + { + LOGWARN("Error in plugin %s Initialize() must return a boolean value!", m_Directory.c_str() ); + lua_close( m_LuaState ); + m_LuaState = 0; + return false; + } + + bool bSuccess = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bSuccess; +} + + + + + +void cPlugin_NewLua::OnDisable() +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnDisable", false) ) // false = don't log error if not found + return; + + CallFunction(0, 0, "OnDisable"); +} + + + + + +void cPlugin_NewLua::Tick(float a_Dt) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("Tick") ) + return; + + tolua_pushnumber( m_LuaState, a_Dt ); + + CallFunction(1, 0, "Tick"); +} + + + + + +bool cPlugin_NewLua::OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnCollectItem") ) + return false; + + tolua_pushusertype(m_LuaState, a_Pickup, "cPickup"); + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + + if( !CallFunction(2, 1, "OnCollectItem") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnDisconnect(const AString & a_Reason, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnDisconnect") ) + return false; + + tolua_pushstring( m_LuaState, a_Reason.c_str() ); + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + + if( !CallFunction(2, 1, "OnDisconnect") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnBlockPlace") ) + return false; + + tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_BlockPlace"); + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + + if( !CallFunction(2, 1, "OnBlockPlace") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnBlockDig") ) + return false; + + tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_BlockDig"); + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + tolua_pushusertype(m_LuaState, a_PickupItem, "cItem"); + + if( !CallFunction(3, 1, "OnBlockDig") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnChat( const char* a_Chat, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnChat") ) + return false; + + tolua_pushstring( m_LuaState, a_Chat ); + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + + if( !CallFunction(2, 1, "OnChat") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnLogin( cPacket_Login* a_PacketData ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnLogin") ) + return false; + + tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_Login"); + + if( !CallFunction(1, 1, "OnLogin") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +void cPlugin_NewLua::OnPlayerSpawn( cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnPlayerSpawn") ) + return; + + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + + CallFunction(1, 0, "OnPlayerSpawn"); +} + + + + + +bool cPlugin_NewLua::OnPlayerJoin( cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnPlayerJoin") ) + return false; + + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + + if( !CallFunction(1, 1, "OnPlayerJoin") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +void cPlugin_NewLua::OnPlayerMove( cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnPlayerMove") ) + return; + + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + + CallFunction(1, 0, "OnPlayerMove"); +} + + + + + +void cPlugin_NewLua::OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnTakeDamage") ) + return; + + tolua_pushusertype(m_LuaState, a_Pawn, "cPawn"); + tolua_pushusertype(m_LuaState, a_TakeDamageInfo, "TakeDamageInfo"); + + CallFunction(2, 0, "OnTakeDamage"); +} + + + + + +bool cPlugin_NewLua::OnKilled( cPawn* a_Killed, cEntity* a_Killer ) +{ + cCSLock Lock( m_CriticalSection ); + if( !PushFunction("OnKilled") ) + return false; + + tolua_pushusertype(m_LuaState, a_Killed, "cPawn"); + tolua_pushusertype(m_LuaState, a_Killer, "cEntity"); + + if( !CallFunction(2, 1, "OnKilled") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +void cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +{ + cCSLock Lock(m_CriticalSection); + if (!PushFunction("OnChunkGenerated")) + { + return; + } + + tolua_pushusertype(m_LuaState, a_World, "cWorld"); + tolua_pushnumber (m_LuaState, a_ChunkX); + tolua_pushnumber (m_LuaState, a_ChunkZ); + + CallFunction(3, 0, "OnChunkGenerated"); +} + + + + + +bool cPlugin_NewLua::OnChunkGenerating( int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) +{ + cCSLock Lock(m_CriticalSection); + if (!PushFunction("OnChunkGenerating")) + return false; + + tolua_pushnumber (m_LuaState, a_ChunkX); + tolua_pushnumber (m_LuaState, a_ChunkZ); + tolua_pushusertype(m_LuaState, a_pLuaChunk, "cLuaChunk"); + + if( !CallFunction(3, 1, "OnChunkGenerating") ) + return false; + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + cCSLock Lock(m_CriticalSection); + if (!PushFunction("OnPreCrafting")) + return false; + + tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); + tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); + tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); + + if (!CallFunction(3, 1, "OnPreCrafting")) + { + return false; + } + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + cCSLock Lock(m_CriticalSection); + if (!PushFunction("OnCraftingNoRecipe")) + return false; + + tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); + tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); + tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); + + if (!CallFunction(3, 1, "OnCraftingNoRecipe")) + { + return false; + } + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + cCSLock Lock(m_CriticalSection); + if (!PushFunction("OnPostCrafting")) + return false; + + tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); + tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); + tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); + + if (!CallFunction(3, 1, "OnPostCrafting")) + { + return false; + } + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnBlockToPickup( + BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, + const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups +) +{ + cLuaItems Pickups(a_Pickups); + cCSLock Lock(m_CriticalSection); + if (!PushFunction("OnBlockToPickup")) + return false; + + tolua_pushnumber (m_LuaState, a_BlockType); + tolua_pushnumber (m_LuaState, a_BlockMeta); + tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); + tolua_pushusertype(m_LuaState, (void *)&a_EquippedItem, "cItem"); + tolua_pushusertype(m_LuaState, (void *)&Pickups, "cLuaItems"); + + if (!CallFunction(5, 1, "OnBlockToPickup")) + { + return false; + } + + bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); + return bRetVal; +} + + + + + +cWebPlugin_Lua* cPlugin_NewLua::CreateWebPlugin(lua_State* a_LuaState) +{ + cCSLock Lock( m_CriticalSection ); + if( a_LuaState != m_LuaState ) + { + LOGERROR("Not allowed to create a WebPlugin from another plugin but your own!"); + return 0; + } + cWebPlugin_Lua* WebPlugin = new cWebPlugin_Lua( this ); + + m_WebPlugins.push_back( WebPlugin ); + + return WebPlugin; +} + + +// Helper functions +bool cPlugin_NewLua::PushFunction( const char* a_FunctionName, bool a_bLogError /* = true */ ) +{ + lua_getglobal(m_LuaState, a_FunctionName); + if(!lua_isfunction(m_LuaState,-1)) + { + if( a_bLogError ) + { + LOGWARN("Error in plugin %s: Could not find function %s()", m_Directory.c_str(), a_FunctionName ); + } + lua_pop(m_LuaState,1); + return false; + } + return true; +} + +bool cPlugin_NewLua::CallFunction( int a_NumArgs, int a_NumResults, const char* a_FunctionName ) +{ + int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0); + if( report_errors( m_LuaState, s ) ) + { + LOGWARN("Error in plugin %s calling function %s()", m_Directory.c_str(), a_FunctionName ); + return false; + } + return true; }
\ No newline at end of file diff --git a/source/cPlugin_NewLua.h b/source/cPlugin_NewLua.h index d6bb50637..e66c26e3f 100644 --- a/source/cPlugin_NewLua.h +++ b/source/cPlugin_NewLua.h @@ -1,60 +1,60 @@ -
-#pragma once
-
-#include "cPlugin.h"
-
-
-
-
-
-typedef struct lua_State lua_State;
-class cWebPlugin_Lua;
-
-
-
-
-
-class cPlugin_NewLua : public cPlugin //tolua_export
-{ //tolua_export
-public: //tolua_export
- cPlugin_NewLua( const char* a_PluginName );
- ~cPlugin_NewLua();
-
- virtual void OnDisable(); //tolua_export
- virtual bool Initialize(); //tolua_export
-
- virtual void Tick(float a_Dt); //tolua_export
-
- virtual bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ) override;
- virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ) override;
- virtual bool OnBlockPlace (cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) override;
- virtual bool OnBlockDig (cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) override;
- virtual bool OnChat (const char* a_Chat, cPlayer* a_Player ) override;
- virtual bool OnLogin (cPacket_Login* a_PacketData ) override;
- virtual void OnPlayerSpawn (cPlayer* a_Player ) override;
- virtual bool OnPlayerJoin (cPlayer* a_Player ) override;
- virtual void OnPlayerMove (cPlayer* a_Player ) override;
- virtual void OnTakeDamage (cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) override;
- virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) override;
- virtual void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override;
- virtual bool OnChunkGenerating (int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) override;
- virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
- virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
- virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
- virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups);
-
- lua_State* GetLuaState() { return m_LuaState; }
-
- cWebPlugin_Lua* CreateWebPlugin(lua_State* a_LuaState); //tolua_export
-private:
- bool PushFunction( const char* a_FunctionName, bool a_bLogError = true );
- bool CallFunction( int a_NumArgs, int a_NumResults, const char* a_FunctionName ); // a_FunctionName is only used for error messages, nothing else
-
- typedef std::list< cWebPlugin_Lua* > WebPluginList;
- WebPluginList m_WebPlugins;
-
- cCriticalSection m_CriticalSection;
-
- std::string m_Directory;
- lua_State* m_LuaState;
+ +#pragma once + +#include "cPlugin.h" + + + + + +typedef struct lua_State lua_State; +class cWebPlugin_Lua; + + + + + +class cPlugin_NewLua : public cPlugin //tolua_export +{ //tolua_export +public: //tolua_export + cPlugin_NewLua( const char* a_PluginName ); + ~cPlugin_NewLua(); + + virtual void OnDisable(); //tolua_export + virtual bool Initialize(); //tolua_export + + virtual void Tick(float a_Dt); //tolua_export + + virtual bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ) override; + virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ) override; + virtual bool OnBlockPlace (cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) override; + virtual bool OnBlockDig (cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) override; + virtual bool OnChat (const char* a_Chat, cPlayer* a_Player ) override; + virtual bool OnLogin (cPacket_Login* a_PacketData ) override; + virtual void OnPlayerSpawn (cPlayer* a_Player ) override; + virtual bool OnPlayerJoin (cPlayer* a_Player ) override; + virtual void OnPlayerMove (cPlayer* a_Player ) override; + virtual void OnTakeDamage (cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) override; + virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) override; + virtual void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; + virtual bool OnChunkGenerating (int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) override; + virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups); + + lua_State* GetLuaState() { return m_LuaState; } + + cWebPlugin_Lua* CreateWebPlugin(lua_State* a_LuaState); //tolua_export +private: + bool PushFunction( const char* a_FunctionName, bool a_bLogError = true ); + bool CallFunction( int a_NumArgs, int a_NumResults, const char* a_FunctionName ); // a_FunctionName is only used for error messages, nothing else + + typedef std::list< cWebPlugin_Lua* > WebPluginList; + WebPluginList m_WebPlugins; + + cCriticalSection m_CriticalSection; + + std::string m_Directory; + lua_State* m_LuaState; };//tolua_export
\ No newline at end of file diff --git a/source/cRedstone.cpp b/source/cRedstone.cpp index 5a1c9bc8b..701835d5a 100644 --- a/source/cRedstone.cpp +++ b/source/cRedstone.cpp @@ -1,374 +1,374 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cRedstone.h"
-#include "cPiston.h"
-#include "cRoot.h"
-#include "cWorld.h"
-#include "BlockID.h"
-#include <iostream>
-
-
-
-
-
-bool cRedstone::s_UseRedstone = false;
-
-
-
-
-
-cRedstone::cRedstone( cWorld* a_World )
- :m_World ( a_World )
- ,m_Metadata ( 0 )
- ,m_Direction ( 0 )
-{
-
-}
-
-
-
-
-
-void cRedstone::ChangeRedstone( int fillx, int filly, int fillz, bool added )
-{
- s_UseRedstone = false;
- if( !s_UseRedstone ) return;
-
- char before;
- //int tempX;
- //int tempY;
- //int tempZ;
- //int state;
- //m_Direction
- // 0 = x+
- // 1 = x-
- // 2 = z+
- // 3 = z-
- // 4 = y+
- // 5 = v-
-
-
- if (added) {
- m_Metadata = 15;
- } else {
- m_Metadata = 0;
- }
- before = m_Metadata;
-
- //printf("etb1\n");
- CalculateRedstone( fillx, filly, fillz ); //calculate all item centers.
- //printf("etb2\n");
-
- int Block = (int)m_World->GetBlock( fillx, filly, fillz );
-
- switch (Block)//these blocks won't trigger the normal calculaton because they are affected by the redstone around them. So we check each possible channel around them instead.
- {
- case E_BLOCK_REDSTONE_TORCH_ON:
- case E_BLOCK_REDSTONE_TORCH_OFF:
- case E_BLOCK_AIR:
- case E_BLOCK_PISTON_EXTENSION:
- case E_BLOCK_PISTON:
- case E_BLOCK_STICKY_PISTON:
- {
- m_Metadata = 0;
- m_Direction = 0;
- CalculateRedstone( fillx+1, filly, fillz );
- m_Metadata = 0;
- m_Direction = 1;
- CalculateRedstone( fillx-1, filly, fillz );
- m_Metadata = 0;
- m_Direction = 2;
- CalculateRedstone( fillx, filly, fillz+1 );
- m_Metadata = 0;
- m_Direction = 3;
- CalculateRedstone( fillx, filly, fillz-1 );
- m_Metadata = 0;
- CalculateRedstone( fillx, filly-1, fillz );
- break;
- }
- case E_BLOCK_REDSTONE_WIRE: //special case for redstone wire.
- {
- m_Direction = 0;
- CalculateRedstone( fillx+1, filly, fillz );
- m_Direction = 1;
- CalculateRedstone( fillx-1, filly, fillz );
- m_Direction = 2;
- CalculateRedstone( fillx, filly, fillz+1 );
- m_Direction = 3;
- CalculateRedstone( fillx, filly, fillz-1 );
- m_Metadata = 0;
- CalculateRedstone( fillx, filly-1, fillz );
-
- m_Direction = 4;
- CalculateRedstone( fillx+1, filly+1, fillz );
- CalculateRedstone( fillx-1, filly+1, fillz );
- CalculateRedstone( fillx, filly+1, fillz+1 );
- CalculateRedstone( fillx, filly+1, fillz-1 );
-
- m_Direction = 5;
- CalculateRedstone( fillx+1, filly-1, fillz );
- CalculateRedstone( fillx-1, filly-1, fillz );
- CalculateRedstone( fillx, filly-1, fillz+1 );
- CalculateRedstone( fillx, filly-1, fillz-1 );
- break;
- }
- }
-
- //printf("done here\n");
-}
-
-
-
-
-
-void cRedstone::CalculateRedstone( int fillx, int filly, int fillz)
-{
-
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_STICKY_PISTON ) || ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_PISTON ) ) {
- char pistonMeta = m_World->GetBlockMeta( fillx, filly, fillz );
- if (m_Metadata > 0) {
- if (pistonMeta < 6) { // only extend if piston is not already extended
- cPiston Piston(m_World);
- Piston.ExtendPiston(fillx, filly, fillz);
- }
- } else {
- if (pistonMeta > 6) { // only retract if piston is not already retracted
- cPiston Piston(m_World);
- Piston.RetractPiston(fillx, filly, fillz);
- }
- }
-
- } else if ( ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_ITEM_LEVER ) || ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_ITEM_STONE_BUTTON ) ) {
-
- if ( (int)m_World->GetBlockMeta( fillx, filly, fillz) > 6 ) { //button powered
- m_Metadata = 15; //change meta to 15 only if redstone power device in on possition is found.
- if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) {
- CalculateRedstone(fillx-1,filly,fillz);
- }
- if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) {
- CalculateRedstone(fillx+1,filly,fillz);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) {
- CalculateRedstone(fillx,filly,fillz-1);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) {
- CalculateRedstone(fillx,filly,fillz+1);
- }
- } else {
- if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) {
- CalculateRedstone(fillx-1,filly,fillz);
- }
- if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) {
- CalculateRedstone(fillx+1,filly,fillz);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) {
- CalculateRedstone(fillx,filly,fillz-1);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) {
- CalculateRedstone(fillx,filly,fillz+1);
- }
- }
-
- } else if ( ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_STONE_PRESSURE_PLATE ) || ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_STONE_BUTTON ) ) {
-
- if ( (int)m_World->GetBlockMeta( fillx, filly, fillz) == 1 ) { //plate powered
- m_Metadata = 15; //change meta to 15 only if redstone power device in on possition is found.
- if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) {
- CalculateRedstone(fillx-1,filly,fillz);
- }
- if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) {
- CalculateRedstone(fillx+1,filly,fillz);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) {
- CalculateRedstone(fillx,filly,fillz-1);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) {
- CalculateRedstone(fillx,filly,fillz+1);
- }
-
- } else {
-
- if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) {
- CalculateRedstone(fillx-1,filly,fillz);
- }
- if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) {
- CalculateRedstone(fillx+1,filly,fillz);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) {
- CalculateRedstone(fillx,filly,fillz-1);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) {
- CalculateRedstone(fillx,filly,fillz+1);
- }
- }
-
- } else if ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON ) { //If torch is on
- //printf("found torch on\n");
- m_Metadata = 15; //change meta to 15 only if redstone torch in on possition is found.
- if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) {
- CalculateRedstone(fillx-1,filly,fillz);
- }
- if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) {
- CalculateRedstone(fillx+1,filly,fillz);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) {
- CalculateRedstone(fillx,filly,fillz-1);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) {
- CalculateRedstone(fillx,filly,fillz+1);
- }
-
- } else if ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF ) { //if the torch is off
- //printf("found torch off\n");
- // no need to change meta here.
- if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) {
- CalculateRedstone(fillx-1,filly,fillz);
- }
- if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) {
- CalculateRedstone(fillx+1,filly,fillz);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) {
- CalculateRedstone(fillx,filly,fillz-1);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) {
- CalculateRedstone(fillx,filly,fillz+1);
- }
-
- } else if ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_REDSTONE_WIRE ) { //simple fill algorithm for redstone wire.
-
- if ( (int)m_World->GetBlockMeta( fillx, filly, fillz) != m_Metadata ) {
- m_World->FastSetBlock( fillx, filly, fillz, (char)E_BLOCK_REDSTONE_WIRE, m_Metadata );
- m_Direction = 0;
- CalculateRedstone( fillx+1, filly, fillz );
- m_Direction = 1;
- CalculateRedstone( fillx-1, filly, fillz );
- m_Direction = 2;
- CalculateRedstone( fillx, filly, fillz+1 );
- m_Direction = 3;
- CalculateRedstone( fillx, filly, fillz-1 );
- CalculateRedstone( fillx, filly-1, fillz ); //check one block below //similar to same plane
-
- m_Direction = 4;
- CalculateRedstone( fillx+1, filly+1, fillz );
- CalculateRedstone( fillx-1, filly+1, fillz );
- CalculateRedstone( fillx, filly+1, fillz+1 );
- CalculateRedstone( fillx, filly+1, fillz-1 );
-
- m_Direction = 5;
- CalculateRedstone( fillx+1, filly-1, fillz );
- CalculateRedstone( fillx-1, filly-1, fillz );
- CalculateRedstone( fillx, filly-1, fillz+1 );
- CalculateRedstone( fillx, filly-1, fillz-1 );
- }
-
- } else { //default, check item for torch attached to it. If meta > 0 then turn that torch off, otherwise turn it on. This change needs to be passed to the next world tick.
- //check for torch to east with meta 1 //turn off
- //check for torch to west with meta 2 //turn off
- //check for torch to south with meta 3 //turn off
- //check for torch to north with meta 4 //turn off
- //check for torch above with meta 5 //turn off
- if ( (int)m_World->GetBlock( fillx, filly, fillz ) != E_BLOCK_AIR ) {
- if (m_Direction < 4) { //redstone wire can only power blocks on the same plane or directly below
- if ( (int)m_Metadata > 0 ) { //wire powered
-
- //printf("bird: %i dog: %i \n",(int)m_World->GetBlock( fillx, filly+1, fillz ),(int)m_World->GetBlockMeta( fillx, filly+1, fillz));
- if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) == 1 ) ) { //east
- m_World->m_RSList.push_back(fillx+1);
- m_World->m_RSList.push_back(filly);
- m_World->m_RSList.push_back(fillz);
- m_World->m_RSList.push_back(00000);
- }
- if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) == 2 ) ) { //west
- m_World->m_RSList.push_back(fillx-1);
- m_World->m_RSList.push_back(filly);
- m_World->m_RSList.push_back(fillz);
- m_World->m_RSList.push_back(00000);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) == 3 ) ) { //south
- m_World->m_RSList.push_back(fillx);
- m_World->m_RSList.push_back(filly);
- m_World->m_RSList.push_back(fillz+1);
- m_World->m_RSList.push_back(00000);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) == 4 ) ) { //north
- m_World->m_RSList.push_back(fillx);
- m_World->m_RSList.push_back(filly);
- m_World->m_RSList.push_back(fillz-1);
- m_World->m_RSList.push_back(00000);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly+1, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx, filly+1, fillz) == 5 ) ) { //top
- m_World->m_RSList.push_back(fillx);
- m_World->m_RSList.push_back(filly+1);
- m_World->m_RSList.push_back(fillz);
- m_World->m_RSList.push_back(00000);
- }
-
- } else { //wire not powered
-
- bool BlockPowered = IsBlockPowered( fillx, filly, fillz ); //chck this block for other wire turned on or torch turned on below:
- if (BlockPowered == false) { //if block is not bowered by something else then I need to check for off torches and turn them on.
-
- //printf("echo: %i cruiser: %i \n",(int)m_World->GetBlock( fillx, filly+1, fillz ),(int)m_World->GetBlockMeta( fillx, filly+1, fillz));
- if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) == 1 ) ) { //east
- m_World->m_RSList.push_back(fillx+1);
- m_World->m_RSList.push_back(filly);
- m_World->m_RSList.push_back(fillz);
- m_World->m_RSList.push_back(11111);
- }
- if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) == 2 ) ) { //west
- m_World->m_RSList.push_back(fillx-1);
- m_World->m_RSList.push_back(filly);
- m_World->m_RSList.push_back(fillz);
- m_World->m_RSList.push_back(11111);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) == 3 ) ) { //south
- m_World->m_RSList.push_back(fillx);
- m_World->m_RSList.push_back(filly);
- m_World->m_RSList.push_back(fillz+1);
- m_World->m_RSList.push_back(11111);;
- }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) == 4 ) ) { //north
- m_World->m_RSList.push_back(fillx);
- m_World->m_RSList.push_back(filly);
- m_World->m_RSList.push_back(fillz-1);
- m_World->m_RSList.push_back(11111);
- }
- if ( ( (int)m_World->GetBlock( fillx, filly+1, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx, filly+1, fillz) == 5 ) ) { //top
- m_World->m_RSList.push_back(fillx);
- m_World->m_RSList.push_back(filly+1);
- m_World->m_RSList.push_back(fillz);
- m_World->m_RSList.push_back(11111);
- }
-
- }
-
- }
-
- }
-
- }
-
- }
-
-}
-
-
-
-
-
-bool cRedstone::IsBlockPowered( int fillx, int filly, int fillz )
-{
-
- if ( (int)m_World->GetBlock( fillx, filly-1, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; }
- if ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; }
- if ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; }
- if ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; }
- if ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; }
- if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) > 0 ) ) { return true; }
- if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) > 0 ) ) { return true; }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) > 0 ) ) { return true; }
- if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) > 0 ) ) { return true; }
- if ( ( (int)m_World->GetBlock( fillx, filly+1, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly+1, fillz) > 0 ) ) { return true; }
- return false;
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cRedstone.h" +#include "cPiston.h" +#include "cRoot.h" +#include "cWorld.h" +#include "BlockID.h" +#include <iostream> + + + + + +bool cRedstone::s_UseRedstone = false; + + + + + +cRedstone::cRedstone( cWorld* a_World ) + :m_World ( a_World ) + ,m_Metadata ( 0 ) + ,m_Direction ( 0 ) +{ + +} + + + + + +void cRedstone::ChangeRedstone( int fillx, int filly, int fillz, bool added ) +{ + s_UseRedstone = false; + if( !s_UseRedstone ) return; + + char before; + //int tempX; + //int tempY; + //int tempZ; + //int state; + //m_Direction + // 0 = x+ + // 1 = x- + // 2 = z+ + // 3 = z- + // 4 = y+ + // 5 = v- + + + if (added) { + m_Metadata = 15; + } else { + m_Metadata = 0; + } + before = m_Metadata; + + //printf("etb1\n"); + CalculateRedstone( fillx, filly, fillz ); //calculate all item centers. + //printf("etb2\n"); + + int Block = (int)m_World->GetBlock( fillx, filly, fillz ); + + switch (Block)//these blocks won't trigger the normal calculaton because they are affected by the redstone around them. So we check each possible channel around them instead. + { + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_AIR: + case E_BLOCK_PISTON_EXTENSION: + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + { + m_Metadata = 0; + m_Direction = 0; + CalculateRedstone( fillx+1, filly, fillz ); + m_Metadata = 0; + m_Direction = 1; + CalculateRedstone( fillx-1, filly, fillz ); + m_Metadata = 0; + m_Direction = 2; + CalculateRedstone( fillx, filly, fillz+1 ); + m_Metadata = 0; + m_Direction = 3; + CalculateRedstone( fillx, filly, fillz-1 ); + m_Metadata = 0; + CalculateRedstone( fillx, filly-1, fillz ); + break; + } + case E_BLOCK_REDSTONE_WIRE: //special case for redstone wire. + { + m_Direction = 0; + CalculateRedstone( fillx+1, filly, fillz ); + m_Direction = 1; + CalculateRedstone( fillx-1, filly, fillz ); + m_Direction = 2; + CalculateRedstone( fillx, filly, fillz+1 ); + m_Direction = 3; + CalculateRedstone( fillx, filly, fillz-1 ); + m_Metadata = 0; + CalculateRedstone( fillx, filly-1, fillz ); + + m_Direction = 4; + CalculateRedstone( fillx+1, filly+1, fillz ); + CalculateRedstone( fillx-1, filly+1, fillz ); + CalculateRedstone( fillx, filly+1, fillz+1 ); + CalculateRedstone( fillx, filly+1, fillz-1 ); + + m_Direction = 5; + CalculateRedstone( fillx+1, filly-1, fillz ); + CalculateRedstone( fillx-1, filly-1, fillz ); + CalculateRedstone( fillx, filly-1, fillz+1 ); + CalculateRedstone( fillx, filly-1, fillz-1 ); + break; + } + } + + //printf("done here\n"); +} + + + + + +void cRedstone::CalculateRedstone( int fillx, int filly, int fillz) +{ + + if ( ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_STICKY_PISTON ) || ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_PISTON ) ) { + char pistonMeta = m_World->GetBlockMeta( fillx, filly, fillz ); + if (m_Metadata > 0) { + if (pistonMeta < 6) { // only extend if piston is not already extended + cPiston Piston(m_World); + Piston.ExtendPiston(fillx, filly, fillz); + } + } else { + if (pistonMeta > 6) { // only retract if piston is not already retracted + cPiston Piston(m_World); + Piston.RetractPiston(fillx, filly, fillz); + } + } + + } else if ( ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_ITEM_LEVER ) || ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_ITEM_STONE_BUTTON ) ) { + + if ( (int)m_World->GetBlockMeta( fillx, filly, fillz) > 6 ) { //button powered + m_Metadata = 15; //change meta to 15 only if redstone power device in on possition is found. + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx-1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx+1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz-1); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz+1); + } + } else { + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx-1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx+1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz-1); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz+1); + } + } + + } else if ( ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_STONE_PRESSURE_PLATE ) || ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_STONE_BUTTON ) ) { + + if ( (int)m_World->GetBlockMeta( fillx, filly, fillz) == 1 ) { //plate powered + m_Metadata = 15; //change meta to 15 only if redstone power device in on possition is found. + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx-1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx+1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz-1); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz+1); + } + + } else { + + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx-1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx+1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz-1); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz+1); + } + } + + } else if ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON ) { //If torch is on + //printf("found torch on\n"); + m_Metadata = 15; //change meta to 15 only if redstone torch in on possition is found. + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx-1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx+1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz-1); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz+1); + } + + } else if ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF ) { //if the torch is off + //printf("found torch off\n"); + // no need to change meta here. + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx-1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) != m_Metadata ) ) { + CalculateRedstone(fillx+1,filly,fillz); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz-1); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) != m_Metadata ) ) { + CalculateRedstone(fillx,filly,fillz+1); + } + + } else if ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_REDSTONE_WIRE ) { //simple fill algorithm for redstone wire. + + if ( (int)m_World->GetBlockMeta( fillx, filly, fillz) != m_Metadata ) { + m_World->FastSetBlock( fillx, filly, fillz, (char)E_BLOCK_REDSTONE_WIRE, m_Metadata ); + m_Direction = 0; + CalculateRedstone( fillx+1, filly, fillz ); + m_Direction = 1; + CalculateRedstone( fillx-1, filly, fillz ); + m_Direction = 2; + CalculateRedstone( fillx, filly, fillz+1 ); + m_Direction = 3; + CalculateRedstone( fillx, filly, fillz-1 ); + CalculateRedstone( fillx, filly-1, fillz ); //check one block below //similar to same plane + + m_Direction = 4; + CalculateRedstone( fillx+1, filly+1, fillz ); + CalculateRedstone( fillx-1, filly+1, fillz ); + CalculateRedstone( fillx, filly+1, fillz+1 ); + CalculateRedstone( fillx, filly+1, fillz-1 ); + + m_Direction = 5; + CalculateRedstone( fillx+1, filly-1, fillz ); + CalculateRedstone( fillx-1, filly-1, fillz ); + CalculateRedstone( fillx, filly-1, fillz+1 ); + CalculateRedstone( fillx, filly-1, fillz-1 ); + } + + } else { //default, check item for torch attached to it. If meta > 0 then turn that torch off, otherwise turn it on. This change needs to be passed to the next world tick. + //check for torch to east with meta 1 //turn off + //check for torch to west with meta 2 //turn off + //check for torch to south with meta 3 //turn off + //check for torch to north with meta 4 //turn off + //check for torch above with meta 5 //turn off + if ( (int)m_World->GetBlock( fillx, filly, fillz ) != E_BLOCK_AIR ) { + if (m_Direction < 4) { //redstone wire can only power blocks on the same plane or directly below + if ( (int)m_Metadata > 0 ) { //wire powered + + //printf("bird: %i dog: %i \n",(int)m_World->GetBlock( fillx, filly+1, fillz ),(int)m_World->GetBlockMeta( fillx, filly+1, fillz)); + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) == 1 ) ) { //east + m_World->m_RSList.push_back(fillx+1); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz); + m_World->m_RSList.push_back(00000); + } + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) == 2 ) ) { //west + m_World->m_RSList.push_back(fillx-1); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz); + m_World->m_RSList.push_back(00000); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) == 3 ) ) { //south + m_World->m_RSList.push_back(fillx); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz+1); + m_World->m_RSList.push_back(00000); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) == 4 ) ) { //north + m_World->m_RSList.push_back(fillx); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz-1); + m_World->m_RSList.push_back(00000); + } + if ( ( (int)m_World->GetBlock( fillx, filly+1, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) && ( (int)m_World->GetBlockMeta( fillx, filly+1, fillz) == 5 ) ) { //top + m_World->m_RSList.push_back(fillx); + m_World->m_RSList.push_back(filly+1); + m_World->m_RSList.push_back(fillz); + m_World->m_RSList.push_back(00000); + } + + } else { //wire not powered + + bool BlockPowered = IsBlockPowered( fillx, filly, fillz ); //chck this block for other wire turned on or torch turned on below: + if (BlockPowered == false) { //if block is not bowered by something else then I need to check for off torches and turn them on. + + //printf("echo: %i cruiser: %i \n",(int)m_World->GetBlock( fillx, filly+1, fillz ),(int)m_World->GetBlockMeta( fillx, filly+1, fillz)); + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) == 1 ) ) { //east + m_World->m_RSList.push_back(fillx+1); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz); + m_World->m_RSList.push_back(11111); + } + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) == 2 ) ) { //west + m_World->m_RSList.push_back(fillx-1); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz); + m_World->m_RSList.push_back(11111); + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) == 3 ) ) { //south + m_World->m_RSList.push_back(fillx); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz+1); + m_World->m_RSList.push_back(11111);; + } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) == 4 ) ) { //north + m_World->m_RSList.push_back(fillx); + m_World->m_RSList.push_back(filly); + m_World->m_RSList.push_back(fillz-1); + m_World->m_RSList.push_back(11111); + } + if ( ( (int)m_World->GetBlock( fillx, filly+1, fillz ) == E_BLOCK_REDSTONE_TORCH_OFF) && ( (int)m_World->GetBlockMeta( fillx, filly+1, fillz) == 5 ) ) { //top + m_World->m_RSList.push_back(fillx); + m_World->m_RSList.push_back(filly+1); + m_World->m_RSList.push_back(fillz); + m_World->m_RSList.push_back(11111); + } + + } + + } + + } + + } + + } + +} + + + + + +bool cRedstone::IsBlockPowered( int fillx, int filly, int fillz ) +{ + + if ( (int)m_World->GetBlock( fillx, filly-1, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } + if ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } + if ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } + if ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } + if ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_TORCH_ON) { return true; } + if ( ( (int)m_World->GetBlock( fillx+1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx+1, filly, fillz) > 0 ) ) { return true; } + if ( ( (int)m_World->GetBlock( fillx-1, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx-1, filly, fillz) > 0 ) ) { return true; } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz+1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz+1) > 0 ) ) { return true; } + if ( ( (int)m_World->GetBlock( fillx, filly, fillz-1 ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz-1) > 0 ) ) { return true; } + if ( ( (int)m_World->GetBlock( fillx, filly+1, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly+1, fillz) > 0 ) ) { return true; } + return false; }
\ No newline at end of file diff --git a/source/cRedstone.h b/source/cRedstone.h index 5c971ad36..a5377e8a7 100644 --- a/source/cRedstone.h +++ b/source/cRedstone.h @@ -1,122 +1,122 @@ -#pragma once
-
-#include "Vector3i.h"
-
-class cWorld;
-class cRedstone
-{
-public:
-
- cRedstone( cWorld* a_World );
-
- static char RepeaterRotationToMetaData( float a_Rotation )
- {
- a_Rotation += 90 + 45; // So its not aligned with axis
- if( a_Rotation > 360.f ) a_Rotation -= 360.f;
- if( a_Rotation >= 0.f && a_Rotation < 90.f )
- return 0x1;
- else if( a_Rotation >= 180 && a_Rotation < 270 )
- return 0x3;
- else if( a_Rotation >= 90 && a_Rotation < 180 )
- return 0x2;
- else
- return 0x0;
- }
-
- static bool IsRepeaterPointingTo( const Vector3i & a_RepeaterPos, char a_MetaData, const Vector3i & a_BlockPos )
- {
- switch( a_MetaData & 0x3 )
- {
- case 0x0:
- if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0, 1 ) ) )
- {
- return true;
- }
- break;
- case 0x1:
- if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i(-1, 0, 0 ) ) )
- {
- return true;
- }
- break;
- case 0x2:
- if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0,-1 ) ) )
- {
- return true;
- }
- break;
- case 0x3:
- if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 1, 0, 0 ) ) )
- {
- return true;
- }
- break;
- default:
- break;
- }
- return false;
- }
-
- static bool IsRepeaterPointingAway( const Vector3i & a_RepeaterPos, char a_MetaData, const Vector3i & a_BlockPos )
- {
- switch( a_MetaData & 0x3 )
- {
- case 0x0:
- if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0,-1 ) ) )
- {
- return true;
- }
- break;
- case 0x1:
- if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 1, 0, 0 ) ) )
- {
- return true;
- }
- break;
- case 0x2:
- if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0, 1 ) ) )
- {
- return true;
- }
- break;
- case 0x3:
- if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i(-1, 0, 0 ) ) )
- {
- return true;
- }
- break;
- default:
- break;
- }
- return false;
- }
-
- static Vector3i GetRepeaterDirection( char a_MetaData )
- {
- switch( a_MetaData & 0x3 )
- {
- case 0x0:
- return Vector3i( 0, 0,-1 );
- case 0x1:
- return Vector3i( 1, 0, 0 );
- case 0x2:
- return Vector3i( 0, 0, 1 );
- case 0x3:
- return Vector3i(-1, 0, 0 );
- default:
- break;
- }
- return Vector3i();
- }
-
- void CalculateRedstone( int, int, int );
- void ChangeRedstone( int, int, int, bool );
- bool IsBlockPowered( int, int, int );
-
- cWorld* m_World;
-
- char m_Metadata;
- char m_Direction;
-
- static bool s_UseRedstone;
-};
+#pragma once + +#include "Vector3i.h" + +class cWorld; +class cRedstone +{ +public: + + cRedstone( cWorld* a_World ); + + static char RepeaterRotationToMetaData( float a_Rotation ) + { + a_Rotation += 90 + 45; // So its not aligned with axis + if( a_Rotation > 360.f ) a_Rotation -= 360.f; + if( a_Rotation >= 0.f && a_Rotation < 90.f ) + return 0x1; + else if( a_Rotation >= 180 && a_Rotation < 270 ) + return 0x3; + else if( a_Rotation >= 90 && a_Rotation < 180 ) + return 0x2; + else + return 0x0; + } + + static bool IsRepeaterPointingTo( const Vector3i & a_RepeaterPos, char a_MetaData, const Vector3i & a_BlockPos ) + { + switch( a_MetaData & 0x3 ) + { + case 0x0: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0, 1 ) ) ) + { + return true; + } + break; + case 0x1: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i(-1, 0, 0 ) ) ) + { + return true; + } + break; + case 0x2: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0,-1 ) ) ) + { + return true; + } + break; + case 0x3: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 1, 0, 0 ) ) ) + { + return true; + } + break; + default: + break; + } + return false; + } + + static bool IsRepeaterPointingAway( const Vector3i & a_RepeaterPos, char a_MetaData, const Vector3i & a_BlockPos ) + { + switch( a_MetaData & 0x3 ) + { + case 0x0: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0,-1 ) ) ) + { + return true; + } + break; + case 0x1: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 1, 0, 0 ) ) ) + { + return true; + } + break; + case 0x2: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i( 0, 0, 1 ) ) ) + { + return true; + } + break; + case 0x3: + if( (a_RepeaterPos - a_BlockPos).Equals( Vector3i(-1, 0, 0 ) ) ) + { + return true; + } + break; + default: + break; + } + return false; + } + + static Vector3i GetRepeaterDirection( char a_MetaData ) + { + switch( a_MetaData & 0x3 ) + { + case 0x0: + return Vector3i( 0, 0,-1 ); + case 0x1: + return Vector3i( 1, 0, 0 ); + case 0x2: + return Vector3i( 0, 0, 1 ); + case 0x3: + return Vector3i(-1, 0, 0 ); + default: + break; + } + return Vector3i(); + } + + void CalculateRedstone( int, int, int ); + void ChangeRedstone( int, int, int, bool ); + bool IsBlockPowered( int, int, int ); + + cWorld* m_World; + + char m_Metadata; + char m_Direction; + + static bool s_UseRedstone; +}; diff --git a/source/cRedstoneSimulator.cpp b/source/cRedstoneSimulator.cpp index 652d5a943..44a6bdb4c 100644 --- a/source/cRedstoneSimulator.cpp +++ b/source/cRedstoneSimulator.cpp @@ -1,702 +1,702 @@ -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cRedstoneSimulator.h"
-#include "cPiston.h"
-#include "cWorld.h"
-#include "BlockID.h"
-#include "cCriticalSection.h"
-#include "cTorch.h"
-
-#include "cRedstone.h"
-
-
-
-cRedstoneSimulator::cRedstoneSimulator( cWorld* a_World )
- : super(a_World)
-{
-}
-
-
-
-
-
-cRedstoneSimulator::~cRedstoneSimulator()
-{
-}
-
-
-
-
-
-void cRedstoneSimulator::WakeUp( int a_X, int a_Y, int a_Z )
-{
- if( cRedstone::s_UseRedstone ) return; // Using the other/broken simulator
-
- cCSLock Lock( m_CS );
- m_Blocks.push_back( Vector3i( a_X, a_Y, a_Z ) );
-}
-
-
-
-
-
-void cRedstoneSimulator::Simulate( float a_Dt )
-{
- if( cRedstone::s_UseRedstone ) return; // Using the other/broken simulator
-
- // Toggle torches on/off
- while( !m_RefreshTorchesAround.empty() )
- {
- Vector3i pos = m_RefreshTorchesAround.front();
- m_RefreshTorchesAround.pop_front();
-
- RefreshTorchesAround( pos );
- }
-
- // Set repeaters to correct values, and decrement ticks
- for( RepeaterList::iterator itr = m_SetRepeaters.begin(); itr != m_SetRepeaters.end(); )
- {
- (*itr).Ticks--;
- if( (*itr).Ticks <= 0 )
- {
- char Block = m_World->GetBlock( (*itr).Position );
- if( (*itr).bPowerOn == true && Block == E_BLOCK_REDSTONE_REPEATER_OFF )
- {
- m_World->FastSetBlock( (*itr).Position.x, (*itr).Position.y, (*itr).Position.z, E_BLOCK_REDSTONE_REPEATER_ON, m_World->GetBlockMeta( (*itr).Position ) );
- m_Blocks.push_back( (*itr).Position );
- }
- else if( (*itr).bPowerOn == false && Block == E_BLOCK_REDSTONE_REPEATER_ON )
- {
- m_World->FastSetBlock( (*itr).Position.x, (*itr).Position.y, (*itr).Position.z, E_BLOCK_REDSTONE_REPEATER_OFF, m_World->GetBlockMeta( (*itr).Position ) );
- m_Blocks.push_back( (*itr).Position );
- }
-
- if( (*itr).bPowerOffNextTime )
- {
- (*itr).bPowerOn = false;
- (*itr).bPowerOffNextTime = false;
- (*itr).Ticks = 10; // TODO: Look up actual ticks from block metadata
- ++itr;
- }
- else
- {
- itr = m_SetRepeaters.erase( itr );
- }
- }
- else
- {
- ++itr;
- }
- }
-
- // Handle changed blocks
- {
- cCSLock Lock( m_CS );
- std::swap( m_Blocks, m_BlocksBuffer );
- }
- for( BlockList::iterator itr = m_BlocksBuffer.begin(); itr != m_BlocksBuffer.end(); ++itr )
- {
- HandleChange( *itr );
- }
- m_BlocksBuffer.clear();
-}
-
-
-
-
-
-void cRedstoneSimulator::RefreshTorchesAround( const Vector3i & a_BlockPos )
-{
- static Vector3i Surroundings [] = {
- Vector3i(-1, 0, 0),
- Vector3i( 1, 0, 0),
- Vector3i( 0, 0,-1),
- Vector3i( 0, 0, 1),
- Vector3i( 0, 1, 0), // Also toggle torch on top
- };
- char TargetBlockID = E_BLOCK_REDSTONE_TORCH_ON;
- char TargetRepeaterID = E_BLOCK_REDSTONE_REPEATER_OFF;
- if( IsPowered( a_BlockPos, true ) )
- {
- TargetBlockID = E_BLOCK_REDSTONE_TORCH_OFF;
- TargetRepeaterID = E_BLOCK_REDSTONE_REPEATER_ON;
- //if( m_World->GetBlock( a_BlockPos ) == E_BLOCK_DIRT )
- //{
- // m_World->FastSetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, E_BLOCK_STONE, 0 );
- //}
- }
- else
- {
- //if( m_World->GetBlock( a_BlockPos ) == E_BLOCK_STONE )
- //{
- // m_World->FastSetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, E_BLOCK_DIRT, 0 );
- //}
- }
-
- for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i )
- {
- Vector3i TorchPos = a_BlockPos + Surroundings[i];
- const char Block = m_World->GetBlock( TorchPos );
- switch( Block )
- {
- case E_BLOCK_REDSTONE_TORCH_ON:
- case E_BLOCK_REDSTONE_TORCH_OFF:
- if( Block != TargetBlockID )
- {
- char TorchMeta = m_World->GetBlockMeta( TorchPos );
- if( cTorch::IsAttachedTo( TorchPos, TorchMeta, a_BlockPos ) )
- {
- m_World->FastSetBlock( TorchPos.x, TorchPos.y, TorchPos.z, TargetBlockID, m_World->GetBlockMeta( TorchPos ) );
- m_Blocks.push_back( TorchPos );
- }
- }
- break;
- case E_BLOCK_REDSTONE_REPEATER_ON:
- case E_BLOCK_REDSTONE_REPEATER_OFF:
- if( Block != TargetRepeaterID && cRedstone::IsRepeaterPointingAway( TorchPos, m_World->GetBlockMeta( TorchPos ), a_BlockPos ) )
- {
- SetRepeater( TorchPos, 10, TargetRepeaterID == E_BLOCK_REDSTONE_REPEATER_ON );
- }
- break;
- default:
- break;
- };
- }
-}
-
-
-
-
-
-void cRedstoneSimulator::HandleChange( const Vector3i & a_BlockPos )
-{
- std::deque< Vector3i > SpreadStack;
-
- Vector3i Surroundings[] = {
- Vector3i( 1, 0, 0 ),
- Vector3i( 1, 1, 0 ),
- Vector3i( 1,-1, 0 ),
- Vector3i(-1, 0, 0 ),
- Vector3i(-1, 1, 0 ),
- Vector3i(-1,-1, 0 ),
- Vector3i( 0, 0, 1 ),
- Vector3i( 0, 1, 1 ),
- Vector3i( 0,-1, 1 ),
- Vector3i( 0, 0,-1 ),
- Vector3i( 0, 1,-1 ),
- Vector3i( 0,-1,-1 ),
- Vector3i( 0,-1, 0 ),
- };
-
- char Block = m_World->GetBlock( a_BlockPos );
-
- // First check whether torch should be on or off
- if( Block == E_BLOCK_REDSTONE_TORCH_ON || Block == E_BLOCK_REDSTONE_TORCH_OFF )
- {
- static Vector3i Surroundings [] = {
- Vector3i(-1, 0, 0),
- Vector3i( 1, 0, 0),
- Vector3i( 0, 0,-1),
- Vector3i( 0, 0, 1),
- Vector3i( 0,-1, 0),
- };
- for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i )
- {
- Vector3i pos = a_BlockPos + Surroundings[i];
- char OtherBlock = m_World->GetBlock( pos );
- if( (OtherBlock != E_BLOCK_AIR) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_ON) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_OFF) )
- {
- RefreshTorchesAround( pos );
- }
- }
- Block = m_World->GetBlock( a_BlockPos ); // Make sure we got the updated block
- }
- else if( Block == E_BLOCK_REDSTONE_REPEATER_ON || Block == E_BLOCK_REDSTONE_REPEATER_OFF ) // Check if repeater is powered by a 'powered block' (not wires/torch)
- {
- Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) );
- Vector3i pos = a_BlockPos - Direction; // NOTE: It's minus Direction
- char OtherBlock = m_World->GetBlock( pos );
- if( (OtherBlock != E_BLOCK_AIR) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_ON) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_OFF) && (OtherBlock != E_BLOCK_REDSTONE_WIRE) )
- {
- RefreshTorchesAround( pos );
- }
- else
- {
- SetRepeater( a_BlockPos, 10, IsPowered( a_BlockPos, false ) );
- }
- Block = m_World->GetBlock( a_BlockPos );
- }
-
- BlockList Sources;
- // If torch is still on, use it as a source
- if( Block == E_BLOCK_REDSTONE_TORCH_ON )
- {
- Sources.push_back( a_BlockPos );
- }
- else if( Block == E_BLOCK_REDSTONE_REPEATER_ON )
- {
- static Vector3i Surroundings [] = { // It only spreads right in front, and one block up
- Vector3i( 0, 0, 0),
- Vector3i( 0, 1, 0),
- };
- Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) );
- for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i )
- {
- Vector3i pos = a_BlockPos + Direction + Surroundings[i];
- if( PowerBlock( pos, a_BlockPos, 0xf ) )
- {
- SpreadStack.push_back( pos );
- }
- }
- }
-
- // Power all blocks legally connected to the sources
- if( Block != E_BLOCK_REDSTONE_REPEATER_ON )
- {
- BlockList NewSources = RemoveCurrent( a_BlockPos );
- Sources.insert( Sources.end(), NewSources.begin(), NewSources.end() );
- while( !Sources.empty() )
- {
- Vector3i SourcePos = Sources.back();
- Sources.pop_back();
-
- char Block = m_World->GetBlock( SourcePos );
- switch( Block )
- {
- case E_BLOCK_REDSTONE_TORCH_OFF:
- case E_BLOCK_REDSTONE_TORCH_ON:
- {
- static Vector3i Surroundings [] = {
- Vector3i(-1, 0, 0),
- Vector3i( 1, 0, 0),
- Vector3i( 0, 0,-1),
- Vector3i( 0, 0, 1),
- };
- for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i )
- {
- Vector3i OtherPos = SourcePos + Surroundings[i];
- if( PowerBlock( OtherPos, a_BlockPos, 0xf ) )
- {
- SpreadStack.push_back( OtherPos ); // Changed, so add to stack
- }
- }
- }
- break;
- case E_BLOCK_REDSTONE_REPEATER_OFF:
- case E_BLOCK_REDSTONE_REPEATER_ON:
- {
- static Vector3i Surroundings [] = {
- Vector3i( 0, 0, 0),
- Vector3i( 0, 1, 0),
- };
- Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( SourcePos ) );
- for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i )
- {
- Vector3i pos = SourcePos + Direction + Surroundings[i];
- if( PowerBlock( pos, a_BlockPos, 0xf ) )
- {
- SpreadStack.push_back( pos );
- }
- }
- }
- break;
- };
-
-
- }
- }
-
-
- // Do a floodfill
- while( !SpreadStack.empty() )
- {
- Vector3i pos = SpreadStack.back();
- SpreadStack.pop_back();
-
- char Meta = m_World->GetBlockMeta( pos );
-
- for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i )
- {
- Vector3i OtherPos = pos + Surroundings[i];
- if( PowerBlock( OtherPos, pos, Meta-1 ) )
- {
- SpreadStack.push_back( OtherPos ); // Changed, so add to stack
- }
- }
- }
-
- // Only after a redstone area has been completely simulated the redstone entities can react
- while( !m_RefreshPistons.empty() )
- {
- Vector3i pos = m_RefreshPistons.back();
- m_RefreshPistons.pop_back();
-
- char Block = m_World->GetBlock( pos );
- switch( Block )
- {
- case E_BLOCK_PISTON:
- case E_BLOCK_STICKY_PISTON:
- if( IsPowered( pos ) )
- {
- cPiston Piston( m_World );
- Piston.ExtendPiston( pos.x, pos.y, pos.z );
- }
- else
- {
- cPiston Piston( m_World );
- Piston.RetractPiston( pos.x, pos.y, pos.z );
- }
- break;
- default:
- break;
- };
- }
-}
-
-
-
-
-
-bool cRedstoneSimulator::PowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock, char a_Power )
-{
- char Block = m_World->GetBlock( a_BlockPos );
- switch( Block )
- {
- case E_BLOCK_REDSTONE_WIRE:
- {
- if( m_World->GetBlockMeta( a_BlockPos ) < a_Power )
- {
- m_World->SetBlockMeta( a_BlockPos, a_Power );
- return true;
- }
- }
- break;
- case E_BLOCK_PISTON:
- case E_BLOCK_STICKY_PISTON:
- {
- m_RefreshPistons.push_back( a_BlockPos );
- }
- break;
- case E_BLOCK_REDSTONE_REPEATER_OFF:
- case E_BLOCK_REDSTONE_REPEATER_ON:
- {
- if( cRedstone::IsRepeaterPointingAway( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) )
- {
- SetRepeater( a_BlockPos, 10, true );
- }
- }
- break;
- default:
- {
- if( Block != E_BLOCK_AIR && Block != E_BLOCK_REDSTONE_TORCH_ON && Block != E_BLOCK_REDSTONE_TORCH_OFF )
- {
- if( IsPowered( a_BlockPos, true ) )
- {
- m_RefreshTorchesAround.push_back( a_BlockPos );
- }
- }
- }
- break;
- };
-
- return false;
-}
-
-
-
-
-
-int cRedstoneSimulator::UnPowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock )
-{
- char Block = m_World->GetBlock( a_BlockPos );
- switch( Block )
- {
- case E_BLOCK_REDSTONE_WIRE:
- {
- if( m_World->GetBlockMeta( a_BlockPos ) > 0 )
- {
- m_World->SetBlockMeta( a_BlockPos, 0 );
- return 1;
- }
- }
- break;
- case E_BLOCK_PISTON:
- case E_BLOCK_STICKY_PISTON:
- {
- m_RefreshPistons.push_back( a_BlockPos );
- }
- break;
- case E_BLOCK_REDSTONE_TORCH_ON:
- {
- return 2;
- }
- break;
- case E_BLOCK_REDSTONE_REPEATER_ON:
- {
- if( cRedstone::IsRepeaterPointingTo( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock )
- || cRedstone::IsRepeaterPointingTo( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock - Vector3i(0, 1, 0) ) ) // Check if repeater is next/below wire
- {
- return 2;
- }
- else if( cRedstone::IsRepeaterPointingAway( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) )
- {
- SetRepeater( a_BlockPos, 10, false );
- }
- }
- case E_BLOCK_REDSTONE_REPEATER_OFF:
- if( cRedstone::IsRepeaterPointingAway( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) )
- {
- SetRepeater( a_BlockPos, 10, false );
- }
- break;
- default:
- if( Block != E_BLOCK_AIR && Block != E_BLOCK_REDSTONE_TORCH_ON && Block != E_BLOCK_REDSTONE_TORCH_OFF )
- {
- if( !IsPowered( a_BlockPos, true ) )
- {
- m_RefreshTorchesAround.push_back( a_BlockPos );
- }
- }
- break;
- };
-
- return 0;
-}
-
-
-
-
-
-// Removes current from all powered redstone wires until it reaches an energy source.
-// Also returns all energy sources it encountered
-cRedstoneSimulator::BlockList cRedstoneSimulator::RemoveCurrent( const Vector3i & a_BlockPos )
-{
-
-
- std::deque< Vector3i > SpreadStack;
- std::deque< Vector3i > FoundSources;
-
- Vector3i Surroundings[] = {
- Vector3i( 1, 0, 0 ),
- Vector3i( 1, 1, 0 ),
- Vector3i( 1,-1, 0 ),
- Vector3i(-1, 0, 0 ),
- Vector3i(-1, 1, 0 ),
- Vector3i(-1,-1, 0 ),
- Vector3i( 0, 0, 1 ),
- Vector3i( 0, 1, 1 ),
- Vector3i( 0,-1, 1 ),
- Vector3i( 0, 0,-1 ),
- Vector3i( 0, 1,-1 ),
- Vector3i( 0,-1,-1 ),
- Vector3i( 0,-1, 0 ),
- };
-
- char Block = m_World->GetBlock( a_BlockPos );
- if( Block == E_BLOCK_REDSTONE_REPEATER_ON || Block == E_BLOCK_REDSTONE_REPEATER_OFF )
- {
- static Vector3i Surroundings [] = { // Repeaters only spread right in front and 1 block up
- Vector3i( 0, 0, 0),
- Vector3i( 0, 1, 0),
- };
- Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) );
- for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i )
- {
- Vector3i pos = a_BlockPos + Direction + Surroundings[i];
- int RetVal = UnPowerBlock( pos, a_BlockPos );
- if( RetVal == 1 )
- {
- SpreadStack.push_back( pos ); // Changed, so add to stack
- }
- else if( RetVal == 2 )
- {
- FoundSources.push_back( pos );
- }
- }
- }
- else if( Block == E_BLOCK_REDSTONE_TORCH_OFF || Block == E_BLOCK_REDSTONE_TORCH_ON )
- {
- static Vector3i Surroundings [] = { // Torches only spread on the same level
- Vector3i(-1, 0, 0),
- Vector3i( 1, 0, 0),
- Vector3i( 0, 0,-1),
- Vector3i( 0, 0, 1),
- };
-
- for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i )
- {
- Vector3i pos = Vector3i( a_BlockPos ) + Surroundings[i];
- int RetVal = UnPowerBlock( pos, a_BlockPos );
- if( RetVal == 1 )
- {
- SpreadStack.push_back( pos ); // Changed, so add to stack
- }
- else if( RetVal == 2 )
- {
- FoundSources.push_back( pos );
- }
- }
- }
- else
- {
- SpreadStack.push_back( a_BlockPos );
- }
-
-
- while( !SpreadStack.empty() )
- {
- Vector3i pos = SpreadStack.back();
- SpreadStack.pop_back();
-
- for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i )
- {
- Vector3i OtherPos = pos + Surroundings[i];
- int RetVal = UnPowerBlock( OtherPos, pos );
- if( RetVal == 1 )
- {
- SpreadStack.push_back( OtherPos ); // Changed, so add to stack
- }
- else if( RetVal == 2 )
- {
- FoundSources.push_back( OtherPos );
- }
- }
- }
-
- return FoundSources;
-}
-
-
-
-
-
-bool cRedstoneSimulator::IsPowering( const Vector3i & a_PowerPos, const Vector3i & a_BlockPos, eRedstoneDirection a_WireDirection, bool a_bOnlyByWire )
-{
- char PowerBlock = m_World->GetBlock( a_PowerPos );
- if( !a_bOnlyByWire && PowerBlock == E_BLOCK_REDSTONE_TORCH_ON ) return true;
- if( PowerBlock == E_BLOCK_REDSTONE_REPEATER_ON ) // A repeater pointing towards block is regarded as wire
- {
- if( cRedstone::IsRepeaterPointingTo( a_PowerPos, m_World->GetBlockMeta( a_PowerPos ), a_BlockPos ) )
- {
- return true;
- }
- }
- if( PowerBlock == E_BLOCK_REDSTONE_WIRE )
- {
- if( m_World->GetBlockMeta( a_PowerPos ) > 0 )
- {
- if( GetDirection( a_PowerPos ) == a_WireDirection )
- {
- return true;
- }
- }
- }
-
- return false;
-}
-
-
-
-
-
-bool cRedstoneSimulator::IsPowered( const Vector3i & a_BlockPos, bool a_bOnlyByWire /* = false */ )
-{
- char Block = m_World->GetBlock( a_BlockPos );
- if( Block == E_BLOCK_REDSTONE_REPEATER_OFF || Block == E_BLOCK_REDSTONE_REPEATER_ON )
- {
- Vector3i Behind = a_BlockPos - cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) );
- char BehindBlock = m_World->GetBlock( Behind );
- if( BehindBlock == E_BLOCK_REDSTONE_TORCH_ON )
- {
- return true;
- }
- if( BehindBlock == E_BLOCK_REDSTONE_WIRE )
- {
- if( m_World->GetBlockMeta( Behind ) > 0 )
- {
- return true;
- }
- }
- if( BehindBlock == E_BLOCK_REDSTONE_REPEATER_ON )
- {
- if( cRedstone::IsRepeaterPointingTo( Behind, m_World->GetBlockMeta( Behind ), a_BlockPos ) )
- {
- return true;
- }
- }
- return false;
- }
-
- if( IsPowering( Vector3i( a_BlockPos.x-1, a_BlockPos.y, a_BlockPos.z ), a_BlockPos, REDSTONE_X_POS, a_bOnlyByWire ) )
- return true;
- if( IsPowering( Vector3i( a_BlockPos.x+1, a_BlockPos.y, a_BlockPos.z ), a_BlockPos, REDSTONE_X_NEG, a_bOnlyByWire ) )
- return true;
- if( IsPowering( Vector3i( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z-1 ), a_BlockPos, REDSTONE_Z_POS, a_bOnlyByWire ) )
- return true;
- if( IsPowering( Vector3i( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z+1 ), a_BlockPos, REDSTONE_Z_NEG, a_bOnlyByWire ) )
- return true;
-
- // Only wires can power the bottom block
- char PosY = m_World->GetBlock( a_BlockPos.x, a_BlockPos.y+1, a_BlockPos.z );
- if( PosY == E_BLOCK_REDSTONE_WIRE )
- {
- if( m_World->GetBlockMeta( a_BlockPos.x, a_BlockPos.y+1, a_BlockPos.z ) > 0 )
- {
- return true;
- }
- }
-
- return false;
-}
-
-
-
-
-// Believe me, it works!! TODO: Add repeaters and low/high wires
-cRedstoneSimulator::eRedstoneDirection cRedstoneSimulator::GetDirection( int a_X, int a_Y, int a_Z )
-{
- int Dir = REDSTONE_NONE;
-
- char NegX = m_World->GetBlock( a_X-1, a_Y, a_Z );
- if( NegX == E_BLOCK_REDSTONE_WIRE || NegX == E_BLOCK_REDSTONE_TORCH_ON )
- {
- Dir |= (REDSTONE_X_POS);
- }
- char PosX = m_World->GetBlock( a_X+1, a_Y, a_Z );
- if( PosX == E_BLOCK_REDSTONE_WIRE || PosX == E_BLOCK_REDSTONE_TORCH_ON )
- {
- Dir |= (REDSTONE_X_NEG);
- }
- char NegZ = m_World->GetBlock( a_X, a_Y, a_Z-1 );
- if( NegZ == E_BLOCK_REDSTONE_WIRE || NegZ == E_BLOCK_REDSTONE_TORCH_ON )
- {
- if( (Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG ) ) //corner
- {
- Dir ^= REDSTONE_X_POS;
- Dir |= REDSTONE_X_NEG;
- }
- if( (Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS ) ) //corner
- {
- Dir ^= REDSTONE_X_NEG;
- Dir |= REDSTONE_X_POS;
- }
- Dir |= REDSTONE_Z_POS;
- }
- char PosZ = m_World->GetBlock( a_X, a_Y, a_Z+1 );
- if( PosZ == E_BLOCK_REDSTONE_WIRE || PosZ == E_BLOCK_REDSTONE_TORCH_ON )
- {
- if( (Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG ) ) //corner
- {
- Dir ^= REDSTONE_X_POS;
- Dir |= REDSTONE_X_NEG;
- }
- if( (Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS ) ) //corner
- {
- Dir ^= REDSTONE_X_NEG;
- Dir |= REDSTONE_X_POS;
- }
- Dir |= REDSTONE_Z_NEG;
- }
-
- return (eRedstoneDirection)Dir;
+#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cRedstoneSimulator.h" +#include "cPiston.h" +#include "cWorld.h" +#include "BlockID.h" +#include "cCriticalSection.h" +#include "cTorch.h" + +#include "cRedstone.h" + + + +cRedstoneSimulator::cRedstoneSimulator( cWorld* a_World ) + : super(a_World) +{ +} + + + + + +cRedstoneSimulator::~cRedstoneSimulator() +{ +} + + + + + +void cRedstoneSimulator::WakeUp( int a_X, int a_Y, int a_Z ) +{ + if( cRedstone::s_UseRedstone ) return; // Using the other/broken simulator + + cCSLock Lock( m_CS ); + m_Blocks.push_back( Vector3i( a_X, a_Y, a_Z ) ); +} + + + + + +void cRedstoneSimulator::Simulate( float a_Dt ) +{ + if( cRedstone::s_UseRedstone ) return; // Using the other/broken simulator + + // Toggle torches on/off + while( !m_RefreshTorchesAround.empty() ) + { + Vector3i pos = m_RefreshTorchesAround.front(); + m_RefreshTorchesAround.pop_front(); + + RefreshTorchesAround( pos ); + } + + // Set repeaters to correct values, and decrement ticks + for( RepeaterList::iterator itr = m_SetRepeaters.begin(); itr != m_SetRepeaters.end(); ) + { + (*itr).Ticks--; + if( (*itr).Ticks <= 0 ) + { + char Block = m_World->GetBlock( (*itr).Position ); + if( (*itr).bPowerOn == true && Block == E_BLOCK_REDSTONE_REPEATER_OFF ) + { + m_World->FastSetBlock( (*itr).Position.x, (*itr).Position.y, (*itr).Position.z, E_BLOCK_REDSTONE_REPEATER_ON, m_World->GetBlockMeta( (*itr).Position ) ); + m_Blocks.push_back( (*itr).Position ); + } + else if( (*itr).bPowerOn == false && Block == E_BLOCK_REDSTONE_REPEATER_ON ) + { + m_World->FastSetBlock( (*itr).Position.x, (*itr).Position.y, (*itr).Position.z, E_BLOCK_REDSTONE_REPEATER_OFF, m_World->GetBlockMeta( (*itr).Position ) ); + m_Blocks.push_back( (*itr).Position ); + } + + if( (*itr).bPowerOffNextTime ) + { + (*itr).bPowerOn = false; + (*itr).bPowerOffNextTime = false; + (*itr).Ticks = 10; // TODO: Look up actual ticks from block metadata + ++itr; + } + else + { + itr = m_SetRepeaters.erase( itr ); + } + } + else + { + ++itr; + } + } + + // Handle changed blocks + { + cCSLock Lock( m_CS ); + std::swap( m_Blocks, m_BlocksBuffer ); + } + for( BlockList::iterator itr = m_BlocksBuffer.begin(); itr != m_BlocksBuffer.end(); ++itr ) + { + HandleChange( *itr ); + } + m_BlocksBuffer.clear(); +} + + + + + +void cRedstoneSimulator::RefreshTorchesAround( const Vector3i & a_BlockPos ) +{ + static Vector3i Surroundings [] = { + Vector3i(-1, 0, 0), + Vector3i( 1, 0, 0), + Vector3i( 0, 0,-1), + Vector3i( 0, 0, 1), + Vector3i( 0, 1, 0), // Also toggle torch on top + }; + char TargetBlockID = E_BLOCK_REDSTONE_TORCH_ON; + char TargetRepeaterID = E_BLOCK_REDSTONE_REPEATER_OFF; + if( IsPowered( a_BlockPos, true ) ) + { + TargetBlockID = E_BLOCK_REDSTONE_TORCH_OFF; + TargetRepeaterID = E_BLOCK_REDSTONE_REPEATER_ON; + //if( m_World->GetBlock( a_BlockPos ) == E_BLOCK_DIRT ) + //{ + // m_World->FastSetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, E_BLOCK_STONE, 0 ); + //} + } + else + { + //if( m_World->GetBlock( a_BlockPos ) == E_BLOCK_STONE ) + //{ + // m_World->FastSetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, E_BLOCK_DIRT, 0 ); + //} + } + + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i TorchPos = a_BlockPos + Surroundings[i]; + const char Block = m_World->GetBlock( TorchPos ); + switch( Block ) + { + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_REDSTONE_TORCH_OFF: + if( Block != TargetBlockID ) + { + char TorchMeta = m_World->GetBlockMeta( TorchPos ); + if( cTorch::IsAttachedTo( TorchPos, TorchMeta, a_BlockPos ) ) + { + m_World->FastSetBlock( TorchPos.x, TorchPos.y, TorchPos.z, TargetBlockID, m_World->GetBlockMeta( TorchPos ) ); + m_Blocks.push_back( TorchPos ); + } + } + break; + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_REDSTONE_REPEATER_OFF: + if( Block != TargetRepeaterID && cRedstone::IsRepeaterPointingAway( TorchPos, m_World->GetBlockMeta( TorchPos ), a_BlockPos ) ) + { + SetRepeater( TorchPos, 10, TargetRepeaterID == E_BLOCK_REDSTONE_REPEATER_ON ); + } + break; + default: + break; + }; + } +} + + + + + +void cRedstoneSimulator::HandleChange( const Vector3i & a_BlockPos ) +{ + std::deque< Vector3i > SpreadStack; + + Vector3i Surroundings[] = { + Vector3i( 1, 0, 0 ), + Vector3i( 1, 1, 0 ), + Vector3i( 1,-1, 0 ), + Vector3i(-1, 0, 0 ), + Vector3i(-1, 1, 0 ), + Vector3i(-1,-1, 0 ), + Vector3i( 0, 0, 1 ), + Vector3i( 0, 1, 1 ), + Vector3i( 0,-1, 1 ), + Vector3i( 0, 0,-1 ), + Vector3i( 0, 1,-1 ), + Vector3i( 0,-1,-1 ), + Vector3i( 0,-1, 0 ), + }; + + char Block = m_World->GetBlock( a_BlockPos ); + + // First check whether torch should be on or off + if( Block == E_BLOCK_REDSTONE_TORCH_ON || Block == E_BLOCK_REDSTONE_TORCH_OFF ) + { + static Vector3i Surroundings [] = { + Vector3i(-1, 0, 0), + Vector3i( 1, 0, 0), + Vector3i( 0, 0,-1), + Vector3i( 0, 0, 1), + Vector3i( 0,-1, 0), + }; + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i pos = a_BlockPos + Surroundings[i]; + char OtherBlock = m_World->GetBlock( pos ); + if( (OtherBlock != E_BLOCK_AIR) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_ON) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_OFF) ) + { + RefreshTorchesAround( pos ); + } + } + Block = m_World->GetBlock( a_BlockPos ); // Make sure we got the updated block + } + else if( Block == E_BLOCK_REDSTONE_REPEATER_ON || Block == E_BLOCK_REDSTONE_REPEATER_OFF ) // Check if repeater is powered by a 'powered block' (not wires/torch) + { + Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) ); + Vector3i pos = a_BlockPos - Direction; // NOTE: It's minus Direction + char OtherBlock = m_World->GetBlock( pos ); + if( (OtherBlock != E_BLOCK_AIR) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_ON) && (OtherBlock != E_BLOCK_REDSTONE_TORCH_OFF) && (OtherBlock != E_BLOCK_REDSTONE_WIRE) ) + { + RefreshTorchesAround( pos ); + } + else + { + SetRepeater( a_BlockPos, 10, IsPowered( a_BlockPos, false ) ); + } + Block = m_World->GetBlock( a_BlockPos ); + } + + BlockList Sources; + // If torch is still on, use it as a source + if( Block == E_BLOCK_REDSTONE_TORCH_ON ) + { + Sources.push_back( a_BlockPos ); + } + else if( Block == E_BLOCK_REDSTONE_REPEATER_ON ) + { + static Vector3i Surroundings [] = { // It only spreads right in front, and one block up + Vector3i( 0, 0, 0), + Vector3i( 0, 1, 0), + }; + Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) ); + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i pos = a_BlockPos + Direction + Surroundings[i]; + if( PowerBlock( pos, a_BlockPos, 0xf ) ) + { + SpreadStack.push_back( pos ); + } + } + } + + // Power all blocks legally connected to the sources + if( Block != E_BLOCK_REDSTONE_REPEATER_ON ) + { + BlockList NewSources = RemoveCurrent( a_BlockPos ); + Sources.insert( Sources.end(), NewSources.begin(), NewSources.end() ); + while( !Sources.empty() ) + { + Vector3i SourcePos = Sources.back(); + Sources.pop_back(); + + char Block = m_World->GetBlock( SourcePos ); + switch( Block ) + { + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_REDSTONE_TORCH_ON: + { + static Vector3i Surroundings [] = { + Vector3i(-1, 0, 0), + Vector3i( 1, 0, 0), + Vector3i( 0, 0,-1), + Vector3i( 0, 0, 1), + }; + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i OtherPos = SourcePos + Surroundings[i]; + if( PowerBlock( OtherPos, a_BlockPos, 0xf ) ) + { + SpreadStack.push_back( OtherPos ); // Changed, so add to stack + } + } + } + break; + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_REDSTONE_REPEATER_ON: + { + static Vector3i Surroundings [] = { + Vector3i( 0, 0, 0), + Vector3i( 0, 1, 0), + }; + Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( SourcePos ) ); + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i pos = SourcePos + Direction + Surroundings[i]; + if( PowerBlock( pos, a_BlockPos, 0xf ) ) + { + SpreadStack.push_back( pos ); + } + } + } + break; + }; + + + } + } + + + // Do a floodfill + while( !SpreadStack.empty() ) + { + Vector3i pos = SpreadStack.back(); + SpreadStack.pop_back(); + + char Meta = m_World->GetBlockMeta( pos ); + + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i OtherPos = pos + Surroundings[i]; + if( PowerBlock( OtherPos, pos, Meta-1 ) ) + { + SpreadStack.push_back( OtherPos ); // Changed, so add to stack + } + } + } + + // Only after a redstone area has been completely simulated the redstone entities can react + while( !m_RefreshPistons.empty() ) + { + Vector3i pos = m_RefreshPistons.back(); + m_RefreshPistons.pop_back(); + + char Block = m_World->GetBlock( pos ); + switch( Block ) + { + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + if( IsPowered( pos ) ) + { + cPiston Piston( m_World ); + Piston.ExtendPiston( pos.x, pos.y, pos.z ); + } + else + { + cPiston Piston( m_World ); + Piston.RetractPiston( pos.x, pos.y, pos.z ); + } + break; + default: + break; + }; + } +} + + + + + +bool cRedstoneSimulator::PowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock, char a_Power ) +{ + char Block = m_World->GetBlock( a_BlockPos ); + switch( Block ) + { + case E_BLOCK_REDSTONE_WIRE: + { + if( m_World->GetBlockMeta( a_BlockPos ) < a_Power ) + { + m_World->SetBlockMeta( a_BlockPos, a_Power ); + return true; + } + } + break; + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + { + m_RefreshPistons.push_back( a_BlockPos ); + } + break; + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_REDSTONE_REPEATER_ON: + { + if( cRedstone::IsRepeaterPointingAway( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) ) + { + SetRepeater( a_BlockPos, 10, true ); + } + } + break; + default: + { + if( Block != E_BLOCK_AIR && Block != E_BLOCK_REDSTONE_TORCH_ON && Block != E_BLOCK_REDSTONE_TORCH_OFF ) + { + if( IsPowered( a_BlockPos, true ) ) + { + m_RefreshTorchesAround.push_back( a_BlockPos ); + } + } + } + break; + }; + + return false; +} + + + + + +int cRedstoneSimulator::UnPowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock ) +{ + char Block = m_World->GetBlock( a_BlockPos ); + switch( Block ) + { + case E_BLOCK_REDSTONE_WIRE: + { + if( m_World->GetBlockMeta( a_BlockPos ) > 0 ) + { + m_World->SetBlockMeta( a_BlockPos, 0 ); + return 1; + } + } + break; + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + { + m_RefreshPistons.push_back( a_BlockPos ); + } + break; + case E_BLOCK_REDSTONE_TORCH_ON: + { + return 2; + } + break; + case E_BLOCK_REDSTONE_REPEATER_ON: + { + if( cRedstone::IsRepeaterPointingTo( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) + || cRedstone::IsRepeaterPointingTo( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock - Vector3i(0, 1, 0) ) ) // Check if repeater is next/below wire + { + return 2; + } + else if( cRedstone::IsRepeaterPointingAway( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) ) + { + SetRepeater( a_BlockPos, 10, false ); + } + } + case E_BLOCK_REDSTONE_REPEATER_OFF: + if( cRedstone::IsRepeaterPointingAway( a_BlockPos, m_World->GetBlockMeta( a_BlockPos ), a_FromBlock ) ) + { + SetRepeater( a_BlockPos, 10, false ); + } + break; + default: + if( Block != E_BLOCK_AIR && Block != E_BLOCK_REDSTONE_TORCH_ON && Block != E_BLOCK_REDSTONE_TORCH_OFF ) + { + if( !IsPowered( a_BlockPos, true ) ) + { + m_RefreshTorchesAround.push_back( a_BlockPos ); + } + } + break; + }; + + return 0; +} + + + + + +// Removes current from all powered redstone wires until it reaches an energy source. +// Also returns all energy sources it encountered +cRedstoneSimulator::BlockList cRedstoneSimulator::RemoveCurrent( const Vector3i & a_BlockPos ) +{ + + + std::deque< Vector3i > SpreadStack; + std::deque< Vector3i > FoundSources; + + Vector3i Surroundings[] = { + Vector3i( 1, 0, 0 ), + Vector3i( 1, 1, 0 ), + Vector3i( 1,-1, 0 ), + Vector3i(-1, 0, 0 ), + Vector3i(-1, 1, 0 ), + Vector3i(-1,-1, 0 ), + Vector3i( 0, 0, 1 ), + Vector3i( 0, 1, 1 ), + Vector3i( 0,-1, 1 ), + Vector3i( 0, 0,-1 ), + Vector3i( 0, 1,-1 ), + Vector3i( 0,-1,-1 ), + Vector3i( 0,-1, 0 ), + }; + + char Block = m_World->GetBlock( a_BlockPos ); + if( Block == E_BLOCK_REDSTONE_REPEATER_ON || Block == E_BLOCK_REDSTONE_REPEATER_OFF ) + { + static Vector3i Surroundings [] = { // Repeaters only spread right in front and 1 block up + Vector3i( 0, 0, 0), + Vector3i( 0, 1, 0), + }; + Vector3i Direction = cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) ); + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i pos = a_BlockPos + Direction + Surroundings[i]; + int RetVal = UnPowerBlock( pos, a_BlockPos ); + if( RetVal == 1 ) + { + SpreadStack.push_back( pos ); // Changed, so add to stack + } + else if( RetVal == 2 ) + { + FoundSources.push_back( pos ); + } + } + } + else if( Block == E_BLOCK_REDSTONE_TORCH_OFF || Block == E_BLOCK_REDSTONE_TORCH_ON ) + { + static Vector3i Surroundings [] = { // Torches only spread on the same level + Vector3i(-1, 0, 0), + Vector3i( 1, 0, 0), + Vector3i( 0, 0,-1), + Vector3i( 0, 0, 1), + }; + + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i pos = Vector3i( a_BlockPos ) + Surroundings[i]; + int RetVal = UnPowerBlock( pos, a_BlockPos ); + if( RetVal == 1 ) + { + SpreadStack.push_back( pos ); // Changed, so add to stack + } + else if( RetVal == 2 ) + { + FoundSources.push_back( pos ); + } + } + } + else + { + SpreadStack.push_back( a_BlockPos ); + } + + + while( !SpreadStack.empty() ) + { + Vector3i pos = SpreadStack.back(); + SpreadStack.pop_back(); + + for( unsigned int i = 0; i < ARRAYCOUNT( Surroundings ); ++i ) + { + Vector3i OtherPos = pos + Surroundings[i]; + int RetVal = UnPowerBlock( OtherPos, pos ); + if( RetVal == 1 ) + { + SpreadStack.push_back( OtherPos ); // Changed, so add to stack + } + else if( RetVal == 2 ) + { + FoundSources.push_back( OtherPos ); + } + } + } + + return FoundSources; +} + + + + + +bool cRedstoneSimulator::IsPowering( const Vector3i & a_PowerPos, const Vector3i & a_BlockPos, eRedstoneDirection a_WireDirection, bool a_bOnlyByWire ) +{ + char PowerBlock = m_World->GetBlock( a_PowerPos ); + if( !a_bOnlyByWire && PowerBlock == E_BLOCK_REDSTONE_TORCH_ON ) return true; + if( PowerBlock == E_BLOCK_REDSTONE_REPEATER_ON ) // A repeater pointing towards block is regarded as wire + { + if( cRedstone::IsRepeaterPointingTo( a_PowerPos, m_World->GetBlockMeta( a_PowerPos ), a_BlockPos ) ) + { + return true; + } + } + if( PowerBlock == E_BLOCK_REDSTONE_WIRE ) + { + if( m_World->GetBlockMeta( a_PowerPos ) > 0 ) + { + if( GetDirection( a_PowerPos ) == a_WireDirection ) + { + return true; + } + } + } + + return false; +} + + + + + +bool cRedstoneSimulator::IsPowered( const Vector3i & a_BlockPos, bool a_bOnlyByWire /* = false */ ) +{ + char Block = m_World->GetBlock( a_BlockPos ); + if( Block == E_BLOCK_REDSTONE_REPEATER_OFF || Block == E_BLOCK_REDSTONE_REPEATER_ON ) + { + Vector3i Behind = a_BlockPos - cRedstone::GetRepeaterDirection( m_World->GetBlockMeta( a_BlockPos ) ); + char BehindBlock = m_World->GetBlock( Behind ); + if( BehindBlock == E_BLOCK_REDSTONE_TORCH_ON ) + { + return true; + } + if( BehindBlock == E_BLOCK_REDSTONE_WIRE ) + { + if( m_World->GetBlockMeta( Behind ) > 0 ) + { + return true; + } + } + if( BehindBlock == E_BLOCK_REDSTONE_REPEATER_ON ) + { + if( cRedstone::IsRepeaterPointingTo( Behind, m_World->GetBlockMeta( Behind ), a_BlockPos ) ) + { + return true; + } + } + return false; + } + + if( IsPowering( Vector3i( a_BlockPos.x-1, a_BlockPos.y, a_BlockPos.z ), a_BlockPos, REDSTONE_X_POS, a_bOnlyByWire ) ) + return true; + if( IsPowering( Vector3i( a_BlockPos.x+1, a_BlockPos.y, a_BlockPos.z ), a_BlockPos, REDSTONE_X_NEG, a_bOnlyByWire ) ) + return true; + if( IsPowering( Vector3i( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z-1 ), a_BlockPos, REDSTONE_Z_POS, a_bOnlyByWire ) ) + return true; + if( IsPowering( Vector3i( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z+1 ), a_BlockPos, REDSTONE_Z_NEG, a_bOnlyByWire ) ) + return true; + + // Only wires can power the bottom block + char PosY = m_World->GetBlock( a_BlockPos.x, a_BlockPos.y+1, a_BlockPos.z ); + if( PosY == E_BLOCK_REDSTONE_WIRE ) + { + if( m_World->GetBlockMeta( a_BlockPos.x, a_BlockPos.y+1, a_BlockPos.z ) > 0 ) + { + return true; + } + } + + return false; +} + + + + +// Believe me, it works!! TODO: Add repeaters and low/high wires +cRedstoneSimulator::eRedstoneDirection cRedstoneSimulator::GetDirection( int a_X, int a_Y, int a_Z ) +{ + int Dir = REDSTONE_NONE; + + char NegX = m_World->GetBlock( a_X-1, a_Y, a_Z ); + if( NegX == E_BLOCK_REDSTONE_WIRE || NegX == E_BLOCK_REDSTONE_TORCH_ON ) + { + Dir |= (REDSTONE_X_POS); + } + char PosX = m_World->GetBlock( a_X+1, a_Y, a_Z ); + if( PosX == E_BLOCK_REDSTONE_WIRE || PosX == E_BLOCK_REDSTONE_TORCH_ON ) + { + Dir |= (REDSTONE_X_NEG); + } + char NegZ = m_World->GetBlock( a_X, a_Y, a_Z-1 ); + if( NegZ == E_BLOCK_REDSTONE_WIRE || NegZ == E_BLOCK_REDSTONE_TORCH_ON ) + { + if( (Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG ) ) //corner + { + Dir ^= REDSTONE_X_POS; + Dir |= REDSTONE_X_NEG; + } + if( (Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS ) ) //corner + { + Dir ^= REDSTONE_X_NEG; + Dir |= REDSTONE_X_POS; + } + Dir |= REDSTONE_Z_POS; + } + char PosZ = m_World->GetBlock( a_X, a_Y, a_Z+1 ); + if( PosZ == E_BLOCK_REDSTONE_WIRE || PosZ == E_BLOCK_REDSTONE_TORCH_ON ) + { + if( (Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG ) ) //corner + { + Dir ^= REDSTONE_X_POS; + Dir |= REDSTONE_X_NEG; + } + if( (Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS ) ) //corner + { + Dir ^= REDSTONE_X_NEG; + Dir |= REDSTONE_X_POS; + } + Dir |= REDSTONE_Z_NEG; + } + + return (eRedstoneDirection)Dir; }
\ No newline at end of file diff --git a/source/cRedstoneSimulator.h b/source/cRedstoneSimulator.h index 927902f5a..6ac1eef5d 100644 --- a/source/cRedstoneSimulator.h +++ b/source/cRedstoneSimulator.h @@ -1,90 +1,90 @@ -#pragma once
-
-#include "cSimulator.h"
-#include "Vector3i.h"
-
-class cRedstoneSimulator : public cSimulator
-{
- typedef cSimulator super;
-public:
- cRedstoneSimulator( cWorld* a_World );
- ~cRedstoneSimulator();
-
- virtual void Simulate( float a_Dt );
- virtual bool IsAllowedBlock( char a_BlockID ) { return true; }
-
- virtual void WakeUp( int a_X, int a_Y, int a_Z );
-
- enum eRedstoneDirection
- {
- REDSTONE_NONE = 0,
- REDSTONE_X_POS = 0x1,
- REDSTONE_X_NEG = 0x2,
- REDSTONE_Z_POS = 0x4,
- REDSTONE_Z_NEG = 0x8,
- };
- eRedstoneDirection GetDirection( int a_X, int a_Y, int a_Z );
- eRedstoneDirection GetDirection( const Vector3i & a_Pos ) { return GetDirection( a_Pos.x, a_Pos.y, a_Pos.z ); }
-private:
- struct sRepeaterChange
- {
- Vector3i Position;
- int Ticks;
- bool bPowerOn;
- bool bPowerOffNextTime;
- };
-
- typedef std::deque <Vector3i> BlockList;
-
- typedef std::deque< sRepeaterChange > RepeaterList;
- RepeaterList m_SetRepeaters;
- void SetRepeater( const Vector3i & a_Position, int a_Ticks, bool a_bPowerOn )
- {
- for( RepeaterList::iterator itr = m_SetRepeaters.begin(); itr != m_SetRepeaters.end(); ++itr )
- {
- sRepeaterChange & Change = *itr;
- if( Change.Position.Equals( a_Position ) )
- {
- if( Change.bPowerOn && a_bPowerOn == false )
- {
- Change.bPowerOffNextTime = true;
- }
- if( a_bPowerOn == true )
- {
- Change.bPowerOffNextTime = false;
- }
- Change.bPowerOn |= a_bPowerOn;
- return;
- }
- }
-
- sRepeaterChange RC;
- RC.Position = a_Position;
- RC.Ticks = a_Ticks;
- RC.bPowerOn = a_bPowerOn;
- RC.bPowerOffNextTime = false;
- m_SetRepeaters.push_back( RC );
- }
-
- virtual void AddBlock(int a_X, int a_Y, int a_Z) {}
-
- void HandleChange( const Vector3i & a_BlockPos );
- BlockList RemoveCurrent( const Vector3i & a_BlockPos );
-
- bool PowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock, char a_Power );
- int UnPowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock );
-
- bool IsPowered( const Vector3i & a_BlockPos, bool a_bOnlyByWire = false );
- bool IsPowering( const Vector3i & a_PowerPos, const Vector3i & a_BlockPos, eRedstoneDirection a_WireDirection, bool a_bOnlyByWire );
-
- BlockList m_Blocks;
- BlockList m_BlocksBuffer;
-
- BlockList m_RefreshPistons;
-
- BlockList m_RefreshTorchesAround;
-
- void RefreshTorchesAround( const Vector3i & a_BlockPos );
-
- cCriticalSection m_CS;
+#pragma once + +#include "cSimulator.h" +#include "Vector3i.h" + +class cRedstoneSimulator : public cSimulator +{ + typedef cSimulator super; +public: + cRedstoneSimulator( cWorld* a_World ); + ~cRedstoneSimulator(); + + virtual void Simulate( float a_Dt ); + virtual bool IsAllowedBlock( char a_BlockID ) { return true; } + + virtual void WakeUp( int a_X, int a_Y, int a_Z ); + + enum eRedstoneDirection + { + REDSTONE_NONE = 0, + REDSTONE_X_POS = 0x1, + REDSTONE_X_NEG = 0x2, + REDSTONE_Z_POS = 0x4, + REDSTONE_Z_NEG = 0x8, + }; + eRedstoneDirection GetDirection( int a_X, int a_Y, int a_Z ); + eRedstoneDirection GetDirection( const Vector3i & a_Pos ) { return GetDirection( a_Pos.x, a_Pos.y, a_Pos.z ); } +private: + struct sRepeaterChange + { + Vector3i Position; + int Ticks; + bool bPowerOn; + bool bPowerOffNextTime; + }; + + typedef std::deque <Vector3i> BlockList; + + typedef std::deque< sRepeaterChange > RepeaterList; + RepeaterList m_SetRepeaters; + void SetRepeater( const Vector3i & a_Position, int a_Ticks, bool a_bPowerOn ) + { + for( RepeaterList::iterator itr = m_SetRepeaters.begin(); itr != m_SetRepeaters.end(); ++itr ) + { + sRepeaterChange & Change = *itr; + if( Change.Position.Equals( a_Position ) ) + { + if( Change.bPowerOn && a_bPowerOn == false ) + { + Change.bPowerOffNextTime = true; + } + if( a_bPowerOn == true ) + { + Change.bPowerOffNextTime = false; + } + Change.bPowerOn |= a_bPowerOn; + return; + } + } + + sRepeaterChange RC; + RC.Position = a_Position; + RC.Ticks = a_Ticks; + RC.bPowerOn = a_bPowerOn; + RC.bPowerOffNextTime = false; + m_SetRepeaters.push_back( RC ); + } + + virtual void AddBlock(int a_X, int a_Y, int a_Z) {} + + void HandleChange( const Vector3i & a_BlockPos ); + BlockList RemoveCurrent( const Vector3i & a_BlockPos ); + + bool PowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock, char a_Power ); + int UnPowerBlock( const Vector3i & a_BlockPos, const Vector3i & a_FromBlock ); + + bool IsPowered( const Vector3i & a_BlockPos, bool a_bOnlyByWire = false ); + bool IsPowering( const Vector3i & a_PowerPos, const Vector3i & a_BlockPos, eRedstoneDirection a_WireDirection, bool a_bOnlyByWire ); + + BlockList m_Blocks; + BlockList m_BlocksBuffer; + + BlockList m_RefreshPistons; + + BlockList m_RefreshTorchesAround; + + void RefreshTorchesAround( const Vector3i & a_BlockPos ); + + cCriticalSection m_CS; };
\ No newline at end of file diff --git a/source/cReferenceManager.cpp b/source/cReferenceManager.cpp index e639884c4..b39d71858 100644 --- a/source/cReferenceManager.cpp +++ b/source/cReferenceManager.cpp @@ -1,43 +1,43 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cReferenceManager.h"
-#include "cEntity.h"
-
-
-
-
-
-cReferenceManager::cReferenceManager( ENUM_REFERENCE_MANAGER_TYPE a_Type )
- : m_Type( a_Type )
-{
-}
-
-cReferenceManager::~cReferenceManager()
-{
- if( m_Type == RFMNGR_REFERENCERS )
- {
- for( std::list< cEntity** >::iterator itr = m_References.begin(); itr != m_References.end(); ++itr )
- {
- *(*itr) = 0; // Set referenced pointer to 0
- }
- }
- else
- {
- for( std::list< cEntity** >::iterator itr = m_References.begin(); itr != m_References.end(); ++itr )
- {
- cEntity* Ptr = (*(*itr));
- if( Ptr ) Ptr->Dereference( *(*itr) );
- }
- }
-}
-
-void cReferenceManager::AddReference( cEntity*& a_EntityPtr )
-{
- m_References.push_back( &a_EntityPtr );
-}
-
-void cReferenceManager::Dereference( cEntity*& a_EntityPtr )
-{
- m_References.remove( &a_EntityPtr );
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cReferenceManager.h" +#include "cEntity.h" + + + + + +cReferenceManager::cReferenceManager( ENUM_REFERENCE_MANAGER_TYPE a_Type ) + : m_Type( a_Type ) +{ +} + +cReferenceManager::~cReferenceManager() +{ + if( m_Type == RFMNGR_REFERENCERS ) + { + for( std::list< cEntity** >::iterator itr = m_References.begin(); itr != m_References.end(); ++itr ) + { + *(*itr) = 0; // Set referenced pointer to 0 + } + } + else + { + for( std::list< cEntity** >::iterator itr = m_References.begin(); itr != m_References.end(); ++itr ) + { + cEntity* Ptr = (*(*itr)); + if( Ptr ) Ptr->Dereference( *(*itr) ); + } + } +} + +void cReferenceManager::AddReference( cEntity*& a_EntityPtr ) +{ + m_References.push_back( &a_EntityPtr ); +} + +void cReferenceManager::Dereference( cEntity*& a_EntityPtr ) +{ + m_References.remove( &a_EntityPtr ); }
\ No newline at end of file diff --git a/source/cReferenceManager.h b/source/cReferenceManager.h index 3142d5d5a..bcd451f72 100644 --- a/source/cReferenceManager.h +++ b/source/cReferenceManager.h @@ -1,34 +1,34 @@ -
-#pragma once
-
-
-
-
-
-class cEntity;
-
-
-
-
-
-class cReferenceManager
-{
-public:
- enum ENUM_REFERENCE_MANAGER_TYPE
- {
- RFMNGR_REFERENCERS,
- RFMNGR_REFERENCES,
- };
- cReferenceManager( ENUM_REFERENCE_MANAGER_TYPE a_Type );
- ~cReferenceManager();
-
- void AddReference( cEntity*& a_EntityPtr );
- void Dereference( cEntity*& a_EntityPtr );
-private:
- ENUM_REFERENCE_MANAGER_TYPE m_Type;
- std::list< cEntity** > m_References;
-};
-
-
-
-
+ +#pragma once + + + + + +class cEntity; + + + + + +class cReferenceManager +{ +public: + enum ENUM_REFERENCE_MANAGER_TYPE + { + RFMNGR_REFERENCERS, + RFMNGR_REFERENCES, + }; + cReferenceManager( ENUM_REFERENCE_MANAGER_TYPE a_Type ); + ~cReferenceManager(); + + void AddReference( cEntity*& a_EntityPtr ); + void Dereference( cEntity*& a_EntityPtr ); +private: + ENUM_REFERENCE_MANAGER_TYPE m_Type; + std::list< cEntity** > m_References; +}; + + + + diff --git a/source/cRoot.cpp b/source/cRoot.cpp index 59f0e47f4..9feff537d 100644 --- a/source/cRoot.cpp +++ b/source/cRoot.cpp @@ -1,394 +1,394 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cRoot.h"
-#include "cServer.h"
-#include "cWorld.h"
-#include "cWebAdmin.h"
-#include "cFurnaceRecipe.h"
-#include "cGroupManager.h"
-#include "CraftingRecipes.h"
-#include "cPluginManager.h"
-#include "cMonsterConfig.h"
-#include "cSleep.h"
-#include "cThread.h"
-#include "cFileFormatUpdater.h"
-#include "cRedstone.h"
-
-#include "../iniFile/iniFile.h"
-
-#include <iostream>
-
-
-
-
-
-cRoot* cRoot::s_Root = 0;
-
-typedef std::map< AString, cWorld* > WorldMap;
-struct cRoot::sRootState
-{
- cWorld* pDefaultWorld;
- WorldMap WorldsByName;
-};
-
-
-
-
-
-cRoot::cRoot()
- : m_Server( 0 )
- , m_MonsterConfig( 0 )
- , m_GroupManager( 0 )
- , m_CraftingRecipes(NULL)
- , m_FurnaceRecipe( 0 )
- , m_WebAdmin( 0 )
- , m_PluginManager( 0 )
- , m_Log( 0 )
- , m_bStop( false )
- , m_bRestart( false )
- , m_InputThread( 0 )
- , m_pState( new sRootState )
-{
- s_Root = this;
-}
-
-
-
-
-
-cRoot::~cRoot()
-{
- s_Root = 0;
- delete m_pState;
-}
-
-
-
-
-
-void cRoot::InputThread(void* a_Params)
-{
- cRoot& self = *(cRoot*)a_Params;
-
- while( !(self.m_bStop || self.m_bRestart) )
- {
- std::string Command;
- std::getline(std::cin, Command);
- self.ServerCommand( Command.c_str() );
- }
-}
-
-
-
-
-
-void cRoot::Start()
-{
- delete m_Log;
- m_Log = new cMCLogger();
-
- m_bStop = false;
- while (!m_bStop)
- {
- m_bRestart = false;
-
- LoadGlobalSettings();
-
- cFileFormatUpdater::UpdateFileFormat();
-
- LOG("Creating new server instance...");
- m_Server = new cServer();
-
- LOG("Starting server...");
- cIniFile IniFile("settings.ini");
- IniFile.ReadFile();
- int Port = IniFile.GetValueSetI("Server", "Port", 25565 );
- if(!m_Server->InitServer( Port ))
- {
- LOG("Failed to start server, shutting down.");
- return;
- }
- IniFile.WriteFile();
-
- cIniFile WebIniFile("webadmin.ini");
- if( WebIniFile.ReadFile() )
- {
- if( WebIniFile.GetValueB("WebAdmin", "Enabled", false ) == true )
- {
- LOG("Creating WebAdmin...");
- m_WebAdmin = new cWebAdmin(8080);
- }
- }
-
- LOG("Loading settings...");
- m_GroupManager = new cGroupManager();
- m_CraftingRecipes = new cCraftingRecipes;
- m_FurnaceRecipe = new cFurnaceRecipe();
-
- LOG("Loading worlds...");
- LoadWorlds();
-
- LOG("Loading plugin manager...");
- m_PluginManager = new cPluginManager(); // This should be last
- m_PluginManager->ReloadPluginsNow();
-
- LOG("Loading MonsterConfig...");
- m_MonsterConfig = new cMonsterConfig;
-
- // This sets stuff in motion
- LOG("Starting Authenticator...");
- m_Authenticator.Start();
-
- LOG("Starting worlds...");
- StartWorlds();
-
- LOG("Starting server...");
- m_Server->StartListenThread();
- //cHeartBeat* HeartBeat = new cHeartBeat();
-
- LOG("Starting InputThread...");
- m_InputThread = new cThread( InputThread, this, "cRoot::InputThread" );
- m_InputThread->Start( true );
-
- LOG("Initialization done, server running now.");
- while( !m_bStop && !m_bRestart ) // These are modified by external threads
- {
- cSleep::MilliSleep( 1000 );
- }
-
- delete m_InputThread; m_InputThread = 0;
-
- // Deallocate stuffs
- LOG("Shutting down server...");
- m_Server->Shutdown(); // This waits for threads to stop and d/c clients
- LOG("Stopping authenticator...");
- m_Authenticator.Stop();
- LOG("Stopping plugin manager...");
- delete m_PluginManager; m_PluginManager = 0; // This should be first
- LOG("Freeing MonsterConfig...");
- delete m_MonsterConfig; m_MonsterConfig = 0;
- LOG("Stopping WebAdmin...");
- delete m_WebAdmin; m_WebAdmin = 0;
- LOG("Unloading recipes...");
- delete m_FurnaceRecipe; m_FurnaceRecipe = NULL;
- delete m_CraftingRecipes; m_CraftingRecipes = NULL;
- LOG("Forgetting groups...");
- delete m_GroupManager; m_GroupManager = 0;
- LOG("Unloading worlds...");
- UnloadWorlds();
- LOG("Destroying server...");
- //delete HeartBeat; HeartBeat = 0;
- delete m_Server; m_Server = 0;
- LOG("Shutdown done.");
- }
-
- delete m_Log; m_Log = 0;
-}
-
-
-
-
-
-void cRoot::LoadGlobalSettings()
-{
- cIniFile IniFile("settings.ini");
- if( IniFile.ReadFile() )
- {
- cRedstone::s_UseRedstone = IniFile.GetValueB("Redstone", "SimulateRedstone", true );
- }
-}
-
-
-
-
-
-void cRoot::LoadWorlds(void)
-{
- cIniFile IniFile("settings.ini"); IniFile.ReadFile();
-
- // First get the default world
- AString DefaultWorldName = IniFile.GetValueSet("Worlds", "DefaultWorld", "world");
- m_pState->pDefaultWorld = new cWorld( DefaultWorldName.c_str() );
- m_pState->WorldsByName[ DefaultWorldName ] = m_pState->pDefaultWorld;
-
- // Then load the other worlds
- unsigned int KeyNum = IniFile.FindKey("Worlds");
- unsigned int NumWorlds = IniFile.GetNumValues( KeyNum );
- if (NumWorlds <= 0)
- {
- return;
- }
-
- for (unsigned int i = 0; i < NumWorlds; i++)
- {
- AString ValueName = IniFile.GetValueName(KeyNum, i );
- if (ValueName.compare("World") != 0)
- {
- continue;
- }
- AString WorldName = IniFile.GetValue(KeyNum, i );
- if (WorldName.empty())
- {
- continue;
- }
- cWorld* NewWorld = new cWorld( WorldName.c_str() );
- m_pState->WorldsByName[ WorldName ] = NewWorld;
- } // for i - Worlds
-}
-
-
-
-
-
-void cRoot::StartWorlds(void)
-{
- for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr )
- {
- itr->second->InitializeSpawn();
- }
-}
-
-
-
-
-
-void cRoot::UnloadWorlds(void)
-{
- for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr )
- {
- delete itr->second;
- }
- m_pState->WorldsByName.clear();
-}
-
-
-
-
-
-cWorld* cRoot::GetDefaultWorld()
-{
- return m_pState->pDefaultWorld;
-}
-
-
-
-
-
-cWorld* cRoot::GetWorld( const AString & a_WorldName )
-{
- WorldMap::iterator itr = m_pState->WorldsByName.find( a_WorldName );
- if( itr != m_pState->WorldsByName.end() )
- return itr->second;
- return 0;
-}
-
-
-
-
-
-bool cRoot::ForEachWorld(cWorldListCallback & a_Callback)
-{
- for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr )
- {
- if (a_Callback.Item(itr->second))
- {
- return false;
- }
- }
- return true;
-}
-
-
-
-
-
-void cRoot::TickWorlds( float a_Dt )
-{
- for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr )
- {
- itr->second->Tick( a_Dt );
- }
-}
-
-
-
-
-
-void cRoot::ServerCommand( const char * a_Cmd )
-{
- LOG("Server console command: \"%s\"", a_Cmd );
- m_Server->ServerCommand( a_Cmd );
- if( strcmp(a_Cmd, "stop") == 0 )
- {
- m_bStop = true;
- }
- else if( strcmp( a_Cmd, "restart") == 0 )
- {
- m_bRestart = true;
- }
-}
-
-
-
-
-
-void cRoot::KickUser(int a_ClientID, const AString & a_Reason)
-{
- m_Server->KickUser(a_ClientID, a_Reason);
-}
-
-
-
-
-
-void cRoot::AuthenticateUser(int a_ClientID)
-{
- m_Server->AuthenticateUser(a_ClientID);
-}
-
-
-
-
-
-int cRoot::GetTotalChunkCount(void)
-{
- int res = 0;
- for ( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr )
- {
- res += itr->second->GetNumChunks();
- }
- return res;
-}
-
-
-
-
-
-void cRoot::SaveAllChunks(void)
-{
- for (WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr)
- {
- itr->second->SaveAllChunks();
- }
-}
-
-
-
-
-
-bool cRoot::ForEachPlayer(cPlayerListCallback & a_Callback)
-{
- for (WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr)
- {
- if (!itr->second->ForEachPlayer(a_Callback))
- {
- return false;
- }
- }
- return true;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cRoot.h" +#include "cServer.h" +#include "cWorld.h" +#include "cWebAdmin.h" +#include "cFurnaceRecipe.h" +#include "cGroupManager.h" +#include "CraftingRecipes.h" +#include "cPluginManager.h" +#include "cMonsterConfig.h" +#include "cSleep.h" +#include "cThread.h" +#include "cFileFormatUpdater.h" +#include "cRedstone.h" + +#include "../iniFile/iniFile.h" + +#include <iostream> + + + + + +cRoot* cRoot::s_Root = 0; + +typedef std::map< AString, cWorld* > WorldMap; +struct cRoot::sRootState +{ + cWorld* pDefaultWorld; + WorldMap WorldsByName; +}; + + + + + +cRoot::cRoot() + : m_Server( 0 ) + , m_MonsterConfig( 0 ) + , m_GroupManager( 0 ) + , m_CraftingRecipes(NULL) + , m_FurnaceRecipe( 0 ) + , m_WebAdmin( 0 ) + , m_PluginManager( 0 ) + , m_Log( 0 ) + , m_bStop( false ) + , m_bRestart( false ) + , m_InputThread( 0 ) + , m_pState( new sRootState ) +{ + s_Root = this; +} + + + + + +cRoot::~cRoot() +{ + s_Root = 0; + delete m_pState; +} + + + + + +void cRoot::InputThread(void* a_Params) +{ + cRoot& self = *(cRoot*)a_Params; + + while( !(self.m_bStop || self.m_bRestart) ) + { + std::string Command; + std::getline(std::cin, Command); + self.ServerCommand( Command.c_str() ); + } +} + + + + + +void cRoot::Start() +{ + delete m_Log; + m_Log = new cMCLogger(); + + m_bStop = false; + while (!m_bStop) + { + m_bRestart = false; + + LoadGlobalSettings(); + + cFileFormatUpdater::UpdateFileFormat(); + + LOG("Creating new server instance..."); + m_Server = new cServer(); + + LOG("Starting server..."); + cIniFile IniFile("settings.ini"); + IniFile.ReadFile(); + int Port = IniFile.GetValueSetI("Server", "Port", 25565 ); + if(!m_Server->InitServer( Port )) + { + LOG("Failed to start server, shutting down."); + return; + } + IniFile.WriteFile(); + + cIniFile WebIniFile("webadmin.ini"); + if( WebIniFile.ReadFile() ) + { + if( WebIniFile.GetValueB("WebAdmin", "Enabled", false ) == true ) + { + LOG("Creating WebAdmin..."); + m_WebAdmin = new cWebAdmin(8080); + } + } + + LOG("Loading settings..."); + m_GroupManager = new cGroupManager(); + m_CraftingRecipes = new cCraftingRecipes; + m_FurnaceRecipe = new cFurnaceRecipe(); + + LOG("Loading worlds..."); + LoadWorlds(); + + LOG("Loading plugin manager..."); + m_PluginManager = new cPluginManager(); // This should be last + m_PluginManager->ReloadPluginsNow(); + + LOG("Loading MonsterConfig..."); + m_MonsterConfig = new cMonsterConfig; + + // This sets stuff in motion + LOG("Starting Authenticator..."); + m_Authenticator.Start(); + + LOG("Starting worlds..."); + StartWorlds(); + + LOG("Starting server..."); + m_Server->StartListenThread(); + //cHeartBeat* HeartBeat = new cHeartBeat(); + + LOG("Starting InputThread..."); + m_InputThread = new cThread( InputThread, this, "cRoot::InputThread" ); + m_InputThread->Start( true ); + + LOG("Initialization done, server running now."); + while( !m_bStop && !m_bRestart ) // These are modified by external threads + { + cSleep::MilliSleep( 1000 ); + } + + delete m_InputThread; m_InputThread = 0; + + // Deallocate stuffs + LOG("Shutting down server..."); + m_Server->Shutdown(); // This waits for threads to stop and d/c clients + LOG("Stopping authenticator..."); + m_Authenticator.Stop(); + LOG("Stopping plugin manager..."); + delete m_PluginManager; m_PluginManager = 0; // This should be first + LOG("Freeing MonsterConfig..."); + delete m_MonsterConfig; m_MonsterConfig = 0; + LOG("Stopping WebAdmin..."); + delete m_WebAdmin; m_WebAdmin = 0; + LOG("Unloading recipes..."); + delete m_FurnaceRecipe; m_FurnaceRecipe = NULL; + delete m_CraftingRecipes; m_CraftingRecipes = NULL; + LOG("Forgetting groups..."); + delete m_GroupManager; m_GroupManager = 0; + LOG("Unloading worlds..."); + UnloadWorlds(); + LOG("Destroying server..."); + //delete HeartBeat; HeartBeat = 0; + delete m_Server; m_Server = 0; + LOG("Shutdown done."); + } + + delete m_Log; m_Log = 0; +} + + + + + +void cRoot::LoadGlobalSettings() +{ + cIniFile IniFile("settings.ini"); + if( IniFile.ReadFile() ) + { + cRedstone::s_UseRedstone = IniFile.GetValueB("Redstone", "SimulateRedstone", true ); + } +} + + + + + +void cRoot::LoadWorlds(void) +{ + cIniFile IniFile("settings.ini"); IniFile.ReadFile(); + + // First get the default world + AString DefaultWorldName = IniFile.GetValueSet("Worlds", "DefaultWorld", "world"); + m_pState->pDefaultWorld = new cWorld( DefaultWorldName.c_str() ); + m_pState->WorldsByName[ DefaultWorldName ] = m_pState->pDefaultWorld; + + // Then load the other worlds + unsigned int KeyNum = IniFile.FindKey("Worlds"); + unsigned int NumWorlds = IniFile.GetNumValues( KeyNum ); + if (NumWorlds <= 0) + { + return; + } + + for (unsigned int i = 0; i < NumWorlds; i++) + { + AString ValueName = IniFile.GetValueName(KeyNum, i ); + if (ValueName.compare("World") != 0) + { + continue; + } + AString WorldName = IniFile.GetValue(KeyNum, i ); + if (WorldName.empty()) + { + continue; + } + cWorld* NewWorld = new cWorld( WorldName.c_str() ); + m_pState->WorldsByName[ WorldName ] = NewWorld; + } // for i - Worlds +} + + + + + +void cRoot::StartWorlds(void) +{ + for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) + { + itr->second->InitializeSpawn(); + } +} + + + + + +void cRoot::UnloadWorlds(void) +{ + for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) + { + delete itr->second; + } + m_pState->WorldsByName.clear(); +} + + + + + +cWorld* cRoot::GetDefaultWorld() +{ + return m_pState->pDefaultWorld; +} + + + + + +cWorld* cRoot::GetWorld( const AString & a_WorldName ) +{ + WorldMap::iterator itr = m_pState->WorldsByName.find( a_WorldName ); + if( itr != m_pState->WorldsByName.end() ) + return itr->second; + return 0; +} + + + + + +bool cRoot::ForEachWorld(cWorldListCallback & a_Callback) +{ + for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) + { + if (a_Callback.Item(itr->second)) + { + return false; + } + } + return true; +} + + + + + +void cRoot::TickWorlds( float a_Dt ) +{ + for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) + { + itr->second->Tick( a_Dt ); + } +} + + + + + +void cRoot::ServerCommand( const char * a_Cmd ) +{ + LOG("Server console command: \"%s\"", a_Cmd ); + m_Server->ServerCommand( a_Cmd ); + if( strcmp(a_Cmd, "stop") == 0 ) + { + m_bStop = true; + } + else if( strcmp( a_Cmd, "restart") == 0 ) + { + m_bRestart = true; + } +} + + + + + +void cRoot::KickUser(int a_ClientID, const AString & a_Reason) +{ + m_Server->KickUser(a_ClientID, a_Reason); +} + + + + + +void cRoot::AuthenticateUser(int a_ClientID) +{ + m_Server->AuthenticateUser(a_ClientID); +} + + + + + +int cRoot::GetTotalChunkCount(void) +{ + int res = 0; + for ( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) + { + res += itr->second->GetNumChunks(); + } + return res; +} + + + + + +void cRoot::SaveAllChunks(void) +{ + for (WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr) + { + itr->second->SaveAllChunks(); + } +} + + + + + +bool cRoot::ForEachPlayer(cPlayerListCallback & a_Callback) +{ + for (WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr) + { + if (!itr->second->ForEachPlayer(a_Callback)) + { + return false; + } + } + return true; +} + + + + diff --git a/source/cRoot.h b/source/cRoot.h index 7b0a7ea18..21bd39f7d 100644 --- a/source/cRoot.h +++ b/source/cRoot.h @@ -1,109 +1,109 @@ -
-#pragma once
-
-
-
-
-#include "cAuthenticator.h"
-
-
-
-
-
-class cThread;
-class cMonsterConfig;
-class cGroupManager;
-class cCraftingRecipes;
-class cFurnaceRecipe;
-class cWebAdmin;
-class cPluginManager;
-class cServer;
-class cWorld;
-class cPlayer;
-typedef cItemCallback<cPlayer> cPlayerListCallback;
-typedef cItemCallback<cWorld> cWorldListCallback;
-
-
-
-
-
-class cRoot //tolua_export
-{ //tolua_export
-public:
- static cRoot* Get() { return s_Root; } //tolua_export
-
- cRoot(void);
- ~cRoot();
-
- void Start(void);
-
- cServer * GetServer(void) { return m_Server; } //tolua_export
- cWorld * GetDefaultWorld(void); //tolua_export
- cWorld * GetWorld(const AString & a_WorldName); //tolua_export
-
- /// Calls the callback for each world; returns true if the callback didn't abort (return true)
- bool ForEachWorld(cWorldListCallback & a_Callback); // >> Exported in ManualBindings <<
-
- cMonsterConfig * GetMonsterConfig() { return m_MonsterConfig; }
-
- cGroupManager * GetGroupManager (void) { return m_GroupManager; } // tolua_export
- cCraftingRecipes * GetCraftingRecipes(void) { return m_CraftingRecipes; } // tolua_export
- cFurnaceRecipe * GetFurnaceRecipe (void) { return m_FurnaceRecipe; } // tolua_export
- cWebAdmin * GetWebAdmin (void) { return m_WebAdmin; } // tolua_export
- cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export
- cAuthenticator & GetAuthenticator (void) { return m_Authenticator; }
-
- void ServerCommand(const char* a_Cmd ); //tolua_export
-
- void KickUser(int a_ClientID, const AString & a_Reason); // Kicks the user, no matter in what world they are. Used from cAuthenticator
- void AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user
-
- void TickWorlds( float a_Dt );
-
- /// Returns the number of chunks loaded
- int GetTotalChunkCount(void); // tolua_export
-
- /// Saves all chunks in all worlds
- void SaveAllChunks(void);
-
- /// Calls the callback for each player in all worlds
- bool ForEachPlayer(cPlayerListCallback & a_Callback);
-
-private:
- void LoadGlobalSettings();
-
- /// Loads the worlds from settings.ini, creates the worldmap
- void LoadWorlds(void);
-
- /// Starts each world's life
- void StartWorlds(void);
-
- void UnloadWorlds(void);
-
- cServer * m_Server;
- cMonsterConfig * m_MonsterConfig;
-
- cGroupManager * m_GroupManager;
- cCraftingRecipes * m_CraftingRecipes;
- cFurnaceRecipe * m_FurnaceRecipe;
- cWebAdmin * m_WebAdmin;
- cPluginManager * m_PluginManager;
- cAuthenticator m_Authenticator;
-
- cMCLogger * m_Log;
-
- bool m_bStop;
- bool m_bRestart;
-
- struct sRootState;
- sRootState* m_pState;
-
- cThread* m_InputThread;
- static void InputThread(void* a_Params);
-
- static cRoot* s_Root;
-}; //tolua_export
-
-
-
-
+ +#pragma once + + + + +#include "cAuthenticator.h" + + + + + +class cThread; +class cMonsterConfig; +class cGroupManager; +class cCraftingRecipes; +class cFurnaceRecipe; +class cWebAdmin; +class cPluginManager; +class cServer; +class cWorld; +class cPlayer; +typedef cItemCallback<cPlayer> cPlayerListCallback; +typedef cItemCallback<cWorld> cWorldListCallback; + + + + + +class cRoot //tolua_export +{ //tolua_export +public: + static cRoot* Get() { return s_Root; } //tolua_export + + cRoot(void); + ~cRoot(); + + void Start(void); + + cServer * GetServer(void) { return m_Server; } //tolua_export + cWorld * GetDefaultWorld(void); //tolua_export + cWorld * GetWorld(const AString & a_WorldName); //tolua_export + + /// Calls the callback for each world; returns true if the callback didn't abort (return true) + bool ForEachWorld(cWorldListCallback & a_Callback); // >> Exported in ManualBindings << + + cMonsterConfig * GetMonsterConfig() { return m_MonsterConfig; } + + cGroupManager * GetGroupManager (void) { return m_GroupManager; } // tolua_export + cCraftingRecipes * GetCraftingRecipes(void) { return m_CraftingRecipes; } // tolua_export + cFurnaceRecipe * GetFurnaceRecipe (void) { return m_FurnaceRecipe; } // tolua_export + cWebAdmin * GetWebAdmin (void) { return m_WebAdmin; } // tolua_export + cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export + cAuthenticator & GetAuthenticator (void) { return m_Authenticator; } + + void ServerCommand(const char* a_Cmd ); //tolua_export + + void KickUser(int a_ClientID, const AString & a_Reason); // Kicks the user, no matter in what world they are. Used from cAuthenticator + void AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user + + void TickWorlds( float a_Dt ); + + /// Returns the number of chunks loaded + int GetTotalChunkCount(void); // tolua_export + + /// Saves all chunks in all worlds + void SaveAllChunks(void); + + /// Calls the callback for each player in all worlds + bool ForEachPlayer(cPlayerListCallback & a_Callback); + +private: + void LoadGlobalSettings(); + + /// Loads the worlds from settings.ini, creates the worldmap + void LoadWorlds(void); + + /// Starts each world's life + void StartWorlds(void); + + void UnloadWorlds(void); + + cServer * m_Server; + cMonsterConfig * m_MonsterConfig; + + cGroupManager * m_GroupManager; + cCraftingRecipes * m_CraftingRecipes; + cFurnaceRecipe * m_FurnaceRecipe; + cWebAdmin * m_WebAdmin; + cPluginManager * m_PluginManager; + cAuthenticator m_Authenticator; + + cMCLogger * m_Log; + + bool m_bStop; + bool m_bRestart; + + struct sRootState; + sRootState* m_pState; + + cThread* m_InputThread; + static void InputThread(void* a_Params); + + static cRoot* s_Root; +}; //tolua_export + + + + diff --git a/source/cSandSimulator.cpp b/source/cSandSimulator.cpp index 3fe678f90..6e5c5ecde 100644 --- a/source/cSandSimulator.cpp +++ b/source/cSandSimulator.cpp @@ -1,91 +1,91 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cSandSimulator.h"
-#include "cWorld.h"
-#include "Vector3i.h"
-#include "BlockID.h"
-#include "Defines.h"
-
-
-
-
-
-cSandSimulator::cSandSimulator( cWorld* a_World )
- : cSimulator(a_World)
- , m_Blocks(new BlockList)
- , m_Buffer(new BlockList)
-{
-
-}
-
-cSandSimulator::~cSandSimulator()
-{
- delete m_Buffer;
- delete m_Blocks;
-}
-
-void cSandSimulator::Simulate( float a_Dt )
-{
- m_Buffer->clear();
- std::swap( m_Blocks, m_Buffer );
-
- for( BlockList::iterator itr = m_Buffer->begin(); itr != m_Buffer->end(); ++itr )
- {
- Vector3i Pos = *itr;
- char BlockID = m_World->GetBlock(Pos.x, Pos.y, Pos.z);
- if(!IsAllowedBlock(BlockID))
- continue;
-
- char BottomBlock = m_World->GetBlock( Pos.x, Pos.y - 1, Pos.z );
-
- if( IsPassable(BottomBlock) )
- {
- m_World->SetBlock( Pos.x, Pos.y, Pos.z, E_BLOCK_AIR, 0 );
- m_World->SetBlock( Pos.x, Pos.y - 1, Pos.z, BlockID, 0 );
- }
- }
-
-}
-
-
-bool cSandSimulator::IsAllowedBlock( char a_BlockID )
-{
- return a_BlockID == E_BLOCK_SAND
- || a_BlockID == E_BLOCK_GRAVEL;
-}
-
-void cSandSimulator::AddBlock(int a_X, int a_Y, int a_Z)
-{
- if(!IsAllowedBlock(m_World->GetBlock(a_X, a_Y, a_Z))) //This should save very much time because it doesn´t have to iterate through all blocks
- return;
-
- Vector3i Block(a_X, a_Y, a_Z);
-
- //check for duplicates
- for( BlockList::iterator itr = m_Blocks->begin(); itr != m_Blocks->end(); ++itr )
- {
- Vector3i Pos = *itr;
- if( Pos.x == a_X && Pos.y == a_Y && Pos.z == a_Z )
- return;
- }
-
- m_Blocks->push_back(Block);
-
-}
-
-bool cSandSimulator::IsPassable( char a_BlockID )
-{
- return a_BlockID == E_BLOCK_AIR
- || IsBlockWater(a_BlockID)
- || IsBlockLava(a_BlockID)
- || a_BlockID == E_BLOCK_FIRE;
-
-}
-
-void cSandSimulator::WakeUp( int a_X, int a_Y, int a_Z )
-{
- //Nothing else needs to be simulated :D (Bugs not included :s)
- AddBlock( a_X, a_Y+1, a_Z );
- AddBlock( a_X, a_Y, a_Z );
-}
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSandSimulator.h" +#include "cWorld.h" +#include "Vector3i.h" +#include "BlockID.h" +#include "Defines.h" + + + + + +cSandSimulator::cSandSimulator( cWorld* a_World ) + : cSimulator(a_World) + , m_Blocks(new BlockList) + , m_Buffer(new BlockList) +{ + +} + +cSandSimulator::~cSandSimulator() +{ + delete m_Buffer; + delete m_Blocks; +} + +void cSandSimulator::Simulate( float a_Dt ) +{ + m_Buffer->clear(); + std::swap( m_Blocks, m_Buffer ); + + for( BlockList::iterator itr = m_Buffer->begin(); itr != m_Buffer->end(); ++itr ) + { + Vector3i Pos = *itr; + char BlockID = m_World->GetBlock(Pos.x, Pos.y, Pos.z); + if(!IsAllowedBlock(BlockID)) + continue; + + char BottomBlock = m_World->GetBlock( Pos.x, Pos.y - 1, Pos.z ); + + if( IsPassable(BottomBlock) ) + { + m_World->SetBlock( Pos.x, Pos.y, Pos.z, E_BLOCK_AIR, 0 ); + m_World->SetBlock( Pos.x, Pos.y - 1, Pos.z, BlockID, 0 ); + } + } + +} + + +bool cSandSimulator::IsAllowedBlock( char a_BlockID ) +{ + return a_BlockID == E_BLOCK_SAND + || a_BlockID == E_BLOCK_GRAVEL; +} + +void cSandSimulator::AddBlock(int a_X, int a_Y, int a_Z) +{ + if(!IsAllowedBlock(m_World->GetBlock(a_X, a_Y, a_Z))) //This should save very much time because it doesn´t have to iterate through all blocks + return; + + Vector3i Block(a_X, a_Y, a_Z); + + //check for duplicates + for( BlockList::iterator itr = m_Blocks->begin(); itr != m_Blocks->end(); ++itr ) + { + Vector3i Pos = *itr; + if( Pos.x == a_X && Pos.y == a_Y && Pos.z == a_Z ) + return; + } + + m_Blocks->push_back(Block); + +} + +bool cSandSimulator::IsPassable( char a_BlockID ) +{ + return a_BlockID == E_BLOCK_AIR + || IsBlockWater(a_BlockID) + || IsBlockLava(a_BlockID) + || a_BlockID == E_BLOCK_FIRE; + +} + +void cSandSimulator::WakeUp( int a_X, int a_Y, int a_Z ) +{ + //Nothing else needs to be simulated :D (Bugs not included :s) + AddBlock( a_X, a_Y+1, a_Z ); + AddBlock( a_X, a_Y, a_Z ); +} diff --git a/source/cSandSimulator.h b/source/cSandSimulator.h index c99092726..c95d5e476 100644 --- a/source/cSandSimulator.h +++ b/source/cSandSimulator.h @@ -1,40 +1,40 @@ -
-#pragma once
-
-#include "cSimulator.h"
-#include "cBlockEntity.h"
-#include "Vector3i.h"
-
-
-
-
-
-class cWorld;
-
-
-
-
-
-class cSandSimulator : public cSimulator
-{
-public:
- cSandSimulator( cWorld* a_World );
- ~cSandSimulator();
-
- virtual void Simulate( float a_Dt );
- virtual void WakeUp( int a_X, int a_Y, int a_Z );
-
- virtual bool IsAllowedBlock( char a_BlockID );
- virtual bool IsPassable( char a_BlockID );
-
-protected:
- virtual void AddBlock(int a_X, int a_Y, int a_Z);
-
- typedef std::list <Vector3i> BlockList;
- BlockList * m_Blocks;
- BlockList * m_Buffer;
-};
-
-
-
-
+ +#pragma once + +#include "cSimulator.h" +#include "cBlockEntity.h" +#include "Vector3i.h" + + + + + +class cWorld; + + + + + +class cSandSimulator : public cSimulator +{ +public: + cSandSimulator( cWorld* a_World ); + ~cSandSimulator(); + + virtual void Simulate( float a_Dt ); + virtual void WakeUp( int a_X, int a_Y, int a_Z ); + + virtual bool IsAllowedBlock( char a_BlockID ); + virtual bool IsPassable( char a_BlockID ); + +protected: + virtual void AddBlock(int a_X, int a_Y, int a_Z); + + typedef std::list <Vector3i> BlockList; + BlockList * m_Blocks; + BlockList * m_Buffer; +}; + + + + diff --git a/source/cSemaphore.cpp b/source/cSemaphore.cpp index 6fe8f6d5b..468de6858 100644 --- a/source/cSemaphore.cpp +++ b/source/cSemaphore.cpp @@ -1,91 +1,91 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-
-
-
-
-cSemaphore::cSemaphore( unsigned int a_MaxCount, unsigned int a_InitialCount /* = 0 */ )
-#ifndef _WIN32
- : m_bNamed( false )
-#endif
-{
-#ifndef _WIN32
- (void)a_MaxCount;
- m_Handle = new sem_t;
- if (sem_init( (sem_t*)m_Handle, 0, 0))
- {
- LOG("WARNING cSemaphore: Could not create unnamed semaphore, fallback to named.");
- delete (sem_t*)m_Handle; // named semaphores return their own address
- m_bNamed = true;
-
- AString Name;
- Printf(Name, "cSemaphore%p", this );
- m_Handle = sem_open(Name.c_str(), O_CREAT, 777, a_InitialCount);
- if( m_Handle == SEM_FAILED )
- {
- LOG("ERROR: Could not create Semaphore. (%i)", errno );
- }
- else
- {
- if( sem_unlink(Name.c_str()) != 0 )
- {
- LOG("ERROR: Could not unlink cSemaphore. (%i)", errno);
- }
- }
- }
-#else
- m_Handle = CreateSemaphore(
- NULL, // security attribute
- a_InitialCount, // initial count
- a_MaxCount, // maximum count
- 0 // name (optional)
- );
-#endif
-}
-
-cSemaphore::~cSemaphore()
-{
-#ifdef _WIN32
- CloseHandle( m_Handle );
-#else
- if( m_bNamed )
- {
- if( sem_close( (sem_t*)m_Handle ) != 0 )
- {
- LOG("ERROR: Could not close cSemaphore. (%i)", errno);
- }
- }
- else
- {
- sem_destroy( (sem_t*)m_Handle );
- delete (sem_t*)m_Handle;
- }
- m_Handle = 0;
-
-#endif
-}
-
-void cSemaphore::Wait()
-{
-#ifndef _WIN32
- if( sem_wait( (sem_t*)m_Handle ) != 0)
- {
- LOG("ERROR: Could not wait for cSemaphore. (%i)", errno);
- }
-#else
- WaitForSingleObject( m_Handle, INFINITE);
-#endif
-}
-
-void cSemaphore::Signal()
-{
-#ifndef _WIN32
- if( sem_post( (sem_t*)m_Handle ) != 0 )
- {
- LOG("ERROR: Could not signal cSemaphore. (%i)", errno);
- }
-#else
- ReleaseSemaphore( m_Handle, 1, NULL );
-#endif
-}
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + + + + + +cSemaphore::cSemaphore( unsigned int a_MaxCount, unsigned int a_InitialCount /* = 0 */ ) +#ifndef _WIN32 + : m_bNamed( false ) +#endif +{ +#ifndef _WIN32 + (void)a_MaxCount; + m_Handle = new sem_t; + if (sem_init( (sem_t*)m_Handle, 0, 0)) + { + LOG("WARNING cSemaphore: Could not create unnamed semaphore, fallback to named."); + delete (sem_t*)m_Handle; // named semaphores return their own address + m_bNamed = true; + + AString Name; + Printf(Name, "cSemaphore%p", this ); + m_Handle = sem_open(Name.c_str(), O_CREAT, 777, a_InitialCount); + if( m_Handle == SEM_FAILED ) + { + LOG("ERROR: Could not create Semaphore. (%i)", errno ); + } + else + { + if( sem_unlink(Name.c_str()) != 0 ) + { + LOG("ERROR: Could not unlink cSemaphore. (%i)", errno); + } + } + } +#else + m_Handle = CreateSemaphore( + NULL, // security attribute + a_InitialCount, // initial count + a_MaxCount, // maximum count + 0 // name (optional) + ); +#endif +} + +cSemaphore::~cSemaphore() +{ +#ifdef _WIN32 + CloseHandle( m_Handle ); +#else + if( m_bNamed ) + { + if( sem_close( (sem_t*)m_Handle ) != 0 ) + { + LOG("ERROR: Could not close cSemaphore. (%i)", errno); + } + } + else + { + sem_destroy( (sem_t*)m_Handle ); + delete (sem_t*)m_Handle; + } + m_Handle = 0; + +#endif +} + +void cSemaphore::Wait() +{ +#ifndef _WIN32 + if( sem_wait( (sem_t*)m_Handle ) != 0) + { + LOG("ERROR: Could not wait for cSemaphore. (%i)", errno); + } +#else + WaitForSingleObject( m_Handle, INFINITE); +#endif +} + +void cSemaphore::Signal() +{ +#ifndef _WIN32 + if( sem_post( (sem_t*)m_Handle ) != 0 ) + { + LOG("ERROR: Could not signal cSemaphore. (%i)", errno); + } +#else + ReleaseSemaphore( m_Handle, 1, NULL ); +#endif +} diff --git a/source/cSemaphore.h b/source/cSemaphore.h index 42966b410..fbe8907f1 100644 --- a/source/cSemaphore.h +++ b/source/cSemaphore.h @@ -1,17 +1,17 @@ -#pragma once
-
-class cSemaphore
-{
-public:
- cSemaphore( unsigned int a_MaxCount, unsigned int a_InitialCount = 0 );
- ~cSemaphore();
-
- void Wait();
- void Signal();
-private:
- void* m_Handle; // HANDLE pointer
-
-#ifndef _WIN32
- bool m_bNamed;
-#endif
-};
+#pragma once + +class cSemaphore +{ +public: + cSemaphore( unsigned int a_MaxCount, unsigned int a_InitialCount = 0 ); + ~cSemaphore(); + + void Wait(); + void Signal(); +private: + void* m_Handle; // HANDLE pointer + +#ifndef _WIN32 + bool m_bNamed; +#endif +}; diff --git a/source/cServer.cpp b/source/cServer.cpp index c0b38c88b..65691e0cf 100644 --- a/source/cServer.cpp +++ b/source/cServer.cpp @@ -1,738 +1,738 @@ -
-// ReDucTor is an awesome guy who helped me a lot
-
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cServer.h"
-#include "cClientHandle.h"
-#include "cSleep.h"
-#include "cTimer.h"
-#include "cMonster.h"
-#include "cSocket.h"
-#include "cRoot.h"
-#include "cWorld.h"
-#include "ChunkDef.h"
-#include "cPluginManager.h"
-#include "cGroupManager.h"
-#include "cChatColor.h"
-#include "cPlayer.h"
-#include "cInventory.h"
-#include "cItem.h"
-#include "cFurnaceRecipe.h"
-#include "cTracer.h"
-#include "cWebAdmin.h"
-#include "cChunk.h"
-
-#include "MersenneTwister.h"
-
-#include "../iniFile/iniFile.h"
-#include "Vector3f.h"
-
-#include "packets/cPacket_Chat.h"
-
-#include <fstream>
-#include <sstream>
-#include <iostream>
-
-
-
-
-
-extern "C" {
- #include "zlib.h"
-}
-
-
-
-bool g_bWaterPhysics = false;
-
-typedef std::list< cClientHandle* > ClientList;
-
-
-
-
-
-struct cServer::sServerState
-{
- sServerState()
- : pListenThread( 0 )
- , pTickThread( 0 )
- , bStopListenThread( false )
- , bStopTickThread( false )
- {}
- cSocket SListenClient; // socket listening for client calls
-
- cThread* pListenThread; bool bStopListenThread;
- cThread* pTickThread; bool bStopTickThread;
-
- cEvent RestartEvent;
- std::string ServerID;
-};
-
-
-
-
-
-cServer * cServer::GetServer()
-{
- LOGWARN("WARNING: Using deprecated function cServer::GetServer() use cRoot::Get()->GetServer() instead!");
- return cRoot::Get()->GetServer();
-}
-
-
-
-
-
-void cServer::ServerListenThread( void *a_Args )
-{
- LOG("ServerListenThread");
- cServer* self = (cServer*)a_Args;
- sServerState* m_pState = self->m_pState;
- while( !m_pState->bStopListenThread )
- {
- self->StartListenClient();
- }
-}
-
-
-
-
-
-void cServer::ClientDestroying(const cClientHandle * a_Client)
-{
- m_SocketThreads.StopReading(a_Client);
-}
-
-
-
-
-
-void cServer::NotifyClientWrite(const cClientHandle * a_Client)
-{
- m_NotifyWriteThread.NotifyClientWrite(a_Client);
-}
-
-
-
-
-
-void cServer::WriteToClient(const cSocket * a_Socket, const AString & a_Data)
-{
- m_SocketThreads.Write(a_Socket, a_Data);
-}
-
-
-
-
-
-void cServer::QueueClientClose(const cSocket * a_Socket)
-{
- m_SocketThreads.QueueClose(a_Socket);
-}
-
-
-
-
-
-void cServer::RemoveClient(const cSocket * a_Socket)
-{
- m_SocketThreads.RemoveClient(a_Socket);
-}
-
-
-
-
-
-bool cServer::InitServer( int a_Port )
-{
- if( m_bIsConnected )
- {
- LOGERROR("ERROR: Trying to initialize server while server is already running!");
- return false;
- }
-
- printf("/============================\\\n");
- printf("| Custom Minecraft Server |\n");
- printf("| Created by Kevin Bansberg |\n");
- printf("| A.K.A. FakeTruth |\n");
- printf("| Monsters by Alex Sonek |\n");
- printf("| A.K.A. Duralex |\n");
- printf("| Stuff by Mattes D |\n");
- printf("| A.K.A. _Xoft(o) |\n");
- printf("\\============================/\n");
- printf("More info: WWW.MC-SERVER.ORG\n");
- printf(" WWW.AE-C.NET\n");
- printf(" WWW.RBTHINKTANK.COM\n");
- printf("email: faketruth@gmail.com\n\n");
-
- LOG("Starting up server.");
- LOGINFO("Compatible clients: %s, protocol version %d", MCS_CLIENT_VERSION, MCS_PROTOCOL_VERSION);
-
- if( cSocket::WSAStartup() != 0 ) // Only does anything on Windows, but whatever
- {
- LOGERROR("WSAStartup() != 0");
- return false;
- }
-
- m_pState->SListenClient = cSocket::CreateSocket();
-
- if( !m_pState->SListenClient.IsValid() )
- {
- LOGERROR("m_SListenClient==INVALID_SOCKET (%s)", cSocket::GetErrorString( cSocket::GetLastError() ).c_str() );
- return false;
- }
-
- if( m_pState->SListenClient.SetReuseAddress() == -1 )
- {
- LOGERROR("setsockopt == -1");
- return false;
- }
-
- cSocket::SockAddr_In local;
- local.Family = cSocket::ADDRESS_FAMILY_INTERNET;
- local.Address = cSocket::INTERNET_ADDRESS_ANY;
- local.Port = (unsigned short)a_Port; // 25565
-
- if( m_pState->SListenClient.Bind( local ) != 0 )
- {
- LOGERROR("bind fail (%s)", cSocket::GetErrorString( cSocket::GetLastError() ).c_str() );
- return false;
- }
-
- if( m_pState->SListenClient.Listen( 10 ) != 0)
- {
- LOGERROR("listen fail (%s)", cSocket::GetErrorString( cSocket::GetLastError() ).c_str() );
- return false;
- }
-
- m_iServerPort = a_Port;
- LOG("Port %i has been bound, server is open for connections", m_iServerPort);
- m_bIsConnected = true;
-
- cIniFile IniFile("settings.ini");
- if (IniFile.ReadFile())
- {
- g_bWaterPhysics = IniFile.GetValueB("Physics", "Water", false );
-
- m_pState->ServerID = "-";
- if (IniFile.GetValueB("Authentication", "Authenticate"))
- {
- MTRand mtrand1;
- unsigned int r1 = (mtrand1.randInt()%1147483647) + 1000000000;
- unsigned int r2 = (mtrand1.randInt()%1147483647) + 1000000000;
- std::ostringstream sid;
- sid << std::hex << r1;
- sid << std::hex << r2;
- std::string ServerID = sid.str();
- ServerID.resize(16, '0');
- m_pState->ServerID = ServerID;
- }
-
- m_ClientViewDistance = IniFile.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE);
- if (m_ClientViewDistance < cClientHandle::MIN_VIEW_DISTANCE)
- {
- m_ClientViewDistance = cClientHandle::MIN_VIEW_DISTANCE;
- LOGINFO("Setting default viewdistance to the minimum of %d", m_ClientViewDistance);
- }
- if (m_ClientViewDistance > cClientHandle::MAX_VIEW_DISTANCE)
- {
- m_ClientViewDistance = cClientHandle::MAX_VIEW_DISTANCE;
- LOGINFO("Setting default viewdistance to the maximum of %d", m_ClientViewDistance);
- }
- IniFile.WriteFile();
- }
-
- m_NotifyWriteThread.Start(this);
-
- return true;
-}
-
-
-
-
-
-cServer::cServer()
- : m_pState( new sServerState )
- , m_Millisecondsf( 0 )
- , m_Milliseconds( 0 )
- , m_bIsConnected( false )
- , m_iServerPort( 0 )
- , m_bRestarting( false )
-{
-}
-
-
-
-
-
-cServer::~cServer()
-{
- // TODO: Shut down the server gracefully
- if ( m_pState->SListenClient )
- {
- m_pState->SListenClient.CloseSocket();
- }
- m_pState->SListenClient = 0;
-
- m_pState->bStopListenThread = true;
- delete m_pState->pListenThread; m_pState->pListenThread = NULL;
- m_pState->bStopTickThread = true;
- delete m_pState->pTickThread; m_pState->pTickThread = NULL;
-
- delete m_pState;
-}
-
-
-
-
-
-// TODO - Need to modify this or something, so it broadcasts to all worlds? And move this to cWorld?
-void cServer::Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude /* = 0 */ )
-{
- cCSLock Lock(m_CSClients);
- for( ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr)
- {
- if ((*itr == a_Exclude) || !(*itr)->IsLoggedIn())
- {
- continue;
- }
- (*itr)->Send( a_Packet );
- }
-}
-
-
-
-
-
-void cServer::StartListenClient()
-{
- cSocket SClient = m_pState->SListenClient.Accept();
-
- if (!SClient.IsValid())
- {
- return;
- }
-
- const AString & ClientIP = SClient.GetIPString();
- if (ClientIP.empty())
- {
- LOGWARN("cServer: A client connected, but didn't present its IP, disconnecting.");
- SClient.CloseSocket();
- return;
- }
-
- LOG("Client \"%s\" connected!", ClientIP.c_str());
-
- cClientHandle *NewHandle = new cClientHandle(SClient, m_ClientViewDistance);
- if (!m_SocketThreads.AddClient(&(NewHandle->GetSocket()), NewHandle))
- {
- // For some reason SocketThreads have rejected the handle, clean it up
- LOGERROR("Client \"%s\" cannot be handled, server probably unstable", SClient.GetIPString().c_str());
- SClient.CloseSocket();
- delete NewHandle;
- return;
- }
-
- cCSLock Lock(m_CSClients);
- m_Clients.push_back( NewHandle );
-}
-
-
-
-
-
-bool cServer::Tick(float a_Dt)
-{
- //LOG("1. Tick %0.2f", a_Dt);
- if( a_Dt > 100.f ) a_Dt = 100.f; // Don't go over 1/10 second
-
- m_Millisecondsf += a_Dt;
- if( m_Millisecondsf > 1.f )
- {
- m_Milliseconds += (int)m_Millisecondsf;
- m_Millisecondsf = m_Millisecondsf - (int)m_Millisecondsf;
- }
-
- cRoot::Get()->TickWorlds( a_Dt ); // TODO - Maybe give all worlds their own thread?
-
- cClientHandleList RemoveClients;
- {
- cCSLock Lock(m_CSClients);
- for (cClientHandleList::iterator itr = m_Clients.begin(); itr != m_Clients.end();)
- {
- if ((*itr)->IsDestroyed())
- {
- RemoveClients.push_back(*itr); // Remove the client later, when CS is not held, to avoid deadlock ( http://forum.mc-server.org/showthread.php?tid=374 )
- itr = m_Clients.erase(itr);
- continue;
- }
- (*itr)->Tick(a_Dt);
- ++itr;
- } // for itr - m_Clients[]
- }
- for (cClientHandleList::iterator itr = RemoveClients.begin(); itr != RemoveClients.end(); ++itr)
- {
- delete *itr;
- } // for itr - RemoveClients[]
-
- cRoot::Get()->GetPluginManager()->Tick( a_Dt );
-
- if( !m_bRestarting )
- {
- return true;
- }
- else
- {
- m_bRestarting = false;
- m_pState->RestartEvent.Set();
- return false;
- }
-}
-
-
-
-
-
-void ServerTickThread( void * a_Param )
-{
- LOG("ServerTickThread");
- cServer *CServerObj = (cServer*)a_Param;
-
- cTimer Timer;
-
- long long msPerTick = 50; // TODO - Put this in server config file
- long long LastTime = Timer.GetNowTime();
-
- bool bKeepGoing = true;
- while( bKeepGoing )
- {
- long long NowTime = Timer.GetNowTime();
- float DeltaTime = (float)(NowTime-LastTime);
- bKeepGoing = CServerObj->Tick( DeltaTime );
- long long TickTime = Timer.GetNowTime() - NowTime;
-
- if( TickTime < msPerTick ) // Stretch tick time until it's at least msPerTick
- {
- cSleep::MilliSleep( (unsigned int)( msPerTick - TickTime ) );
- }
-
- LastTime = NowTime;
- }
-
- LOG("TICK THREAD STOPPED");
-}
-
-
-
-
-
-void cServer::StartListenThread()
-{
- m_pState->pListenThread = new cThread( ServerListenThread, this, "cServer::ServerListenThread" );
- m_pState->pTickThread = new cThread( ServerTickThread, this, "cServer::ServerTickThread" );
- m_pState->pListenThread->Start( true );
- m_pState->pTickThread->Start( true );
-}
-
-
-
-
-
-template <class T>
-bool from_string(
- T& t,
- const std::string& s,
- std::ios_base& (*f)(std::ios_base&)
-)
-{
- std::istringstream iss(s);
- return !(iss >> f >> t).fail();
-}
-
-
-
-
-
-bool cServer::Command( cClientHandle & a_Client, const char* a_Cmd )
-{
- cPluginManager* PM = cRoot::Get()->GetPluginManager();
- if( PM->CallHook( cPluginManager::E_PLUGIN_CHAT, 2, a_Cmd, a_Client.GetPlayer() ) )
- {
- return true;
- }
- return false;
-}
-
-
-
-
-
-void cServer::ServerCommand( const char * a_Cmd )
-{
- AString Command( a_Cmd );
- AStringVector split = StringSplit( Command, " " );
- if( split.empty())
- {
- return;
- }
-
- if( split[0].compare( "help" ) == 0 )
- {
- printf("================== ALL COMMANDS ===================\n");
- printf("help - Shows this message\n");
- printf("save-all - Saves all loaded chunks to disk\n");
- printf("list - Lists all players currently in server\n");
- printf("unload - Unloads all unused chunks\n");
- printf("numchunks - Shows number of chunks currently loaded\n");
- printf("chunkstats - Shows chunks statistics\n");
- printf("say - Sends a chat message to all players\n");
- printf("restart - Kicks all clients, and saves everything\n");
- printf(" and clears memory\n");
- printf("stop - Saves everything and closes server\n");
- printf("===================================================\n");
- return;
- }
- if( split[0].compare( "stop" ) == 0 || split[0].compare( "restart" ) == 0 )
- {
- return;
- }
- if( split[0].compare( "save-all" ) == 0 )
- {
- cRoot::Get()->SaveAllChunks(); // TODO - Force ALL worlds to save their chunks
- return;
- }
- if (split[0].compare("unload") == 0)
- {
- LOG("Num loaded chunks before: %i", cRoot::Get()->GetTotalChunkCount() );
- cRoot::Get()->GetDefaultWorld()->UnloadUnusedChunks(); // TODO: Iterate through ALL worlds
- LOG("Num loaded chunks after: %i", cRoot::Get()->GetTotalChunkCount() );
- return;
- }
- if( split[0].compare( "list" ) == 0 )
- {
- class cPlayerLogger : public cPlayerListCallback
- {
- virtual bool Item(cPlayer * a_Player) override
- {
- LOG("\t%s @ %s", a_Player->GetName().c_str(), a_Player->GetClientHandle()->GetSocket().GetIPString().c_str());
- return false;
- }
- } Logger;
- cRoot::Get()->ForEachPlayer(Logger);
- return;
- }
- if( split[0].compare( "numchunks" ) == 0 )
- {
- LOG("Num loaded chunks: %i", cRoot::Get()->GetTotalChunkCount() );
- return;
- }
- if (split[0].compare("chunkstats") == 0)
- {
- // TODO: For each world
- int NumValid = 0;
- int NumDirty = 0;
- int NumInLighting = 0;
- cWorld * World = cRoot::Get()->GetDefaultWorld();
- int NumInGenerator = World->GetGeneratorQueueLength();
- int NumInSaveQueue = World->GetStorageSaveQueueLength();
- int NumInLoadQueue = World->GetStorageLoadQueueLength();
- World->GetChunkStats(NumValid, NumDirty, NumInLighting);
- LOG("Num loaded chunks: %d", NumValid);
- LOG("Num dirty chunks: %d", NumDirty);
- LOG("Num chunks in lighting queue: %d", NumInLighting);
- LOG("Num chunks in generator queue: %d", NumInGenerator);
- LOG("Num chunks in storage load queue: %d", NumInLoadQueue);
- LOG("Num chunks in storage save queue: %d", NumInSaveQueue);
- int Mem = NumValid * sizeof(cChunk);
- LOG("Memory used by chunks: %d KiB (%d MiB)", (Mem + 1023) / 1024, (Mem + 1024 * 1024 - 1) / (1024 * 1024));
- LOG("Per-chunk memory size breakdown:");
- LOG(" block types: %6d bytes (%3d KiB)", sizeof(cChunkDef::BlockTypes), (sizeof(cChunkDef::BlockTypes) + 1023) / 1024);
- LOG(" block metadata: %6d bytes (%3d KiB)", sizeof(cChunkDef::BlockNibbles), (sizeof(cChunkDef::BlockNibbles) + 1023) / 1024);
- LOG(" block lighting: %6d bytes (%3d KiB)", 2 * sizeof(cChunkDef::BlockNibbles), (2 * sizeof(cChunkDef::BlockNibbles) + 1023) / 1024);
- LOG(" heightmap: %6d bytes (%3d KiB)", sizeof(cChunkDef::HeightMap), (sizeof(cChunkDef::HeightMap) + 1023) / 1024);
- LOG(" biomemap: %6d bytes (%3d KiB)", sizeof(cChunkDef::BiomeMap), (sizeof(cChunkDef::BiomeMap) + 1023) / 1024);
- int Rest = sizeof(cChunk) - sizeof(cChunkDef::BlockTypes) - 3 * sizeof(cChunkDef::BlockNibbles) - sizeof(cChunkDef::HeightMap) - sizeof(cChunkDef::BiomeMap);
- LOG(" other: %6d bytes (%3d KiB)", Rest, (Rest + 1023) / 1024);
- return;
- }
-
- if(split[0].compare("monsters") == 0 )
- {
- // TODO: cWorld::ListMonsters();
- return;
- }
-
- if(split.size() > 1)
- {
- if( split[0].compare( "say" ) == 0 )
- {
- std::string Message = cChatColor::Purple + "[SERVER] " + Command.substr( Command.find_first_of("say") + 4 );
- LOG("%s", Message.c_str() );
- Broadcast( cPacket_Chat(Message) );
- return;
- }
- }
- printf("Unknown command, type 'help' for all commands.\n");
- // LOG("You didn't enter anything? (%s)", a_Cmd.c_str() );
-}
-
-
-
-
-
-void cServer::SendMessage( const char* a_Message, cPlayer* a_Player /* = 0 */, bool a_bExclude /* = false */ )
-{
- cPacket_Chat Chat( a_Message );
- if( a_Player && !a_bExclude )
- {
- cClientHandle* Client = a_Player->GetClientHandle();
- if( Client ) Client->Send( Chat );
- return;
- }
-
- Broadcast( Chat, (a_Player)?a_Player->GetClientHandle():0 );
-}
-
-
-
-
-
-void cServer::Shutdown()
-{
- m_bRestarting = true;
- m_pState->RestartEvent.Wait();
-
- cRoot::Get()->SaveAllChunks();
-
- cCSLock Lock(m_CSClients);
- for( ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr )
- {
- delete *itr;
- }
- m_Clients.clear();
-}
-
-
-
-
-
-const AString & cServer::GetServerID(void) const
-{
- return m_pState->ServerID;
-}
-
-
-
-
-
-void cServer::KickUser(int a_ClientID, const AString & a_Reason)
-{
- cCSLock Lock(m_CSClients);
- for (ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr)
- {
- if ((*itr)->GetUniqueID() == a_ClientID)
- {
- (*itr)->Kick(a_Reason);
- }
- } // for itr - m_Clients[]
-}
-
-
-
-
-
-void cServer::AuthenticateUser(int a_ClientID)
-{
- cCSLock Lock(m_CSClients);
- for (ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr)
- {
- if ((*itr)->GetUniqueID() == a_ClientID)
- {
- (*itr)->Authenticate();
- }
- } // for itr - m_Clients[]
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cServer::cClientPacketThread:
-
-cServer::cNotifyWriteThread::cNotifyWriteThread(void) :
- super("ClientPacketThread"),
- m_Server(NULL)
-{
-}
-
-
-
-
-
-cServer::cNotifyWriteThread::~cNotifyWriteThread()
-{
- m_ShouldTerminate = true;
- m_Event.Set();
- Wait();
-}
-
-
-
-
-
-bool cServer::cNotifyWriteThread::Start(cServer * a_Server)
-{
- m_Server = a_Server;
- return super::Start();
-}
-
-
-
-
-
-void cServer::cNotifyWriteThread::Execute(void)
-{
- cClientHandleList Clients;
- while (!m_ShouldTerminate)
- {
- cCSLock Lock(m_CS);
- while (m_Clients.size() == 0)
- {
- cCSUnlock Unlock(Lock);
- m_Event.Wait();
- if (m_ShouldTerminate)
- {
- return;
- }
- }
-
- // Copy the clients to notify and unlock the CS:
- Clients.splice(Clients.begin(), m_Clients);
- Lock.Unlock();
-
- for (cClientHandleList::iterator itr = Clients.begin(); itr != Clients.end(); ++itr)
- {
- m_Server->m_SocketThreads.NotifyWrite(*itr);
- } // for itr - Clients[]
- Clients.clear();
- } // while (!mShouldTerminate)
-}
-
-
-
-
-
-void cServer::cNotifyWriteThread::NotifyClientWrite(const cClientHandle * a_Client)
-{
- {
- cCSLock Lock(m_CS);
- m_Clients.remove(const_cast<cClientHandle *>(a_Client)); // Put it there only once
- m_Clients.push_back(const_cast<cClientHandle *>(a_Client));
- }
- m_Event.Set();
-}
-
-
-
-
+ +// ReDucTor is an awesome guy who helped me a lot + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cServer.h" +#include "cClientHandle.h" +#include "cSleep.h" +#include "cTimer.h" +#include "cMonster.h" +#include "cSocket.h" +#include "cRoot.h" +#include "cWorld.h" +#include "ChunkDef.h" +#include "cPluginManager.h" +#include "cGroupManager.h" +#include "cChatColor.h" +#include "cPlayer.h" +#include "cInventory.h" +#include "cItem.h" +#include "cFurnaceRecipe.h" +#include "cTracer.h" +#include "cWebAdmin.h" +#include "cChunk.h" + +#include "MersenneTwister.h" + +#include "../iniFile/iniFile.h" +#include "Vector3f.h" + +#include "packets/cPacket_Chat.h" + +#include <fstream> +#include <sstream> +#include <iostream> + + + + + +extern "C" { + #include "zlib.h" +} + + + +bool g_bWaterPhysics = false; + +typedef std::list< cClientHandle* > ClientList; + + + + + +struct cServer::sServerState +{ + sServerState() + : pListenThread( 0 ) + , pTickThread( 0 ) + , bStopListenThread( false ) + , bStopTickThread( false ) + {} + cSocket SListenClient; // socket listening for client calls + + cThread* pListenThread; bool bStopListenThread; + cThread* pTickThread; bool bStopTickThread; + + cEvent RestartEvent; + std::string ServerID; +}; + + + + + +cServer * cServer::GetServer() +{ + LOGWARN("WARNING: Using deprecated function cServer::GetServer() use cRoot::Get()->GetServer() instead!"); + return cRoot::Get()->GetServer(); +} + + + + + +void cServer::ServerListenThread( void *a_Args ) +{ + LOG("ServerListenThread"); + cServer* self = (cServer*)a_Args; + sServerState* m_pState = self->m_pState; + while( !m_pState->bStopListenThread ) + { + self->StartListenClient(); + } +} + + + + + +void cServer::ClientDestroying(const cClientHandle * a_Client) +{ + m_SocketThreads.StopReading(a_Client); +} + + + + + +void cServer::NotifyClientWrite(const cClientHandle * a_Client) +{ + m_NotifyWriteThread.NotifyClientWrite(a_Client); +} + + + + + +void cServer::WriteToClient(const cSocket * a_Socket, const AString & a_Data) +{ + m_SocketThreads.Write(a_Socket, a_Data); +} + + + + + +void cServer::QueueClientClose(const cSocket * a_Socket) +{ + m_SocketThreads.QueueClose(a_Socket); +} + + + + + +void cServer::RemoveClient(const cSocket * a_Socket) +{ + m_SocketThreads.RemoveClient(a_Socket); +} + + + + + +bool cServer::InitServer( int a_Port ) +{ + if( m_bIsConnected ) + { + LOGERROR("ERROR: Trying to initialize server while server is already running!"); + return false; + } + + printf("/============================\\\n"); + printf("| Custom Minecraft Server |\n"); + printf("| Created by Kevin Bansberg |\n"); + printf("| A.K.A. FakeTruth |\n"); + printf("| Monsters by Alex Sonek |\n"); + printf("| A.K.A. Duralex |\n"); + printf("| Stuff by Mattes D |\n"); + printf("| A.K.A. _Xoft(o) |\n"); + printf("\\============================/\n"); + printf("More info: WWW.MC-SERVER.ORG\n"); + printf(" WWW.AE-C.NET\n"); + printf(" WWW.RBTHINKTANK.COM\n"); + printf("email: faketruth@gmail.com\n\n"); + + LOG("Starting up server."); + LOGINFO("Compatible clients: %s, protocol version %d", MCS_CLIENT_VERSION, MCS_PROTOCOL_VERSION); + + if( cSocket::WSAStartup() != 0 ) // Only does anything on Windows, but whatever + { + LOGERROR("WSAStartup() != 0"); + return false; + } + + m_pState->SListenClient = cSocket::CreateSocket(); + + if( !m_pState->SListenClient.IsValid() ) + { + LOGERROR("m_SListenClient==INVALID_SOCKET (%s)", cSocket::GetErrorString( cSocket::GetLastError() ).c_str() ); + return false; + } + + if( m_pState->SListenClient.SetReuseAddress() == -1 ) + { + LOGERROR("setsockopt == -1"); + return false; + } + + cSocket::SockAddr_In local; + local.Family = cSocket::ADDRESS_FAMILY_INTERNET; + local.Address = cSocket::INTERNET_ADDRESS_ANY; + local.Port = (unsigned short)a_Port; // 25565 + + if( m_pState->SListenClient.Bind( local ) != 0 ) + { + LOGERROR("bind fail (%s)", cSocket::GetErrorString( cSocket::GetLastError() ).c_str() ); + return false; + } + + if( m_pState->SListenClient.Listen( 10 ) != 0) + { + LOGERROR("listen fail (%s)", cSocket::GetErrorString( cSocket::GetLastError() ).c_str() ); + return false; + } + + m_iServerPort = a_Port; + LOG("Port %i has been bound, server is open for connections", m_iServerPort); + m_bIsConnected = true; + + cIniFile IniFile("settings.ini"); + if (IniFile.ReadFile()) + { + g_bWaterPhysics = IniFile.GetValueB("Physics", "Water", false ); + + m_pState->ServerID = "-"; + if (IniFile.GetValueB("Authentication", "Authenticate")) + { + MTRand mtrand1; + unsigned int r1 = (mtrand1.randInt()%1147483647) + 1000000000; + unsigned int r2 = (mtrand1.randInt()%1147483647) + 1000000000; + std::ostringstream sid; + sid << std::hex << r1; + sid << std::hex << r2; + std::string ServerID = sid.str(); + ServerID.resize(16, '0'); + m_pState->ServerID = ServerID; + } + + m_ClientViewDistance = IniFile.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE); + if (m_ClientViewDistance < cClientHandle::MIN_VIEW_DISTANCE) + { + m_ClientViewDistance = cClientHandle::MIN_VIEW_DISTANCE; + LOGINFO("Setting default viewdistance to the minimum of %d", m_ClientViewDistance); + } + if (m_ClientViewDistance > cClientHandle::MAX_VIEW_DISTANCE) + { + m_ClientViewDistance = cClientHandle::MAX_VIEW_DISTANCE; + LOGINFO("Setting default viewdistance to the maximum of %d", m_ClientViewDistance); + } + IniFile.WriteFile(); + } + + m_NotifyWriteThread.Start(this); + + return true; +} + + + + + +cServer::cServer() + : m_pState( new sServerState ) + , m_Millisecondsf( 0 ) + , m_Milliseconds( 0 ) + , m_bIsConnected( false ) + , m_iServerPort( 0 ) + , m_bRestarting( false ) +{ +} + + + + + +cServer::~cServer() +{ + // TODO: Shut down the server gracefully + if ( m_pState->SListenClient ) + { + m_pState->SListenClient.CloseSocket(); + } + m_pState->SListenClient = 0; + + m_pState->bStopListenThread = true; + delete m_pState->pListenThread; m_pState->pListenThread = NULL; + m_pState->bStopTickThread = true; + delete m_pState->pTickThread; m_pState->pTickThread = NULL; + + delete m_pState; +} + + + + + +// TODO - Need to modify this or something, so it broadcasts to all worlds? And move this to cWorld? +void cServer::Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude /* = 0 */ ) +{ + cCSLock Lock(m_CSClients); + for( ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) + { + if ((*itr == a_Exclude) || !(*itr)->IsLoggedIn()) + { + continue; + } + (*itr)->Send( a_Packet ); + } +} + + + + + +void cServer::StartListenClient() +{ + cSocket SClient = m_pState->SListenClient.Accept(); + + if (!SClient.IsValid()) + { + return; + } + + const AString & ClientIP = SClient.GetIPString(); + if (ClientIP.empty()) + { + LOGWARN("cServer: A client connected, but didn't present its IP, disconnecting."); + SClient.CloseSocket(); + return; + } + + LOG("Client \"%s\" connected!", ClientIP.c_str()); + + cClientHandle *NewHandle = new cClientHandle(SClient, m_ClientViewDistance); + if (!m_SocketThreads.AddClient(&(NewHandle->GetSocket()), NewHandle)) + { + // For some reason SocketThreads have rejected the handle, clean it up + LOGERROR("Client \"%s\" cannot be handled, server probably unstable", SClient.GetIPString().c_str()); + SClient.CloseSocket(); + delete NewHandle; + return; + } + + cCSLock Lock(m_CSClients); + m_Clients.push_back( NewHandle ); +} + + + + + +bool cServer::Tick(float a_Dt) +{ + //LOG("1. Tick %0.2f", a_Dt); + if( a_Dt > 100.f ) a_Dt = 100.f; // Don't go over 1/10 second + + m_Millisecondsf += a_Dt; + if( m_Millisecondsf > 1.f ) + { + m_Milliseconds += (int)m_Millisecondsf; + m_Millisecondsf = m_Millisecondsf - (int)m_Millisecondsf; + } + + cRoot::Get()->TickWorlds( a_Dt ); // TODO - Maybe give all worlds their own thread? + + cClientHandleList RemoveClients; + { + cCSLock Lock(m_CSClients); + for (cClientHandleList::iterator itr = m_Clients.begin(); itr != m_Clients.end();) + { + if ((*itr)->IsDestroyed()) + { + RemoveClients.push_back(*itr); // Remove the client later, when CS is not held, to avoid deadlock ( http://forum.mc-server.org/showthread.php?tid=374 ) + itr = m_Clients.erase(itr); + continue; + } + (*itr)->Tick(a_Dt); + ++itr; + } // for itr - m_Clients[] + } + for (cClientHandleList::iterator itr = RemoveClients.begin(); itr != RemoveClients.end(); ++itr) + { + delete *itr; + } // for itr - RemoveClients[] + + cRoot::Get()->GetPluginManager()->Tick( a_Dt ); + + if( !m_bRestarting ) + { + return true; + } + else + { + m_bRestarting = false; + m_pState->RestartEvent.Set(); + return false; + } +} + + + + + +void ServerTickThread( void * a_Param ) +{ + LOG("ServerTickThread"); + cServer *CServerObj = (cServer*)a_Param; + + cTimer Timer; + + long long msPerTick = 50; // TODO - Put this in server config file + long long LastTime = Timer.GetNowTime(); + + bool bKeepGoing = true; + while( bKeepGoing ) + { + long long NowTime = Timer.GetNowTime(); + float DeltaTime = (float)(NowTime-LastTime); + bKeepGoing = CServerObj->Tick( DeltaTime ); + long long TickTime = Timer.GetNowTime() - NowTime; + + if( TickTime < msPerTick ) // Stretch tick time until it's at least msPerTick + { + cSleep::MilliSleep( (unsigned int)( msPerTick - TickTime ) ); + } + + LastTime = NowTime; + } + + LOG("TICK THREAD STOPPED"); +} + + + + + +void cServer::StartListenThread() +{ + m_pState->pListenThread = new cThread( ServerListenThread, this, "cServer::ServerListenThread" ); + m_pState->pTickThread = new cThread( ServerTickThread, this, "cServer::ServerTickThread" ); + m_pState->pListenThread->Start( true ); + m_pState->pTickThread->Start( true ); +} + + + + + +template <class T> +bool from_string( + T& t, + const std::string& s, + std::ios_base& (*f)(std::ios_base&) +) +{ + std::istringstream iss(s); + return !(iss >> f >> t).fail(); +} + + + + + +bool cServer::Command( cClientHandle & a_Client, const char* a_Cmd ) +{ + cPluginManager* PM = cRoot::Get()->GetPluginManager(); + if( PM->CallHook( cPluginManager::E_PLUGIN_CHAT, 2, a_Cmd, a_Client.GetPlayer() ) ) + { + return true; + } + return false; +} + + + + + +void cServer::ServerCommand( const char * a_Cmd ) +{ + AString Command( a_Cmd ); + AStringVector split = StringSplit( Command, " " ); + if( split.empty()) + { + return; + } + + if( split[0].compare( "help" ) == 0 ) + { + printf("================== ALL COMMANDS ===================\n"); + printf("help - Shows this message\n"); + printf("save-all - Saves all loaded chunks to disk\n"); + printf("list - Lists all players currently in server\n"); + printf("unload - Unloads all unused chunks\n"); + printf("numchunks - Shows number of chunks currently loaded\n"); + printf("chunkstats - Shows chunks statistics\n"); + printf("say - Sends a chat message to all players\n"); + printf("restart - Kicks all clients, and saves everything\n"); + printf(" and clears memory\n"); + printf("stop - Saves everything and closes server\n"); + printf("===================================================\n"); + return; + } + if( split[0].compare( "stop" ) == 0 || split[0].compare( "restart" ) == 0 ) + { + return; + } + if( split[0].compare( "save-all" ) == 0 ) + { + cRoot::Get()->SaveAllChunks(); // TODO - Force ALL worlds to save their chunks + return; + } + if (split[0].compare("unload") == 0) + { + LOG("Num loaded chunks before: %i", cRoot::Get()->GetTotalChunkCount() ); + cRoot::Get()->GetDefaultWorld()->UnloadUnusedChunks(); // TODO: Iterate through ALL worlds + LOG("Num loaded chunks after: %i", cRoot::Get()->GetTotalChunkCount() ); + return; + } + if( split[0].compare( "list" ) == 0 ) + { + class cPlayerLogger : public cPlayerListCallback + { + virtual bool Item(cPlayer * a_Player) override + { + LOG("\t%s @ %s", a_Player->GetName().c_str(), a_Player->GetClientHandle()->GetSocket().GetIPString().c_str()); + return false; + } + } Logger; + cRoot::Get()->ForEachPlayer(Logger); + return; + } + if( split[0].compare( "numchunks" ) == 0 ) + { + LOG("Num loaded chunks: %i", cRoot::Get()->GetTotalChunkCount() ); + return; + } + if (split[0].compare("chunkstats") == 0) + { + // TODO: For each world + int NumValid = 0; + int NumDirty = 0; + int NumInLighting = 0; + cWorld * World = cRoot::Get()->GetDefaultWorld(); + int NumInGenerator = World->GetGeneratorQueueLength(); + int NumInSaveQueue = World->GetStorageSaveQueueLength(); + int NumInLoadQueue = World->GetStorageLoadQueueLength(); + World->GetChunkStats(NumValid, NumDirty, NumInLighting); + LOG("Num loaded chunks: %d", NumValid); + LOG("Num dirty chunks: %d", NumDirty); + LOG("Num chunks in lighting queue: %d", NumInLighting); + LOG("Num chunks in generator queue: %d", NumInGenerator); + LOG("Num chunks in storage load queue: %d", NumInLoadQueue); + LOG("Num chunks in storage save queue: %d", NumInSaveQueue); + int Mem = NumValid * sizeof(cChunk); + LOG("Memory used by chunks: %d KiB (%d MiB)", (Mem + 1023) / 1024, (Mem + 1024 * 1024 - 1) / (1024 * 1024)); + LOG("Per-chunk memory size breakdown:"); + LOG(" block types: %6d bytes (%3d KiB)", sizeof(cChunkDef::BlockTypes), (sizeof(cChunkDef::BlockTypes) + 1023) / 1024); + LOG(" block metadata: %6d bytes (%3d KiB)", sizeof(cChunkDef::BlockNibbles), (sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); + LOG(" block lighting: %6d bytes (%3d KiB)", 2 * sizeof(cChunkDef::BlockNibbles), (2 * sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); + LOG(" heightmap: %6d bytes (%3d KiB)", sizeof(cChunkDef::HeightMap), (sizeof(cChunkDef::HeightMap) + 1023) / 1024); + LOG(" biomemap: %6d bytes (%3d KiB)", sizeof(cChunkDef::BiomeMap), (sizeof(cChunkDef::BiomeMap) + 1023) / 1024); + int Rest = sizeof(cChunk) - sizeof(cChunkDef::BlockTypes) - 3 * sizeof(cChunkDef::BlockNibbles) - sizeof(cChunkDef::HeightMap) - sizeof(cChunkDef::BiomeMap); + LOG(" other: %6d bytes (%3d KiB)", Rest, (Rest + 1023) / 1024); + return; + } + + if(split[0].compare("monsters") == 0 ) + { + // TODO: cWorld::ListMonsters(); + return; + } + + if(split.size() > 1) + { + if( split[0].compare( "say" ) == 0 ) + { + std::string Message = cChatColor::Purple + "[SERVER] " + Command.substr( Command.find_first_of("say") + 4 ); + LOG("%s", Message.c_str() ); + Broadcast( cPacket_Chat(Message) ); + return; + } + } + printf("Unknown command, type 'help' for all commands.\n"); + // LOG("You didn't enter anything? (%s)", a_Cmd.c_str() ); +} + + + + + +void cServer::SendMessage( const char* a_Message, cPlayer* a_Player /* = 0 */, bool a_bExclude /* = false */ ) +{ + cPacket_Chat Chat( a_Message ); + if( a_Player && !a_bExclude ) + { + cClientHandle* Client = a_Player->GetClientHandle(); + if( Client ) Client->Send( Chat ); + return; + } + + Broadcast( Chat, (a_Player)?a_Player->GetClientHandle():0 ); +} + + + + + +void cServer::Shutdown() +{ + m_bRestarting = true; + m_pState->RestartEvent.Wait(); + + cRoot::Get()->SaveAllChunks(); + + cCSLock Lock(m_CSClients); + for( ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr ) + { + delete *itr; + } + m_Clients.clear(); +} + + + + + +const AString & cServer::GetServerID(void) const +{ + return m_pState->ServerID; +} + + + + + +void cServer::KickUser(int a_ClientID, const AString & a_Reason) +{ + cCSLock Lock(m_CSClients); + for (ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) + { + if ((*itr)->GetUniqueID() == a_ClientID) + { + (*itr)->Kick(a_Reason); + } + } // for itr - m_Clients[] +} + + + + + +void cServer::AuthenticateUser(int a_ClientID) +{ + cCSLock Lock(m_CSClients); + for (ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) + { + if ((*itr)->GetUniqueID() == a_ClientID) + { + (*itr)->Authenticate(); + } + } // for itr - m_Clients[] +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cServer::cClientPacketThread: + +cServer::cNotifyWriteThread::cNotifyWriteThread(void) : + super("ClientPacketThread"), + m_Server(NULL) +{ +} + + + + + +cServer::cNotifyWriteThread::~cNotifyWriteThread() +{ + m_ShouldTerminate = true; + m_Event.Set(); + Wait(); +} + + + + + +bool cServer::cNotifyWriteThread::Start(cServer * a_Server) +{ + m_Server = a_Server; + return super::Start(); +} + + + + + +void cServer::cNotifyWriteThread::Execute(void) +{ + cClientHandleList Clients; + while (!m_ShouldTerminate) + { + cCSLock Lock(m_CS); + while (m_Clients.size() == 0) + { + cCSUnlock Unlock(Lock); + m_Event.Wait(); + if (m_ShouldTerminate) + { + return; + } + } + + // Copy the clients to notify and unlock the CS: + Clients.splice(Clients.begin(), m_Clients); + Lock.Unlock(); + + for (cClientHandleList::iterator itr = Clients.begin(); itr != Clients.end(); ++itr) + { + m_Server->m_SocketThreads.NotifyWrite(*itr); + } // for itr - Clients[] + Clients.clear(); + } // while (!mShouldTerminate) +} + + + + + +void cServer::cNotifyWriteThread::NotifyClientWrite(const cClientHandle * a_Client) +{ + { + cCSLock Lock(m_CS); + m_Clients.remove(const_cast<cClientHandle *>(a_Client)); // Put it there only once + m_Clients.push_back(const_cast<cClientHandle *>(a_Client)); + } + m_Event.Set(); +} + + + + diff --git a/source/cServer.h b/source/cServer.h index dc1de96cd..e0723f76a 100644 --- a/source/cServer.h +++ b/source/cServer.h @@ -1,132 +1,132 @@ -
-// cServer.h
-
-// Interfaces to the cServer object representing the network server
-
-
-
-
-
-#pragma once
-#ifndef CSERVER_H_INCLUDED
-#define CSERVER_H_INCLUDED
-
-#include "cSocketThreads.h"
-
-
-
-
-
-class cPlayer;
-class cClientHandle;
-class cPacket;
-
-typedef std::list<cClientHandle *> cClientHandleList;
-
-
-
-
-
-class cServer //tolua_export
-{ //tolua_export
-public: //tolua_export
- static cServer * GetServer(); //tolua_export
-
- bool InitServer( int a_Port = 25565 );
-
- int GetPort() { return m_iServerPort; }
- bool IsConnected(){return m_bIsConnected;} // returns connection status
- void StartListenClient(); // Listen to client
-
- void Broadcast(const cPacket & a_Packet, cClientHandle* a_Exclude = NULL);
-
- bool Tick(float a_Dt);
-
- void StartListenThread();
-
- bool Command( cClientHandle & a_Client, const char* a_Cmd );
- void ServerCommand( const char* a_Cmd ); //tolua_export
- void Shutdown();
-
- void SendMessage( const char* a_Message, cPlayer* a_Player = 0, bool a_bExclude = false ); //tolua_export
-
- void KickUser(int a_ClientID, const AString & a_Reason);
- void AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user
-
- static void ServerListenThread( void* a_Args );
-
- const AString & GetServerID(void) const;
-
- void ClientDestroying(const cClientHandle * a_Client); // Called by cClientHandle::Destroy(); stop m_SocketThreads from calling back into a_Client
-
- void NotifyClientWrite(const cClientHandle * a_Client); // Notifies m_SocketThreads that client has something to be written
-
- void WriteToClient(const cSocket * a_Socket, const AString & a_Data); // Queues outgoing data for the socket through m_SocketThreads
-
- void QueueClientClose(const cSocket * a_Socket); // Queues the socket to close when all its outgoing data is sent
-
- void RemoveClient(const cSocket * a_Socket); // Removes the socket from m_SocketThreads
-
-private:
-
- friend class cRoot; // so cRoot can create and destroy cServer
-
- /// When NotifyClientWrite() is called, it is queued for this thread to process (to avoid deadlocks between cSocketThreads, cClientHandle and cChunkMap)
- class cNotifyWriteThread :
- public cIsThread
- {
- typedef cIsThread super;
-
- cEvent m_Event; // Set when m_Clients gets appended
- cServer * m_Server;
-
- cCriticalSection m_CS;
- cClientHandleList m_Clients;
-
- virtual void Execute(void);
-
- public:
-
- cNotifyWriteThread(void);
- ~cNotifyWriteThread();
-
- bool Start(cServer * a_Server);
-
- void NotifyClientWrite(const cClientHandle * a_Client);
- } ;
-
- struct sServerState;
- sServerState* m_pState;
-
- cNotifyWriteThread m_NotifyWriteThread;
-
- cCriticalSection m_CSClients; // Locks client list
- cClientHandleList m_Clients; // Clients that are connected to the server
-
- cSocketThreads m_SocketThreads;
-
- int m_ClientViewDistance; // The default view distance for clients; settable in Settings.ini
-
- // Time since server was started
- float m_Millisecondsf;
- unsigned int m_Milliseconds;
-
- bool m_bIsConnected; // true - connected false - not connected
- int m_iServerPort;
-
- bool m_bRestarting;
-
- cServer();
- ~cServer();
-
-}; //tolua_export
-
-
-
-
-
-#endif // CSERVER_H_INCLUDED
-
-
-
-
+ +// cServer.h + +// Interfaces to the cServer object representing the network server + + + + + +#pragma once +#ifndef CSERVER_H_INCLUDED +#define CSERVER_H_INCLUDED + +#include "cSocketThreads.h" + + + + + +class cPlayer; +class cClientHandle; +class cPacket; + +typedef std::list<cClientHandle *> cClientHandleList; + + + + + +class cServer //tolua_export +{ //tolua_export +public: //tolua_export + static cServer * GetServer(); //tolua_export + + bool InitServer( int a_Port = 25565 ); + + int GetPort() { return m_iServerPort; } + bool IsConnected(){return m_bIsConnected;} // returns connection status + void StartListenClient(); // Listen to client + + void Broadcast(const cPacket & a_Packet, cClientHandle* a_Exclude = NULL); + + bool Tick(float a_Dt); + + void StartListenThread(); + + bool Command( cClientHandle & a_Client, const char* a_Cmd ); + void ServerCommand( const char* a_Cmd ); //tolua_export + void Shutdown(); + + void SendMessage( const char* a_Message, cPlayer* a_Player = 0, bool a_bExclude = false ); //tolua_export + + void KickUser(int a_ClientID, const AString & a_Reason); + void AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user + + static void ServerListenThread( void* a_Args ); + + const AString & GetServerID(void) const; + + void ClientDestroying(const cClientHandle * a_Client); // Called by cClientHandle::Destroy(); stop m_SocketThreads from calling back into a_Client + + void NotifyClientWrite(const cClientHandle * a_Client); // Notifies m_SocketThreads that client has something to be written + + void WriteToClient(const cSocket * a_Socket, const AString & a_Data); // Queues outgoing data for the socket through m_SocketThreads + + void QueueClientClose(const cSocket * a_Socket); // Queues the socket to close when all its outgoing data is sent + + void RemoveClient(const cSocket * a_Socket); // Removes the socket from m_SocketThreads + +private: + + friend class cRoot; // so cRoot can create and destroy cServer + + /// When NotifyClientWrite() is called, it is queued for this thread to process (to avoid deadlocks between cSocketThreads, cClientHandle and cChunkMap) + class cNotifyWriteThread : + public cIsThread + { + typedef cIsThread super; + + cEvent m_Event; // Set when m_Clients gets appended + cServer * m_Server; + + cCriticalSection m_CS; + cClientHandleList m_Clients; + + virtual void Execute(void); + + public: + + cNotifyWriteThread(void); + ~cNotifyWriteThread(); + + bool Start(cServer * a_Server); + + void NotifyClientWrite(const cClientHandle * a_Client); + } ; + + struct sServerState; + sServerState* m_pState; + + cNotifyWriteThread m_NotifyWriteThread; + + cCriticalSection m_CSClients; // Locks client list + cClientHandleList m_Clients; // Clients that are connected to the server + + cSocketThreads m_SocketThreads; + + int m_ClientViewDistance; // The default view distance for clients; settable in Settings.ini + + // Time since server was started + float m_Millisecondsf; + unsigned int m_Milliseconds; + + bool m_bIsConnected; // true - connected false - not connected + int m_iServerPort; + + bool m_bRestarting; + + cServer(); + ~cServer(); + +}; //tolua_export + + + + + +#endif // CSERVER_H_INCLUDED + + + + diff --git a/source/cSheep.cpp b/source/cSheep.cpp index 921cd2d28..c9fed280a 100644 --- a/source/cSheep.cpp +++ b/source/cSheep.cpp @@ -1,65 +1,65 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cSheep.h"
-
-
-
-
-
-//Todo: Implement color
-
-
-
-
-
-cSheep::cSheep(void) :
- m_IsSheared(false),
- m_WoolColor(0) // TODO: E_META_WOOL_WHITE
-{
- m_MobType = 91;
- GetMonsterConfig("Sheep");
-}
-
-
-
-
-
-cSheep::~cSheep()
-{
-}
-
-
-
-
-
-bool cSheep::IsA( const char* a_EntityType )
-{
- if (strcmp( a_EntityType, "cSheep" ) == 0)
- {
- return true;
- }
- return cMonster::IsA( a_EntityType );
-}
-
-
-
-
-
-void cSheep::KilledBy( cEntity* a_Killer )
-{
- // TODO: Check whether it is sheared
- // TODO: Check color
-
- if (!m_IsSheared)
- {
- cItems Drops;
- Drops.push_back(cItem(E_ITEM_WHITE_CLOTH, 1, m_WoolColor));
- m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
- }
-
- cMonster::KilledBy( a_Killer );
-}
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSheep.h" + + + + + +//Todo: Implement color + + + + + +cSheep::cSheep(void) : + m_IsSheared(false), + m_WoolColor(0) // TODO: E_META_WOOL_WHITE +{ + m_MobType = 91; + GetMonsterConfig("Sheep"); +} + + + + + +cSheep::~cSheep() +{ +} + + + + + +bool cSheep::IsA( const char* a_EntityType ) +{ + if (strcmp( a_EntityType, "cSheep" ) == 0) + { + return true; + } + return cMonster::IsA( a_EntityType ); +} + + + + + +void cSheep::KilledBy( cEntity* a_Killer ) +{ + // TODO: Check whether it is sheared + // TODO: Check color + + if (!m_IsSheared) + { + cItems Drops; + Drops.push_back(cItem(E_ITEM_WHITE_CLOTH, 1, m_WoolColor)); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + } + + cMonster::KilledBy( a_Killer ); +} + + + diff --git a/source/cSheep.h b/source/cSheep.h index 9faa25592..98faa266c 100644 --- a/source/cSheep.h +++ b/source/cSheep.h @@ -1,17 +1,17 @@ -#pragma once
-
-#include "cPassiveMonster.h"
-
-class cSheep : public cPassiveMonster
-{
-public:
- cSheep();
- ~cSheep();
-
- bool m_IsSheared;
- NIBBLETYPE m_WoolColor; // Uses E_META_WOOL_ constants for colors
-
- virtual bool IsA(const char * a_EntityType);
-
- virtual void KilledBy(cEntity * a_Killer);
-};
+#pragma once + +#include "cPassiveMonster.h" + +class cSheep : public cPassiveMonster +{ +public: + cSheep(); + ~cSheep(); + + bool m_IsSheared; + NIBBLETYPE m_WoolColor; // Uses E_META_WOOL_ constants for colors + + virtual bool IsA(const char * a_EntityType); + + virtual void KilledBy(cEntity * a_Killer); +}; diff --git a/source/cSign.h b/source/cSign.h index ebdeb3031..9daa8234c 100644 --- a/source/cSign.h +++ b/source/cSign.h @@ -1,32 +1,32 @@ -#pragma once
-
-class cSign //tolua_export
-{ //tolua_export
-public:
- static char RotationToMetaData( float a_Rotation ) //tolua_export
- { //tolua_export
- a_Rotation += 180 + (180/16); // So its not aligned with axis
- if( a_Rotation > 360.f ) a_Rotation -= 360.f;
-
- a_Rotation = (a_Rotation/360) * 16;
-
- return ((char)a_Rotation) % 16;
- } //tolua_export
- static char DirectionToMetaData( char a_Direction ) //tolua_export
- { //tolua_export
- switch( a_Direction )
- {
- case 0x2:
- return 0x2;
- case 0x3:
- return 0x3;
- case 0x4:
- return 0x4;
- case 0x5:
- return 0x5;
- default:
- break;
- };
- return 0x2;
- }
+#pragma once + +class cSign //tolua_export +{ //tolua_export +public: + static char RotationToMetaData( float a_Rotation ) //tolua_export + { //tolua_export + a_Rotation += 180 + (180/16); // So its not aligned with axis + if( a_Rotation > 360.f ) a_Rotation -= 360.f; + + a_Rotation = (a_Rotation/360) * 16; + + return ((char)a_Rotation) % 16; + } //tolua_export + static char DirectionToMetaData( char a_Direction ) //tolua_export + { //tolua_export + switch( a_Direction ) + { + case 0x2: + return 0x2; + case 0x3: + return 0x3; + case 0x4: + return 0x4; + case 0x5: + return 0x5; + default: + break; + }; + return 0x2; + } }; //tolua_export
\ No newline at end of file diff --git a/source/cSignEntity.cpp b/source/cSignEntity.cpp index cf0a13650..80e10621e 100644 --- a/source/cSignEntity.cpp +++ b/source/cSignEntity.cpp @@ -1,140 +1,140 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cSignEntity.h"
-
-#include "cPlayer.h"
-#include "cClientHandle.h"
-#include "cWorld.h"
-#include "cRoot.h"
-
-#include "packets/cPacket_UpdateSign.h"
-
-#include <json/json.h>
-
-
-
-
-
-cSignEntity::cSignEntity(ENUM_BLOCK_ID a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World)
- : cBlockEntity(a_BlockType, a_X, a_Y, a_Z, a_World)
-{
-}
-
-
-
-
-
-cSignEntity::~cSignEntity()
-{
-}
-
-
-
-
-
-// It don't do anything when 'used'
-void cSignEntity::UsedBy( cPlayer * a_Player )
-{
- (void)a_Player;
-}
-
-
-
-
-
-void cSignEntity::SetLines( const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4 )
-{
- m_Line[0] = a_Line1;
- m_Line[1] = a_Line2;
- m_Line[2] = a_Line3;
- m_Line[3] = a_Line4;
-}
-
-
-
-
-
-void cSignEntity::SetLine( int a_Index, const AString & a_Line )
-{
- if( a_Index < 4 && a_Index > -1 )
- {
- m_Line[a_Index] = a_Line;
- }
-}
-
-
-
-
-
-AString cSignEntity::GetLine( int a_Index ) const
-{
- if( a_Index < 4 && a_Index > -1 )
- {
- return m_Line[a_Index];
- }
- return "";
-}
-
-
-
-
-
-cPacket * cSignEntity::GetPacket(void)
-{
- cPacket_UpdateSign * Sign = new cPacket_UpdateSign;
- Sign->m_PosX = m_PosX;
- Sign->m_PosY = (short)m_PosY;
- Sign->m_PosZ = m_PosZ;
- Sign->m_Line1 = m_Line[0];
- Sign->m_Line2 = m_Line[1];
- Sign->m_Line3 = m_Line[2];
- Sign->m_Line4 = m_Line[3];
- return Sign;
-}
-
-
-
-
-
-#define READ(File, Var) \
- if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \
- { \
- LOGERROR("ERROR READING cSignEntity %s FROM FILE (line %d)", #Var, __LINE__); \
- return false; \
- }
-
-
-
-
-
-
-bool cSignEntity::LoadFromJson( const Json::Value & a_Value )
-{
- m_PosX = a_Value.get("x", 0).asInt();
- m_PosY = a_Value.get("y", 0).asInt();
- m_PosZ = a_Value.get("z", 0).asInt();
-
- m_Line[0] = a_Value.get("Line1", "").asString();
- m_Line[1] = a_Value.get("Line2", "").asString();
- m_Line[2] = a_Value.get("Line3", "").asString();
- m_Line[3] = a_Value.get("Line4", "").asString();
-
- return true;
-}
-
-void cSignEntity::SaveToJson( Json::Value & a_Value )
-{
- a_Value["x"] = m_PosX;
- a_Value["y"] = m_PosY;
- a_Value["z"] = m_PosZ;
-
- a_Value["Line1"] = m_Line[0];
- a_Value["Line2"] = m_Line[1];
- a_Value["Line3"] = m_Line[2];
- a_Value["Line4"] = m_Line[3];
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSignEntity.h" + +#include "cPlayer.h" +#include "cClientHandle.h" +#include "cWorld.h" +#include "cRoot.h" + +#include "packets/cPacket_UpdateSign.h" + +#include <json/json.h> + + + + + +cSignEntity::cSignEntity(ENUM_BLOCK_ID a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World) + : cBlockEntity(a_BlockType, a_X, a_Y, a_Z, a_World) +{ +} + + + + + +cSignEntity::~cSignEntity() +{ +} + + + + + +// It don't do anything when 'used' +void cSignEntity::UsedBy( cPlayer * a_Player ) +{ + (void)a_Player; +} + + + + + +void cSignEntity::SetLines( const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4 ) +{ + m_Line[0] = a_Line1; + m_Line[1] = a_Line2; + m_Line[2] = a_Line3; + m_Line[3] = a_Line4; +} + + + + + +void cSignEntity::SetLine( int a_Index, const AString & a_Line ) +{ + if( a_Index < 4 && a_Index > -1 ) + { + m_Line[a_Index] = a_Line; + } +} + + + + + +AString cSignEntity::GetLine( int a_Index ) const +{ + if( a_Index < 4 && a_Index > -1 ) + { + return m_Line[a_Index]; + } + return ""; +} + + + + + +cPacket * cSignEntity::GetPacket(void) +{ + cPacket_UpdateSign * Sign = new cPacket_UpdateSign; + Sign->m_PosX = m_PosX; + Sign->m_PosY = (short)m_PosY; + Sign->m_PosZ = m_PosZ; + Sign->m_Line1 = m_Line[0]; + Sign->m_Line2 = m_Line[1]; + Sign->m_Line3 = m_Line[2]; + Sign->m_Line4 = m_Line[3]; + return Sign; +} + + + + + +#define READ(File, Var) \ + if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \ + { \ + LOGERROR("ERROR READING cSignEntity %s FROM FILE (line %d)", #Var, __LINE__); \ + return false; \ + } + + + + + + +bool cSignEntity::LoadFromJson( const Json::Value & a_Value ) +{ + m_PosX = a_Value.get("x", 0).asInt(); + m_PosY = a_Value.get("y", 0).asInt(); + m_PosZ = a_Value.get("z", 0).asInt(); + + m_Line[0] = a_Value.get("Line1", "").asString(); + m_Line[1] = a_Value.get("Line2", "").asString(); + m_Line[2] = a_Value.get("Line3", "").asString(); + m_Line[3] = a_Value.get("Line4", "").asString(); + + return true; +} + +void cSignEntity::SaveToJson( Json::Value & a_Value ) +{ + a_Value["x"] = m_PosX; + a_Value["y"] = m_PosY; + a_Value["z"] = m_PosZ; + + a_Value["Line1"] = m_Line[0]; + a_Value["Line2"] = m_Line[1]; + a_Value["Line3"] = m_Line[2]; + a_Value["Line4"] = m_Line[3]; +} + + + + diff --git a/source/cSignEntity.h b/source/cSignEntity.h index 3b633c8af..5f6e60889 100644 --- a/source/cSignEntity.h +++ b/source/cSignEntity.h @@ -1,45 +1,45 @@ -
-#pragma once
-
-#include "cBlockEntity.h"
-
-
-
-
-
-namespace Json
-{
- class Value;
-}
-
-
-
-
-
-class cSignEntity :
- public cBlockEntity
-{
-public:
- cSignEntity(ENUM_BLOCK_ID a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World);
- virtual ~cSignEntity();
-
- bool LoadFromJson( const Json::Value& a_Value );
- virtual void SaveToJson(Json::Value& a_Value ) override;
-
- void SetLines( const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4 );
- void SetLine( int a_Index, const AString & a_Line );
-
- AString GetLine( int a_Index ) const;
-
- virtual void UsedBy( cPlayer * a_Player ) override;
-
- virtual cPacket * GetPacket(void) override;
-
-private:
-
- AString m_Line[4];
-};
-
-
-
-
+ +#pragma once + +#include "cBlockEntity.h" + + + + + +namespace Json +{ + class Value; +} + + + + + +class cSignEntity : + public cBlockEntity +{ +public: + cSignEntity(ENUM_BLOCK_ID a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World); + virtual ~cSignEntity(); + + bool LoadFromJson( const Json::Value& a_Value ); + virtual void SaveToJson(Json::Value& a_Value ) override; + + void SetLines( const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4 ); + void SetLine( int a_Index, const AString & a_Line ); + + AString GetLine( int a_Index ) const; + + virtual void UsedBy( cPlayer * a_Player ) override; + + virtual cPacket * GetPacket(void) override; + +private: + + AString m_Line[4]; +}; + + + + diff --git a/source/cSilverfish.cpp b/source/cSilverfish.cpp index c08129181..7302934b6 100644 --- a/source/cSilverfish.cpp +++ b/source/cSilverfish.cpp @@ -1,25 +1,25 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cSilverfish.h"
-
-
-
-
-
-cSilverfish::cSilverfish()
-{
- m_MobType = 60;
- GetMonsterConfig("Silverfish");
-}
-
-cSilverfish::~cSilverfish()
-{
-}
-
-bool cSilverfish::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cSilverfish" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSilverfish.h" + + + + + +cSilverfish::cSilverfish() +{ + m_MobType = 60; + GetMonsterConfig("Silverfish"); +} + +cSilverfish::~cSilverfish() +{ +} + +bool cSilverfish::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cSilverfish" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + diff --git a/source/cSilverfish.h b/source/cSilverfish.h index 0a949c7e3..1cdc89e62 100644 --- a/source/cSilverfish.h +++ b/source/cSilverfish.h @@ -1,12 +1,12 @@ -#pragma once
-
-#include "cAggressiveMonster.h"
-
-class cSilverfish : public cAggressiveMonster
-{
-public:
- cSilverfish();
- ~cSilverfish();
-
- virtual bool IsA( const char* a_EntityType );
-};
+#pragma once + +#include "cAggressiveMonster.h" + +class cSilverfish : public cAggressiveMonster +{ +public: + cSilverfish(); + ~cSilverfish(); + + virtual bool IsA( const char* a_EntityType ); +}; diff --git a/source/cSimulator.cpp b/source/cSimulator.cpp index 92cc0823c..377d69eb3 100644 --- a/source/cSimulator.cpp +++ b/source/cSimulator.cpp @@ -1,33 +1,33 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cSimulator.h"
-#include "cWorld.h"
-#include "Vector3i.h"
-#include "BlockID.h"
-#include "Defines.h"
-
-
-
-
-
-cSimulator::cSimulator( cWorld* a_World )
- : m_World(a_World)
-{
-
-}
-
-cSimulator::~cSimulator()
-{
-}
-
-void cSimulator::WakeUp( int a_X, int a_Y, int a_Z )
-{
- AddBlock( a_X, a_Y, a_Z );
- AddBlock( a_X-1, a_Y, a_Z );
- AddBlock( a_X+1, a_Y, a_Z );
- AddBlock( a_X, a_Y-1, a_Z );
- AddBlock( a_X, a_Y+1, a_Z );
- AddBlock( a_X, a_Y, a_Z-1 );
- AddBlock( a_X, a_Y, a_Z+1 );
-}
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSimulator.h" +#include "cWorld.h" +#include "Vector3i.h" +#include "BlockID.h" +#include "Defines.h" + + + + + +cSimulator::cSimulator( cWorld* a_World ) + : m_World(a_World) +{ + +} + +cSimulator::~cSimulator() +{ +} + +void cSimulator::WakeUp( int a_X, int a_Y, int a_Z ) +{ + AddBlock( a_X, a_Y, a_Z ); + AddBlock( a_X-1, a_Y, a_Z ); + AddBlock( a_X+1, a_Y, a_Z ); + AddBlock( a_X, a_Y-1, a_Z ); + AddBlock( a_X, a_Y+1, a_Z ); + AddBlock( a_X, a_Y, a_Z-1 ); + AddBlock( a_X, a_Y, a_Z+1 ); +} diff --git a/source/cSimulator.h b/source/cSimulator.h index 4e92ec152..158e74b99 100644 --- a/source/cSimulator.h +++ b/source/cSimulator.h @@ -1,20 +1,20 @@ -#pragma once
-
-class Vector3i;
-class cWorld;
-class cSimulator
-{
-public:
- cSimulator( cWorld* a_World );
- ~cSimulator();
-
- virtual void Simulate( float a_Dt ) = 0;
- virtual void WakeUp( int a_X, int a_Y, int a_Z );
-
- virtual bool IsAllowedBlock( char a_BlockID ) = 0;
-
-protected:
- virtual void AddBlock(int a_X, int a_Y, int a_Z) = 0;
-
- cWorld * m_World;
+#pragma once + +class Vector3i; +class cWorld; +class cSimulator +{ +public: + cSimulator( cWorld* a_World ); + ~cSimulator(); + + virtual void Simulate( float a_Dt ) = 0; + virtual void WakeUp( int a_X, int a_Y, int a_Z ); + + virtual bool IsAllowedBlock( char a_BlockID ) = 0; + +protected: + virtual void AddBlock(int a_X, int a_Y, int a_Z) = 0; + + cWorld * m_World; };
\ No newline at end of file diff --git a/source/cSimulatorManager.cpp b/source/cSimulatorManager.cpp index 0663e5fe6..0d7ef356d 100644 --- a/source/cSimulatorManager.cpp +++ b/source/cSimulatorManager.cpp @@ -1,67 +1,67 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cSimulatorManager.h"
-
-
-
-
-
-cSimulatorManager::cSimulatorManager()
-{
-
-}
-
-
-
-
-
-cSimulatorManager::~cSimulatorManager()
-{
- for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr )
- {
- delete *itr;
- } // for itr - m_Simulators[]
-}
-
-
-
-
-
-void cSimulatorManager::Simulate( float a_Dt )
-{
- m_Ticks++;
- for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr )
- {
- if(m_Ticks % (*itr)->second == 0)
- (*itr)->first->Simulate(a_Dt);
- }
-}
-
-
-
-
-
-void cSimulatorManager::WakeUp(int a_X, int a_Y, int a_Z)
-{
- for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr )
- {
- (*itr)->first->WakeUp(a_X, a_Y, a_Z);
- }
-}
-
-
-
-
-
-void cSimulatorManager::RegisterSimulator(cSimulator *a_Simulator, short a_Rate)
-{
- //TODO needs some checking
- std::pair<cSimulator *, short> *Pair = new std::pair<cSimulator *, short>(a_Simulator, a_Rate);
-
- m_Simulators.push_back(Pair);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSimulatorManager.h" + + + + + +cSimulatorManager::cSimulatorManager() +{ + +} + + + + + +cSimulatorManager::~cSimulatorManager() +{ + for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr ) + { + delete *itr; + } // for itr - m_Simulators[] +} + + + + + +void cSimulatorManager::Simulate( float a_Dt ) +{ + m_Ticks++; + for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr ) + { + if(m_Ticks % (*itr)->second == 0) + (*itr)->first->Simulate(a_Dt); + } +} + + + + + +void cSimulatorManager::WakeUp(int a_X, int a_Y, int a_Z) +{ + for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr ) + { + (*itr)->first->WakeUp(a_X, a_Y, a_Z); + } +} + + + + + +void cSimulatorManager::RegisterSimulator(cSimulator *a_Simulator, short a_Rate) +{ + //TODO needs some checking + std::pair<cSimulator *, short> *Pair = new std::pair<cSimulator *, short>(a_Simulator, a_Rate); + + m_Simulators.push_back(Pair); +} + + + + diff --git a/source/cSimulatorManager.h b/source/cSimulatorManager.h index 1168e5af8..ec8804992 100644 --- a/source/cSimulatorManager.h +++ b/source/cSimulatorManager.h @@ -1,39 +1,39 @@ -
-// cSimulatorManager.h
-
-
-
-
-#pragma once
-
-
-
-
-#include "cSimulator.h"
-
-
-
-
-
-class cSimulatorManager
-{
-public:
- cSimulatorManager();
- ~cSimulatorManager();
-
- void Simulate( float a_Dt );
- void WakeUp(int a_X, int a_Y, int a_Z);
-
- void RegisterSimulator(cSimulator * a_Simulator, short a_Rate); // Takes ownership of the simulator object!
-
-protected:
-
- typedef std::vector <std::pair<cSimulator *, short> *> cSimulators;
-
- cSimulators m_Simulators;
- long long m_Ticks;
-};
-
-
-
-
+ +// cSimulatorManager.h + + + + +#pragma once + + + + +#include "cSimulator.h" + + + + + +class cSimulatorManager +{ +public: + cSimulatorManager(); + ~cSimulatorManager(); + + void Simulate( float a_Dt ); + void WakeUp(int a_X, int a_Y, int a_Z); + + void RegisterSimulator(cSimulator * a_Simulator, short a_Rate); // Takes ownership of the simulator object! + +protected: + + typedef std::vector <std::pair<cSimulator *, short> *> cSimulators; + + cSimulators m_Simulators; + long long m_Ticks; +}; + + + + diff --git a/source/cSkeleton.cpp b/source/cSkeleton.cpp index eb6ea1234..69ee55d23 100644 --- a/source/cSkeleton.cpp +++ b/source/cSkeleton.cpp @@ -1,65 +1,65 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cSkeleton.h"
-
-
-
-
-
-cSkeleton::cSkeleton()
-{
- m_MobType = 51;
- GetMonsterConfig("Skeleton");
-}
-
-
-
-
-
-cSkeleton::~cSkeleton()
-{
-}
-
-
-
-
-
-bool cSkeleton::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cSkeleton" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
-
-
-
-
-
-void cSkeleton::Tick(float a_Dt)
-{
- cMonster::Tick(a_Dt);
-
- //TODO Outsource
- //TODO should do lightcheck, not daylight -> mobs in the dark don´t burn
- if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING ) { //if daylight
- SetMetaData(BURNING); // BURN, BABY, BURN! >:D
- }
-}
-
-
-
-
-
-void cSkeleton::KilledBy( cEntity* a_Killer )
-{
- cItems Drops;
- AddRandomDropItem(Drops, 0, 2, E_ITEM_ARROW);
- AddRandomDropItem(Drops, 0, 2, E_ITEM_BONE);
- m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
-
- cMonster::KilledBy( a_Killer );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSkeleton.h" + + + + + +cSkeleton::cSkeleton() +{ + m_MobType = 51; + GetMonsterConfig("Skeleton"); +} + + + + + +cSkeleton::~cSkeleton() +{ +} + + + + + +bool cSkeleton::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cSkeleton" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cSkeleton::Tick(float a_Dt) +{ + cMonster::Tick(a_Dt); + + //TODO Outsource + //TODO should do lightcheck, not daylight -> mobs in the dark don´t burn + if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING ) { //if daylight + SetMetaData(BURNING); // BURN, BABY, BURN! >:D + } +} + + + + + +void cSkeleton::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_ARROW); + AddRandomDropItem(Drops, 0, 2, E_ITEM_BONE); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cSkeleton.h b/source/cSkeleton.h index ca7ed2fe3..78eeb731f 100644 --- a/source/cSkeleton.h +++ b/source/cSkeleton.h @@ -1,16 +1,16 @@ -#pragma once
-
-#include "cAggressiveMonster.h"
-
-class cSkeleton : public cAggressiveMonster
-{
-public:
- cSkeleton();
- ~cSkeleton();
-
- virtual bool IsA( const char* a_EntityType );
-
- virtual void Tick(float a_Dt);
- virtual void KilledBy( cEntity* a_Killer );
-
-};
+#pragma once + +#include "cAggressiveMonster.h" + +class cSkeleton : public cAggressiveMonster +{ +public: + cSkeleton(); + ~cSkeleton(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void Tick(float a_Dt); + virtual void KilledBy( cEntity* a_Killer ); + +}; diff --git a/source/cSleep.cpp b/source/cSleep.cpp index 77da5dd58..70fb06b40 100644 --- a/source/cSleep.cpp +++ b/source/cSleep.cpp @@ -1,19 +1,19 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#ifndef _WIN32
- #include <unistd.h>
-#endif
-
-
-
-
-
-void cSleep::MilliSleep( unsigned int a_MilliSeconds )
-{
-#ifdef _WIN32
- Sleep(a_MilliSeconds); // Don't tick too much
-#else
- usleep(a_MilliSeconds*1000);
-#endif
-}
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#ifndef _WIN32 + #include <unistd.h> +#endif + + + + + +void cSleep::MilliSleep( unsigned int a_MilliSeconds ) +{ +#ifdef _WIN32 + Sleep(a_MilliSeconds); // Don't tick too much +#else + usleep(a_MilliSeconds*1000); +#endif +} diff --git a/source/cSleep.h b/source/cSleep.h index 20ca7fc7d..5298c15da 100644 --- a/source/cSleep.h +++ b/source/cSleep.h @@ -1,7 +1,7 @@ -#pragma once
-
-class cSleep
-{
-public:
- static void MilliSleep( unsigned int a_MilliSeconds );
+#pragma once + +class cSleep +{ +public: + static void MilliSleep( unsigned int a_MilliSeconds ); };
\ No newline at end of file diff --git a/source/cSlime.cpp b/source/cSlime.cpp index 7cef1bb14..c314caae3 100644 --- a/source/cSlime.cpp +++ b/source/cSlime.cpp @@ -1,52 +1,52 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cSlime.h"
-
-//TODO Implement sized slimes
-
-
-
-
-
-cSlime::cSlime()
-{
- m_MobType = 55;
- GetMonsterConfig("Slime");
-}
-
-
-
-
-
-cSlime::~cSlime()
-{
-}
-
-
-
-
-
-bool cSlime::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cSlime" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
-
-
-
-
-
-void cSlime::KilledBy( cEntity* a_Killer )
-{
- //TODO: only when tiny
- cItems Drops;
- AddRandomDropItem(Drops, 0, 2, E_ITEM_SLIMEBALL);
- m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
-
- cMonster::KilledBy( a_Killer );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSlime.h" + +//TODO Implement sized slimes + + + + + +cSlime::cSlime() +{ + m_MobType = 55; + GetMonsterConfig("Slime"); +} + + + + + +cSlime::~cSlime() +{ +} + + + + + +bool cSlime::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cSlime" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cSlime::KilledBy( cEntity* a_Killer ) +{ + //TODO: only when tiny + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_SLIMEBALL); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cSlime.h b/source/cSlime.h index 26953cc73..e2e108516 100644 --- a/source/cSlime.h +++ b/source/cSlime.h @@ -1,14 +1,14 @@ -#pragma once
-
-#include "cAggressiveMonster.h"
-
-class cSlime : public cAggressiveMonster
-{
-public:
- cSlime();
- ~cSlime();
-
- virtual bool IsA( const char* a_EntityType );
-
- virtual void KilledBy( cEntity* a_Killer );
-};
+#pragma once + +#include "cAggressiveMonster.h" + +class cSlime : public cAggressiveMonster +{ +public: + cSlime(); + ~cSlime(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/cSocket.cpp b/source/cSocket.cpp index 7fc67e258..09cdfac1d 100644 --- a/source/cSocket.cpp +++ b/source/cSocket.cpp @@ -1,354 +1,354 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cSocket.h"
-#include "packets/cPacket.h"
-
-#ifndef _WIN32
- #include <netdb.h>
- #include <unistd.h>
- #include <arpa/inet.h> //inet_ntoa()
-#else
- #define socklen_t int
-#endif
-
-
-
-
-
-cSocket::cSocket(xSocket a_Socket)
- : m_Socket(a_Socket)
-{
-}
-
-
-
-
-
-cSocket::~cSocket()
-{
- // Do NOT close the socket; this class is an API wrapper, not a RAII!
-}
-
-
-
-
-
-cSocket::operator const cSocket::xSocket() const
-{
- return m_Socket;
-}
-
-
-
-
-
-cSocket::xSocket cSocket::GetSocket() const
-{
- return m_Socket;
-}
-
-
-
-
-
-bool cSocket::IsValid(void) const
-{
- #ifdef _WIN32
- return (m_Socket != INVALID_SOCKET);
- #else // _WIN32
- return (m_Socket >= 0);
- #endif // else _WIN32
-}
-
-
-
-
-
-void cSocket::CloseSocket()
-{
- #ifdef _WIN32
-
- closesocket(m_Socket);
-
- #else // _WIN32
-
- if (shutdown(m_Socket, SHUT_RDWR) != 0)//SD_BOTH);
- {
- LOGWARN("Error on shutting down socket (%s): %s", m_IPString.c_str(), GetLastErrorString().c_str());
- }
- if (close(m_Socket) != 0)
- {
- LOGWARN("Error closing socket (%s): %s", m_IPString.c_str(), GetLastErrorString().c_str());
- }
-
- #endif // else _WIN32
-
- // Invalidate the socket so that this object can be re-used for another connection
- m_Socket = INVALID_SOCKET;
-}
-
-
-
-
-
-AString cSocket::GetErrorString( int a_ErrNo )
-{
- char buffer[ 1024 ];
- AString Out;
-
- #ifdef _WIN32
-
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, a_ErrNo, 0, buffer, ARRAYCOUNT(buffer), NULL);
- Printf(Out, "%d: %s", a_ErrNo, buffer);
- if (!Out.empty() && (Out[Out.length() - 1] == '\n'))
- {
- Out.erase(Out.length() - 2);
- }
- return Out;
-
- #else // _WIN32
-
- // According to http://linux.die.net/man/3/strerror_r there are two versions of strerror_r():
-
- #if ( _GNU_SOURCE ) // GNU version of strerror_r()
-
- char * res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) );
- if( res != NULL )
- {
- Printf(Out, "%d: %s", a_ErrNo, res);
- return Out;
- }
-
- #else // XSI version of strerror_r():
-
- int res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) );
- if( res == 0 )
- {
- Printf(Out, "%d: %s", a_ErrNo, buffer);
- return Out;
- }
-
- #endif // strerror_r() version
-
- else
- {
- Printf(Out, "Error %d while getting error string for error #%d!", errno, a_ErrNo);
- return Out;
- }
-
- #endif // else _WIN32
-}
-
-
-
-
-int cSocket::GetLastError()
-{
-#ifdef _WIN32
- return WSAGetLastError();
-#else
- return errno;
-#endif
-}
-
-
-
-
-
-int cSocket::SetReuseAddress()
-{
-#ifdef _WIN32
- char yes = 1;
-#else
- int yes = 1;
-#endif
- return setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
-}
-
-
-
-
-
-int cSocket::WSAStartup()
-{
-#ifdef _WIN32
- WSADATA wsaData;
- memset(&wsaData, 0, sizeof(wsaData));
- return ::WSAStartup(MAKEWORD(2, 2),&wsaData);
-#else
- return 0;
-#endif
-}
-
-
-
-
-
-cSocket cSocket::CreateSocket()
-{
- return socket(AF_INET,SOCK_STREAM,0);
-}
-
-
-
-
-
-unsigned long cSocket::INTERNET_ADDRESS_LOCALHOST(void)
-{
- static unsigned long LocalHost = 0;
- if (LocalHost == 0)
- {
- LocalHost = inet_addr("127.0.0.1"); // GCC won't accept this as a global var assignment
- }
- return LocalHost;
-}
-
-
-
-
-
-int cSocket::Bind(SockAddr_In& a_Address)
-{
- sockaddr_in local;
- memset(&local, 0, sizeof(local));
-
- local.sin_family = a_Address.Family;
- local.sin_addr.s_addr = a_Address.Address;
- local.sin_port = htons((u_short)a_Address.Port);
-
- return bind(m_Socket, (sockaddr*)&local, sizeof(local));
-}
-
-
-
-
-
-int cSocket::Listen(int a_Backlog)
-{
- return listen(m_Socket, a_Backlog);
-}
-
-
-
-
-
-cSocket cSocket::Accept()
-{
- sockaddr_in from;
- socklen_t fromlen=sizeof(from);
-
- cSocket SClient = accept(m_Socket, (sockaddr*)&from, &fromlen);
-
- if (from.sin_addr.s_addr && SClient.IsValid()) // Get IP in string form
- {
- SClient.m_IPString = inet_ntoa(from.sin_addr);
- //LOG("cSocket::Accept() %s", SClient.m_IPString);
- }
-
- return SClient;
-}
-
-
-
-
-
-int cSocket::Connect(SockAddr_In & a_Address)
-{
- sockaddr_in local;
-
- local.sin_family = a_Address.Family;
- local.sin_addr.s_addr = a_Address.Address;
- local.sin_port = htons((u_short)a_Address.Port);
-
- return connect(m_Socket, (sockaddr *)&local, sizeof(local));
-}
-
-
-
-
-
-int cSocket::Connect(const AString & a_HostNameOrAddr, unsigned short a_Port)
-{
- // First try IP Address string to hostent conversion, because it's faster
- unsigned long addr = inet_addr(a_HostNameOrAddr.c_str());
- hostent * hp = gethostbyaddr((char*)&addr, sizeof(addr), AF_INET);
- if (hp == NULL)
- {
- // It is not an IP Address string, but rather a regular hostname, resolve:
- hp = gethostbyname(a_HostNameOrAddr.c_str());
- if (hp == NULL)
- {
- LOGWARN("cTCPLink: Could not resolve hostname \"%s\"", a_HostNameOrAddr.c_str());
- CloseSocket();
- return false;
- }
- }
-
- sockaddr_in server;
- server.sin_addr.s_addr = *((unsigned long*)hp->h_addr);
- server.sin_family = AF_INET;
- server.sin_port = htons( (unsigned short)a_Port );
- return connect(m_Socket, (sockaddr *)&server, sizeof(server));
-}
-
-
-
-
-
-int cSocket::Receive(char* a_Buffer, unsigned int a_Length, unsigned int a_Flags)
-{
- return recv(m_Socket, a_Buffer, a_Length, a_Flags);
-}
-
-
-
-
-
-int cSocket::Send(const char * a_Buffer, unsigned int a_Length)
-{
- return send(m_Socket, a_Buffer, a_Length, 0);
-}
-
-
-
-
-
-int cSocket::Send(const cPacket * a_Packet)
-{
- AString Serialized;
- a_Packet->Serialize(Serialized);
- return Send(Serialized.data(), Serialized.size());
-}
-
-
-
-
-
-int cSocket::Send(const cPacket & a_Packet)
-{
- AString Serialized;
- a_Packet.Serialize(Serialized);
- return Send(Serialized.data(), Serialized.size());
-}
-
-
-
-
-
-unsigned short cSocket::GetPort(void) const
-{
- ASSERT(IsValid());
-
- sockaddr_in Addr;
- socklen_t AddrSize = sizeof(Addr);
- if (getsockname(m_Socket, (sockaddr *)&Addr, &AddrSize) != 0)
- {
- return 0;
- }
- return ntohs(Addr.sin_port);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSocket.h" +#include "packets/cPacket.h" + +#ifndef _WIN32 + #include <netdb.h> + #include <unistd.h> + #include <arpa/inet.h> //inet_ntoa() +#else + #define socklen_t int +#endif + + + + + +cSocket::cSocket(xSocket a_Socket) + : m_Socket(a_Socket) +{ +} + + + + + +cSocket::~cSocket() +{ + // Do NOT close the socket; this class is an API wrapper, not a RAII! +} + + + + + +cSocket::operator const cSocket::xSocket() const +{ + return m_Socket; +} + + + + + +cSocket::xSocket cSocket::GetSocket() const +{ + return m_Socket; +} + + + + + +bool cSocket::IsValid(void) const +{ + #ifdef _WIN32 + return (m_Socket != INVALID_SOCKET); + #else // _WIN32 + return (m_Socket >= 0); + #endif // else _WIN32 +} + + + + + +void cSocket::CloseSocket() +{ + #ifdef _WIN32 + + closesocket(m_Socket); + + #else // _WIN32 + + if (shutdown(m_Socket, SHUT_RDWR) != 0)//SD_BOTH); + { + LOGWARN("Error on shutting down socket (%s): %s", m_IPString.c_str(), GetLastErrorString().c_str()); + } + if (close(m_Socket) != 0) + { + LOGWARN("Error closing socket (%s): %s", m_IPString.c_str(), GetLastErrorString().c_str()); + } + + #endif // else _WIN32 + + // Invalidate the socket so that this object can be re-used for another connection + m_Socket = INVALID_SOCKET; +} + + + + + +AString cSocket::GetErrorString( int a_ErrNo ) +{ + char buffer[ 1024 ]; + AString Out; + + #ifdef _WIN32 + + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, a_ErrNo, 0, buffer, ARRAYCOUNT(buffer), NULL); + Printf(Out, "%d: %s", a_ErrNo, buffer); + if (!Out.empty() && (Out[Out.length() - 1] == '\n')) + { + Out.erase(Out.length() - 2); + } + return Out; + + #else // _WIN32 + + // According to http://linux.die.net/man/3/strerror_r there are two versions of strerror_r(): + + #if ( _GNU_SOURCE ) // GNU version of strerror_r() + + char * res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) ); + if( res != NULL ) + { + Printf(Out, "%d: %s", a_ErrNo, res); + return Out; + } + + #else // XSI version of strerror_r(): + + int res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) ); + if( res == 0 ) + { + Printf(Out, "%d: %s", a_ErrNo, buffer); + return Out; + } + + #endif // strerror_r() version + + else + { + Printf(Out, "Error %d while getting error string for error #%d!", errno, a_ErrNo); + return Out; + } + + #endif // else _WIN32 +} + + + + +int cSocket::GetLastError() +{ +#ifdef _WIN32 + return WSAGetLastError(); +#else + return errno; +#endif +} + + + + + +int cSocket::SetReuseAddress() +{ +#ifdef _WIN32 + char yes = 1; +#else + int yes = 1; +#endif + return setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); +} + + + + + +int cSocket::WSAStartup() +{ +#ifdef _WIN32 + WSADATA wsaData; + memset(&wsaData, 0, sizeof(wsaData)); + return ::WSAStartup(MAKEWORD(2, 2),&wsaData); +#else + return 0; +#endif +} + + + + + +cSocket cSocket::CreateSocket() +{ + return socket(AF_INET,SOCK_STREAM,0); +} + + + + + +unsigned long cSocket::INTERNET_ADDRESS_LOCALHOST(void) +{ + static unsigned long LocalHost = 0; + if (LocalHost == 0) + { + LocalHost = inet_addr("127.0.0.1"); // GCC won't accept this as a global var assignment + } + return LocalHost; +} + + + + + +int cSocket::Bind(SockAddr_In& a_Address) +{ + sockaddr_in local; + memset(&local, 0, sizeof(local)); + + local.sin_family = a_Address.Family; + local.sin_addr.s_addr = a_Address.Address; + local.sin_port = htons((u_short)a_Address.Port); + + return bind(m_Socket, (sockaddr*)&local, sizeof(local)); +} + + + + + +int cSocket::Listen(int a_Backlog) +{ + return listen(m_Socket, a_Backlog); +} + + + + + +cSocket cSocket::Accept() +{ + sockaddr_in from; + socklen_t fromlen=sizeof(from); + + cSocket SClient = accept(m_Socket, (sockaddr*)&from, &fromlen); + + if (from.sin_addr.s_addr && SClient.IsValid()) // Get IP in string form + { + SClient.m_IPString = inet_ntoa(from.sin_addr); + //LOG("cSocket::Accept() %s", SClient.m_IPString); + } + + return SClient; +} + + + + + +int cSocket::Connect(SockAddr_In & a_Address) +{ + sockaddr_in local; + + local.sin_family = a_Address.Family; + local.sin_addr.s_addr = a_Address.Address; + local.sin_port = htons((u_short)a_Address.Port); + + return connect(m_Socket, (sockaddr *)&local, sizeof(local)); +} + + + + + +int cSocket::Connect(const AString & a_HostNameOrAddr, unsigned short a_Port) +{ + // First try IP Address string to hostent conversion, because it's faster + unsigned long addr = inet_addr(a_HostNameOrAddr.c_str()); + hostent * hp = gethostbyaddr((char*)&addr, sizeof(addr), AF_INET); + if (hp == NULL) + { + // It is not an IP Address string, but rather a regular hostname, resolve: + hp = gethostbyname(a_HostNameOrAddr.c_str()); + if (hp == NULL) + { + LOGWARN("cTCPLink: Could not resolve hostname \"%s\"", a_HostNameOrAddr.c_str()); + CloseSocket(); + return false; + } + } + + sockaddr_in server; + server.sin_addr.s_addr = *((unsigned long*)hp->h_addr); + server.sin_family = AF_INET; + server.sin_port = htons( (unsigned short)a_Port ); + return connect(m_Socket, (sockaddr *)&server, sizeof(server)); +} + + + + + +int cSocket::Receive(char* a_Buffer, unsigned int a_Length, unsigned int a_Flags) +{ + return recv(m_Socket, a_Buffer, a_Length, a_Flags); +} + + + + + +int cSocket::Send(const char * a_Buffer, unsigned int a_Length) +{ + return send(m_Socket, a_Buffer, a_Length, 0); +} + + + + + +int cSocket::Send(const cPacket * a_Packet) +{ + AString Serialized; + a_Packet->Serialize(Serialized); + return Send(Serialized.data(), Serialized.size()); +} + + + + + +int cSocket::Send(const cPacket & a_Packet) +{ + AString Serialized; + a_Packet.Serialize(Serialized); + return Send(Serialized.data(), Serialized.size()); +} + + + + + +unsigned short cSocket::GetPort(void) const +{ + ASSERT(IsValid()); + + sockaddr_in Addr; + socklen_t AddrSize = sizeof(Addr); + if (getsockname(m_Socket, (sockaddr *)&Addr, &AddrSize) != 0) + { + return 0; + } + return ntohs(Addr.sin_port); +} + + + + diff --git a/source/cSocket.h b/source/cSocket.h index 21a7cf3c2..0ed7b1a4e 100644 --- a/source/cSocket.h +++ b/source/cSocket.h @@ -1,87 +1,87 @@ -
-#pragma once
-
-
-
-
-
-class cPacket;
-
-
-
-
-
-class cSocket
-{
-public:
-#ifdef _WIN32
- typedef SOCKET xSocket;
-#else
- typedef int xSocket;
- static const int INVALID_SOCKET = -1;
-#endif
-
- cSocket(void) : m_Socket(INVALID_SOCKET) {}
- cSocket(xSocket a_Socket);
- ~cSocket();
-
- bool IsValid(void) const;
- void CloseSocket();
-
- operator const xSocket() const;
- xSocket GetSocket() const;
-
- bool operator == (const cSocket & a_Other) {return m_Socket == a_Other.m_Socket; }
-
- void SetSocket( xSocket a_Socket );
-
- int SetReuseAddress();
- static int WSAStartup();
-
- static AString GetErrorString( int a_ErrNo );
- static int GetLastError();
- static AString GetLastErrorString(void)
- {
- return GetErrorString(GetLastError());
- }
-
- static cSocket CreateSocket();
-
- inline static bool IsSocketError( int a_ReturnedValue )
- {
-#ifdef _WIN32
- return (a_ReturnedValue == SOCKET_ERROR || a_ReturnedValue == 0);
-#else
- return (a_ReturnedValue <= 0);
-#endif
- }
-
- struct SockAddr_In
- {
- short Family;
- unsigned short Port;
- unsigned long Address;
- };
-
- static const short ADDRESS_FAMILY_INTERNET = 2;
- static const unsigned long INTERNET_ADDRESS_ANY = 0;
- static unsigned long INTERNET_ADDRESS_LOCALHOST(void); // 127.0.0.1 represented in network byteorder; must be a function due to GCC :(
-
- int Bind( SockAddr_In& a_Address );
- int Listen( int a_Backlog );
- cSocket Accept();
- int Connect(SockAddr_In & a_Address); // Returns 0 on success, !0 on failure
- int Connect(const AString & a_HostNameOrAddr, unsigned short a_Port); // Returns 0 on success, !0 on failure
- int Receive( char* a_Buffer, unsigned int a_Length, unsigned int a_Flags );
- int Send (const char * a_Buffer, unsigned int a_Length);
- int Send (const cPacket * a_Packet); // Sends the packet, doesn't handle partial sends
- int Send (const cPacket & a_Packet); // Sends the packet, doesn't handle partial sends
-
- unsigned short GetPort(void) const; // Returns 0 on failure
-
- const AString & GetIPString(void) const { return m_IPString; }
-
-private:
- xSocket m_Socket;
- AString m_IPString;
+ +#pragma once + + + + + +class cPacket; + + + + + +class cSocket +{ +public: +#ifdef _WIN32 + typedef SOCKET xSocket; +#else + typedef int xSocket; + static const int INVALID_SOCKET = -1; +#endif + + cSocket(void) : m_Socket(INVALID_SOCKET) {} + cSocket(xSocket a_Socket); + ~cSocket(); + + bool IsValid(void) const; + void CloseSocket(); + + operator const xSocket() const; + xSocket GetSocket() const; + + bool operator == (const cSocket & a_Other) {return m_Socket == a_Other.m_Socket; } + + void SetSocket( xSocket a_Socket ); + + int SetReuseAddress(); + static int WSAStartup(); + + static AString GetErrorString( int a_ErrNo ); + static int GetLastError(); + static AString GetLastErrorString(void) + { + return GetErrorString(GetLastError()); + } + + static cSocket CreateSocket(); + + inline static bool IsSocketError( int a_ReturnedValue ) + { +#ifdef _WIN32 + return (a_ReturnedValue == SOCKET_ERROR || a_ReturnedValue == 0); +#else + return (a_ReturnedValue <= 0); +#endif + } + + struct SockAddr_In + { + short Family; + unsigned short Port; + unsigned long Address; + }; + + static const short ADDRESS_FAMILY_INTERNET = 2; + static const unsigned long INTERNET_ADDRESS_ANY = 0; + static unsigned long INTERNET_ADDRESS_LOCALHOST(void); // 127.0.0.1 represented in network byteorder; must be a function due to GCC :( + + int Bind( SockAddr_In& a_Address ); + int Listen( int a_Backlog ); + cSocket Accept(); + int Connect(SockAddr_In & a_Address); // Returns 0 on success, !0 on failure + int Connect(const AString & a_HostNameOrAddr, unsigned short a_Port); // Returns 0 on success, !0 on failure + int Receive( char* a_Buffer, unsigned int a_Length, unsigned int a_Flags ); + int Send (const char * a_Buffer, unsigned int a_Length); + int Send (const cPacket * a_Packet); // Sends the packet, doesn't handle partial sends + int Send (const cPacket & a_Packet); // Sends the packet, doesn't handle partial sends + + unsigned short GetPort(void) const; // Returns 0 on failure + + const AString & GetIPString(void) const { return m_IPString; } + +private: + xSocket m_Socket; + AString m_IPString; };
\ No newline at end of file diff --git a/source/cSocketThreads.cpp b/source/cSocketThreads.cpp index fbef2a2c3..b27523972 100644 --- a/source/cSocketThreads.cpp +++ b/source/cSocketThreads.cpp @@ -1,715 +1,715 @@ -
-// cSocketThreads.cpp
-
-// Implements the cSocketThreads class representing the heart of MCS's client networking.
-// This object takes care of network communication, groups sockets into threads and uses as little threads as possible for full read / write support
-// For more detail, see http://forum.mc-server.org/showthread.php?tid=327
-
-#include "Globals.h"
-#include "cSocketThreads.h"
-#include "cClientHandle.h"
-// #include "packets/cPacket_RelativeEntityMoveLook.h"
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cSocketThreads:
-
-cSocketThreads::cSocketThreads(void)
-{
- LOG("cSocketThreads startup");
-}
-
-
-
-
-
-cSocketThreads::~cSocketThreads()
-{
- for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr)
- {
- delete *itr;
- } // for itr - m_Threads[]
- m_Threads.clear();
-}
-
-
-
-
-
-
-bool cSocketThreads::AddClient(cSocket * a_Socket, cCallback * a_Client)
-{
- // Add a (socket, client) pair for processing, data from a_Socket is to be sent to a_Client
-
- // Try to add to existing threads:
- cCSLock Lock(m_CS);
- for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr)
- {
- if ((*itr)->IsValid() && (*itr)->HasEmptySlot())
- {
- (*itr)->AddClient(a_Socket, a_Client);
- return true;
- }
- }
-
- // No thread has free space, create a new one:
- LOG("Creating a new cSocketThread (currently have %d)", m_Threads.size());
- cSocketThread * Thread = new cSocketThread(this);
- if (!Thread->Start())
- {
- // There was an error launching the thread (but it was already logged along with the reason)
- LOGERROR("A new cSocketThread failed to start");
- delete Thread;
- return false;
- }
- Thread->AddClient(a_Socket, a_Client);
- m_Threads.push_back(Thread);
- return true;
-}
-
-
-
-
-
-void cSocketThreads::RemoveClient(const cSocket * a_Socket)
-{
- // Remove the socket (and associated client) from processing
-
- cCSLock Lock(m_CS);
- for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr)
- {
- if ((*itr)->RemoveSocket(a_Socket))
- {
- return;
- }
- } // for itr - m_Threads[]
-
- // Cannot assert here, this may actually happen legally, since cClientHandle has to clean up the socket and it may have already closed in the meantime
- // ASSERT(!"Removing an unknown socket");
-}
-
-
-
-
-
-void cSocketThreads::RemoveClient(const cCallback * a_Client)
-{
- // Remove the associated socket and the client from processing
-
- cCSLock Lock(m_CS);
- for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr)
- {
- if ((*itr)->RemoveClient(a_Client))
- {
- return;
- }
- } // for itr - m_Threads[]
-
- ASSERT(!"Removing an unknown client");
-}
-
-
-
-
-
-void cSocketThreads::NotifyWrite(const cCallback * a_Client)
-{
- // Notifies the thread responsible for a_Client that the client has something to write
-
- cCSLock Lock(m_CS);
- for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr)
- {
- if ((*itr)->NotifyWrite(a_Client))
- {
- return;
- }
- } // for itr - m_Threads[]
-
- // Cannot assert - this normally happens if a client disconnects and has pending packets, the cServer::cNotifyWriteThread will call this on invalid clients too
- // ASSERT(!"Notifying write to an unknown client");
-}
-
-
-
-
-
-void cSocketThreads::Write(const cSocket * a_Socket, const AString & a_Data)
-{
- // Puts a_Data into outgoing data queue for a_Socket
-
- if (!a_Socket->IsValid())
- {
- // Socket already closed, ignore the request
- return;
- }
-
- cCSLock Lock(m_CS);
- for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr)
- {
- if ((*itr)->Write(a_Socket, a_Data))
- {
- return;
- }
- } // for itr - m_Threads[]
-
- // This may be perfectly legal, if the socket has been destroyed and the client is finishing up
- // ASSERT(!"Writing to an unknown socket");
-}
-
-
-
-
-
-/// Stops reading from the socket - when this call returns, no more calls to the callbacks are made
-void cSocketThreads::StopReading(const cCallback * a_Client)
-{
- cCSLock Lock(m_CS);
- for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr)
- {
- if ((*itr)->StopReading(a_Client))
- {
- return;
- }
- } // for itr - m_Threads[]
-
- // Cannot assert, this normally happens if the socket is closed before the client deinitializes
- // ASSERT(!"Stopping reading on an unknown client");
-}
-
-
-
-
-
-/// Queues the socket for closing, as soon as its outgoing data is sent
-void cSocketThreads::QueueClose(const cSocket * a_Socket)
-{
- if (!a_Socket->IsValid())
- {
- // Already closed, ignore the request
- return;
- }
-
- cCSLock Lock(m_CS);
- for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr)
- {
- if ((*itr)->QueueClose(a_Socket))
- {
- return;
- }
- } // for itr - m_Threads[]
-
- ASSERT(!"Queueing close of an unknown socket");
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// cSocketThreads::cSocketThread:
-
-cSocketThreads::cSocketThread::cSocketThread(cSocketThreads * a_Parent) :
- cIsThread("cSocketThread"),
- m_Parent(a_Parent),
- m_NumSlots(0)
-{
- // Nothing needed yet
-}
-
-
-
-
-
-cSocketThreads::cSocketThread::~cSocketThread()
-{
- m_ShouldTerminate = true;
-
- // Notify the thread:
- ASSERT(m_ControlSocket2.IsValid());
- m_ControlSocket2.Send("a", 1);
-
- // Wait for the thread to finish:
- Wait();
-
- // Close the control sockets:
- m_ControlSocket1.CloseSocket();
- m_ControlSocket2.CloseSocket();
-}
-
-
-
-
-
-void cSocketThreads::cSocketThread::AddClient(cSocket * a_Socket, cCallback * a_Client)
-{
- ASSERT(m_NumSlots < MAX_SLOTS); // Use HasEmptySlot() to check before adding
-
- m_Slots[m_NumSlots].m_Client = a_Client;
- m_Slots[m_NumSlots].m_Socket = a_Socket;
- m_Slots[m_NumSlots].m_Outgoing.clear();
- m_NumSlots++;
-
- // Notify the thread of the change:
- ASSERT(m_ControlSocket2.IsValid());
- m_ControlSocket2.Send("a", 1);
-}
-
-
-
-
-
-bool cSocketThreads::cSocketThread::RemoveClient(const cCallback * a_Client)
-{
- // Returns true if removed, false if not found
-
- if (m_NumSlots == 0)
- {
- return false;
- }
-
- for (int i = m_NumSlots - 1; i >= 0 ; --i)
- {
- if (m_Slots[i].m_Client != a_Client)
- {
- continue;
- }
-
- // Found, remove it:
- m_Slots[i] = m_Slots[--m_NumSlots];
-
- // Notify the thread of the change:
- ASSERT(m_ControlSocket2.IsValid());
- m_ControlSocket2.Send("r", 1);
- return true;
- } // for i - m_Slots[]
-
- // Not found
- return false;
-}
-
-
-
-
-
-bool cSocketThreads::cSocketThread::RemoveSocket(const cSocket * a_Socket)
-{
- // Returns true if removed, false if not found
-
- for (int i = m_NumSlots - 1; i >= 0 ; --i)
- {
- if (m_Slots[i].m_Socket != a_Socket)
- {
- continue;
- }
-
- // Found, remove it:
- m_Slots[i] = m_Slots[--m_NumSlots];
-
- // Notify the thread of the change:
- ASSERT(m_ControlSocket2.IsValid());
- m_ControlSocket2.Send("r", 1);
- return true;
- } // for i - m_Slots[]
-
- // Not found
- return false;
-}
-
-
-
-
-
-bool cSocketThreads::cSocketThread::HasClient(const cCallback * a_Client) const
-{
- for (int i = m_NumSlots - 1; i >= 0; --i)
- {
- if (m_Slots[i].m_Client == a_Client)
- {
- return true;
- }
- } // for i - m_Slots[]
- return false;
-}
-
-
-
-
-
-bool cSocketThreads::cSocketThread::HasSocket(const cSocket * a_Socket) const
-{
- for (int i = m_NumSlots - 1; i >= 0; --i)
- {
- if (m_Slots[i].m_Socket->GetSocket() == a_Socket->GetSocket())
- {
- return true;
- }
- } // for i - m_Slots[]
- return false;
-}
-
-
-
-
-
-bool cSocketThreads::cSocketThread::NotifyWrite(const cCallback * a_Client)
-{
- if (HasClient(a_Client))
- {
- // Notify the thread that there's another packet in the queue:
- ASSERT(m_ControlSocket2.IsValid());
- m_ControlSocket2.Send("q", 1);
- return true;
- }
- return false;
-}
-
-
-
-
-
-bool cSocketThreads::cSocketThread::Write(const cSocket * a_Socket, const AString & a_Data)
-{
- // Returns true if socket handled by this thread
- for (int i = m_NumSlots - 1; i >= 0; --i)
- {
- if (m_Slots[i].m_Socket == a_Socket)
- {
- m_Slots[i].m_Outgoing.append(a_Data);
-
- // Notify the thread that there's data in the queue:
- ASSERT(m_ControlSocket2.IsValid());
- m_ControlSocket2.Send("q", 1);
-
- return true;
- }
- } // for i - m_Slots[]
- return false;
-}
-
-
-
-
-
-bool cSocketThreads::cSocketThread::StopReading (const cCallback * a_Client)
-{
- // Returns true if client handled by this thread
- for (int i = m_NumSlots - 1; i >= 0; --i)
- {
- if (m_Slots[i].m_Client == a_Client)
- {
- m_Slots[i].m_Client = NULL;
- m_Slots[i].m_ShouldClose = false;
-
- // Notify the thread that there's a stop reading request:
- ASSERT(m_ControlSocket2.IsValid());
- m_ControlSocket2.Send("s", 1);
-
- return true;
- }
- } // for i - m_Slots[]
- return false;
-}
-
-
-
-
-
-bool cSocketThreads::cSocketThread::QueueClose(const cSocket * a_Socket)
-{
- // Returns true if socket handled by this thread
- for (int i = m_NumSlots - 1; i >= 0; --i)
- {
- if (m_Slots[i].m_Socket == a_Socket)
- {
- ASSERT(m_Slots[i].m_Client == NULL); // Should have stopped reading first
- m_Slots[i].m_ShouldClose = true;
-
- // Notify the thread that there's a close queued (in case its conditions are already met):
- ASSERT(m_ControlSocket2.IsValid());
- m_ControlSocket2.Send("c", 1);
-
- return true;
- }
- } // for i - m_Slots[]
- return false;
-}
-
-
-
-
-
-bool cSocketThreads::cSocketThread::Start(void)
-{
- // Create the control socket listener
- m_ControlSocket2 = cSocket::CreateSocket();
- if (!m_ControlSocket2.IsValid())
- {
- LOGERROR("Cannot create a Control socket for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str());
- return false;
- }
- cSocket::SockAddr_In Addr;
- Addr.Family = cSocket::ADDRESS_FAMILY_INTERNET;
- Addr.Address = cSocket::INTERNET_ADDRESS_LOCALHOST();
- Addr.Port = 0; // Any free port is okay
- if (m_ControlSocket2.Bind(Addr) != 0)
- {
- LOGERROR("Cannot bind a Control socket for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str());
- m_ControlSocket2.CloseSocket();
- return false;
- }
- if (m_ControlSocket2.Listen(1) != 0)
- {
- LOGERROR("Cannot listen on a Control socket for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str());
- m_ControlSocket2.CloseSocket();
- return false;
- }
- if (m_ControlSocket2.GetPort() == 0)
- {
- LOGERROR("Cannot determine Control socket port (\"%s\"); conitnuing, but the server may be unreachable from now on.", cSocket::GetLastErrorString().c_str());
- m_ControlSocket2.CloseSocket();
- return false;
- }
-
- // Start the thread
- if (!super::Start())
- {
- LOGERROR("Cannot start new cSocketThread");
- m_ControlSocket2.CloseSocket();
- return false;
- }
-
- // Finish connecting the control socket by accepting connection from the thread's socket
- cSocket tmp = m_ControlSocket2.Accept();
- if (!tmp.IsValid())
- {
- LOGERROR("Cannot link Control sockets for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str());
- m_ControlSocket2.CloseSocket();
- return false;
- }
- m_ControlSocket2.CloseSocket();
- m_ControlSocket2 = tmp;
-
- return true;
-}
-
-
-
-
-
-void cSocketThreads::cSocketThread::Execute(void)
-{
- // Connect the "client" part of the Control socket:
- m_ControlSocket1 = cSocket::CreateSocket();
- cSocket::SockAddr_In Addr;
- Addr.Family = cSocket::ADDRESS_FAMILY_INTERNET;
- Addr.Address = cSocket::INTERNET_ADDRESS_LOCALHOST();
- Addr.Port = m_ControlSocket2.GetPort();
- ASSERT(Addr.Port != 0); // We checked in the Start() method, but let's be sure
- if (m_ControlSocket1.Connect(Addr) != 0)
- {
- LOGERROR("Cannot connect Control sockets for a cSocketThread (\"%s\"); continuing, but the server may be unreachable from now on.", cSocket::GetLastErrorString().c_str());
- m_ControlSocket2.CloseSocket();
- return;
- }
-
- // The main thread loop:
- while (!m_ShouldTerminate)
- {
- // Put all sockets into the Read set:
- fd_set fdRead;
- cSocket::xSocket Highest = m_ControlSocket1.GetSocket();
-
- PrepareSet(&fdRead, Highest);
-
- // Wait for the sockets:
- if (select(Highest + 1, &fdRead, NULL, NULL, NULL) == -1)
- {
- LOG("select(R) call failed in cSocketThread: \"%s\"", cSocket::GetLastErrorString().c_str());
- continue;
- }
-
- ReadFromSockets(&fdRead);
-
- // Test sockets for writing:
- fd_set fdWrite;
- Highest = m_ControlSocket1.GetSocket();
- PrepareSet(&fdWrite, Highest);
- timeval Timeout;
- Timeout.tv_sec = 0;
- Timeout.tv_usec = 0;
- if (select(Highest + 1, NULL, &fdWrite, NULL, &Timeout) == -1)
- {
- LOG("select(W) call failed in cSocketThread: \"%s\"", cSocket::GetLastErrorString().c_str());
- continue;
- }
-
- WriteToSockets(&fdWrite);
-
- RemoveClosedSockets();
- } // while (!mShouldTerminate)
-}
-
-
-
-
-
-void cSocketThreads::cSocketThread::PrepareSet(fd_set * a_Set, cSocket::xSocket & a_Highest)
-{
- FD_ZERO(a_Set);
- FD_SET(m_ControlSocket1.GetSocket(), a_Set);
-
- cCSLock Lock(m_Parent->m_CS);
- for (int i = m_NumSlots - 1; i >= 0; --i)
- {
- if (!m_Slots[i].m_Socket->IsValid())
- {
- continue;
- }
- cSocket::xSocket s = m_Slots[i].m_Socket->GetSocket();
- FD_SET(s, a_Set);
- if (s > a_Highest)
- {
- a_Highest = s;
- }
- } // for i - m_Slots[]
-}
-
-
-
-
-
-void cSocketThreads::cSocketThread::ReadFromSockets(fd_set * a_Read)
-{
- // Read on available sockets:
-
- // Reset Control socket state:
- if (FD_ISSET(m_ControlSocket1.GetSocket(), a_Read))
- {
- char Dummy[128];
- m_ControlSocket1.Receive(Dummy, sizeof(Dummy), 0);
- }
-
- // Read from clients:
- cCSLock Lock(m_Parent->m_CS);
- for (int i = m_NumSlots - 1; i >= 0; --i)
- {
- if (!FD_ISSET(m_Slots[i].m_Socket->GetSocket(), a_Read))
- {
- continue;
- }
- char Buffer[1024];
- int Received = m_Slots[i].m_Socket->Receive(Buffer, ARRAYCOUNT(Buffer), 0);
- if (Received == 0)
- {
- // The socket has been closed by the remote party, close our socket and let it be removed after we process all reading
- m_Slots[i].m_Socket->CloseSocket();
- if (m_Slots[i].m_Client != NULL)
- {
- m_Slots[i].m_Client->SocketClosed();
- }
- }
- else if (Received > 0)
- {
- if (m_Slots[i].m_Client != NULL)
- {
- m_Slots[i].m_Client->DataReceived(Buffer, Received);
- }
- }
- else
- {
- // The socket has encountered an error, close it and let it be removed after we process all reading
- m_Slots[i].m_Socket->CloseSocket();
- if (m_Slots[i].m_Client != NULL)
- {
- m_Slots[i].m_Client->SocketClosed();
- }
- }
- } // for i - m_Slots[]
-}
-
-
-
-
-
-void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write)
-{
- // Write to available client sockets:
- cCSLock Lock(m_Parent->m_CS);
- for (int i = m_NumSlots - 1; i >= 0; --i)
- {
- if (!FD_ISSET(m_Slots[i].m_Socket->GetSocket(), a_Write))
- {
- continue;
- }
- if (m_Slots[i].m_Outgoing.empty())
- {
- // Request another chunk of outgoing data:
- if (m_Slots[i].m_Client != NULL)
- {
- m_Slots[i].m_Client->GetOutgoingData(m_Slots[i].m_Outgoing);
- }
- if (m_Slots[i].m_Outgoing.empty())
- {
- // Nothing ready
- if ((m_Slots[i].m_Client == NULL) && m_Slots[i].m_ShouldClose)
- {
- // Socket was queued for closing and there's no more data to send, close it now:
- m_Slots[i].m_Socket->CloseSocket();
- m_Slots[i] = m_Slots[--m_NumSlots];
- }
- continue;
- }
- } // if (outgoing data is empty)
-
- int Sent = m_Slots[i].m_Socket->Send(m_Slots[i].m_Outgoing.data(), m_Slots[i].m_Outgoing.size());
- if (Sent < 0)
- {
- int Err = cSocket::GetLastError();
- LOGWARNING("Error %d while writing to client \"%s\", disconnecting. \"%s\"", Err, m_Slots[i].m_Socket->GetIPString().c_str(), cSocket::GetErrorString(Err).c_str());
- m_Slots[i].m_Socket->CloseSocket();
- if (m_Slots[i].m_Client != NULL)
- {
- m_Slots[i].m_Client->SocketClosed();
- }
- return;
- }
- m_Slots[i].m_Outgoing.erase(0, Sent);
-
- // _X: If there's data left, it means the client is not reading fast enough, the server would unnecessarily spin in the main loop with zero actions taken; so signalling is disabled
- // This means that if there's data left, it will be sent only when there's incoming data or someone queues another packet (for any socket handled by this thread)
- /*
- // If there's any data left, signalize the Control socket:
- if (!m_Slots[i].m_Outgoing.empty())
- {
- ASSERT(m_ControlSocket2.IsValid());
- m_ControlSocket2.Send("q", 1);
- }
- */
- } // for i - m_Slots[i]
-}
-
-
-
-
-
-void cSocketThreads::cSocketThread::RemoveClosedSockets(void)
-{
- // Removes sockets that have closed from m_Slots[]
-
- cCSLock Lock(m_Parent->m_CS);
- for (int i = m_NumSlots - 1; i >= 0; --i)
- {
- if (m_Slots[i].m_Socket->IsValid())
- {
- continue;
- }
- m_Slots[i] = m_Slots[--m_NumSlots];
- } // for i - m_Slots[]
-}
-
-
-
-
+ +// cSocketThreads.cpp + +// Implements the cSocketThreads class representing the heart of MCS's client networking. +// This object takes care of network communication, groups sockets into threads and uses as little threads as possible for full read / write support +// For more detail, see http://forum.mc-server.org/showthread.php?tid=327 + +#include "Globals.h" +#include "cSocketThreads.h" +#include "cClientHandle.h" +// #include "packets/cPacket_RelativeEntityMoveLook.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cSocketThreads: + +cSocketThreads::cSocketThreads(void) +{ + LOG("cSocketThreads startup"); +} + + + + + +cSocketThreads::~cSocketThreads() +{ + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + delete *itr; + } // for itr - m_Threads[] + m_Threads.clear(); +} + + + + + + +bool cSocketThreads::AddClient(cSocket * a_Socket, cCallback * a_Client) +{ + // Add a (socket, client) pair for processing, data from a_Socket is to be sent to a_Client + + // Try to add to existing threads: + cCSLock Lock(m_CS); + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + if ((*itr)->IsValid() && (*itr)->HasEmptySlot()) + { + (*itr)->AddClient(a_Socket, a_Client); + return true; + } + } + + // No thread has free space, create a new one: + LOG("Creating a new cSocketThread (currently have %d)", m_Threads.size()); + cSocketThread * Thread = new cSocketThread(this); + if (!Thread->Start()) + { + // There was an error launching the thread (but it was already logged along with the reason) + LOGERROR("A new cSocketThread failed to start"); + delete Thread; + return false; + } + Thread->AddClient(a_Socket, a_Client); + m_Threads.push_back(Thread); + return true; +} + + + + + +void cSocketThreads::RemoveClient(const cSocket * a_Socket) +{ + // Remove the socket (and associated client) from processing + + cCSLock Lock(m_CS); + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + if ((*itr)->RemoveSocket(a_Socket)) + { + return; + } + } // for itr - m_Threads[] + + // Cannot assert here, this may actually happen legally, since cClientHandle has to clean up the socket and it may have already closed in the meantime + // ASSERT(!"Removing an unknown socket"); +} + + + + + +void cSocketThreads::RemoveClient(const cCallback * a_Client) +{ + // Remove the associated socket and the client from processing + + cCSLock Lock(m_CS); + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + if ((*itr)->RemoveClient(a_Client)) + { + return; + } + } // for itr - m_Threads[] + + ASSERT(!"Removing an unknown client"); +} + + + + + +void cSocketThreads::NotifyWrite(const cCallback * a_Client) +{ + // Notifies the thread responsible for a_Client that the client has something to write + + cCSLock Lock(m_CS); + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + if ((*itr)->NotifyWrite(a_Client)) + { + return; + } + } // for itr - m_Threads[] + + // Cannot assert - this normally happens if a client disconnects and has pending packets, the cServer::cNotifyWriteThread will call this on invalid clients too + // ASSERT(!"Notifying write to an unknown client"); +} + + + + + +void cSocketThreads::Write(const cSocket * a_Socket, const AString & a_Data) +{ + // Puts a_Data into outgoing data queue for a_Socket + + if (!a_Socket->IsValid()) + { + // Socket already closed, ignore the request + return; + } + + cCSLock Lock(m_CS); + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + if ((*itr)->Write(a_Socket, a_Data)) + { + return; + } + } // for itr - m_Threads[] + + // This may be perfectly legal, if the socket has been destroyed and the client is finishing up + // ASSERT(!"Writing to an unknown socket"); +} + + + + + +/// Stops reading from the socket - when this call returns, no more calls to the callbacks are made +void cSocketThreads::StopReading(const cCallback * a_Client) +{ + cCSLock Lock(m_CS); + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + if ((*itr)->StopReading(a_Client)) + { + return; + } + } // for itr - m_Threads[] + + // Cannot assert, this normally happens if the socket is closed before the client deinitializes + // ASSERT(!"Stopping reading on an unknown client"); +} + + + + + +/// Queues the socket for closing, as soon as its outgoing data is sent +void cSocketThreads::QueueClose(const cSocket * a_Socket) +{ + if (!a_Socket->IsValid()) + { + // Already closed, ignore the request + return; + } + + cCSLock Lock(m_CS); + for (cSocketThreadList::iterator itr = m_Threads.begin(); itr != m_Threads.end(); ++itr) + { + if ((*itr)->QueueClose(a_Socket)) + { + return; + } + } // for itr - m_Threads[] + + ASSERT(!"Queueing close of an unknown socket"); +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cSocketThreads::cSocketThread: + +cSocketThreads::cSocketThread::cSocketThread(cSocketThreads * a_Parent) : + cIsThread("cSocketThread"), + m_Parent(a_Parent), + m_NumSlots(0) +{ + // Nothing needed yet +} + + + + + +cSocketThreads::cSocketThread::~cSocketThread() +{ + m_ShouldTerminate = true; + + // Notify the thread: + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("a", 1); + + // Wait for the thread to finish: + Wait(); + + // Close the control sockets: + m_ControlSocket1.CloseSocket(); + m_ControlSocket2.CloseSocket(); +} + + + + + +void cSocketThreads::cSocketThread::AddClient(cSocket * a_Socket, cCallback * a_Client) +{ + ASSERT(m_NumSlots < MAX_SLOTS); // Use HasEmptySlot() to check before adding + + m_Slots[m_NumSlots].m_Client = a_Client; + m_Slots[m_NumSlots].m_Socket = a_Socket; + m_Slots[m_NumSlots].m_Outgoing.clear(); + m_NumSlots++; + + // Notify the thread of the change: + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("a", 1); +} + + + + + +bool cSocketThreads::cSocketThread::RemoveClient(const cCallback * a_Client) +{ + // Returns true if removed, false if not found + + if (m_NumSlots == 0) + { + return false; + } + + for (int i = m_NumSlots - 1; i >= 0 ; --i) + { + if (m_Slots[i].m_Client != a_Client) + { + continue; + } + + // Found, remove it: + m_Slots[i] = m_Slots[--m_NumSlots]; + + // Notify the thread of the change: + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("r", 1); + return true; + } // for i - m_Slots[] + + // Not found + return false; +} + + + + + +bool cSocketThreads::cSocketThread::RemoveSocket(const cSocket * a_Socket) +{ + // Returns true if removed, false if not found + + for (int i = m_NumSlots - 1; i >= 0 ; --i) + { + if (m_Slots[i].m_Socket != a_Socket) + { + continue; + } + + // Found, remove it: + m_Slots[i] = m_Slots[--m_NumSlots]; + + // Notify the thread of the change: + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("r", 1); + return true; + } // for i - m_Slots[] + + // Not found + return false; +} + + + + + +bool cSocketThreads::cSocketThread::HasClient(const cCallback * a_Client) const +{ + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (m_Slots[i].m_Client == a_Client) + { + return true; + } + } // for i - m_Slots[] + return false; +} + + + + + +bool cSocketThreads::cSocketThread::HasSocket(const cSocket * a_Socket) const +{ + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (m_Slots[i].m_Socket->GetSocket() == a_Socket->GetSocket()) + { + return true; + } + } // for i - m_Slots[] + return false; +} + + + + + +bool cSocketThreads::cSocketThread::NotifyWrite(const cCallback * a_Client) +{ + if (HasClient(a_Client)) + { + // Notify the thread that there's another packet in the queue: + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("q", 1); + return true; + } + return false; +} + + + + + +bool cSocketThreads::cSocketThread::Write(const cSocket * a_Socket, const AString & a_Data) +{ + // Returns true if socket handled by this thread + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (m_Slots[i].m_Socket == a_Socket) + { + m_Slots[i].m_Outgoing.append(a_Data); + + // Notify the thread that there's data in the queue: + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("q", 1); + + return true; + } + } // for i - m_Slots[] + return false; +} + + + + + +bool cSocketThreads::cSocketThread::StopReading (const cCallback * a_Client) +{ + // Returns true if client handled by this thread + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (m_Slots[i].m_Client == a_Client) + { + m_Slots[i].m_Client = NULL; + m_Slots[i].m_ShouldClose = false; + + // Notify the thread that there's a stop reading request: + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("s", 1); + + return true; + } + } // for i - m_Slots[] + return false; +} + + + + + +bool cSocketThreads::cSocketThread::QueueClose(const cSocket * a_Socket) +{ + // Returns true if socket handled by this thread + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (m_Slots[i].m_Socket == a_Socket) + { + ASSERT(m_Slots[i].m_Client == NULL); // Should have stopped reading first + m_Slots[i].m_ShouldClose = true; + + // Notify the thread that there's a close queued (in case its conditions are already met): + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("c", 1); + + return true; + } + } // for i - m_Slots[] + return false; +} + + + + + +bool cSocketThreads::cSocketThread::Start(void) +{ + // Create the control socket listener + m_ControlSocket2 = cSocket::CreateSocket(); + if (!m_ControlSocket2.IsValid()) + { + LOGERROR("Cannot create a Control socket for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); + return false; + } + cSocket::SockAddr_In Addr; + Addr.Family = cSocket::ADDRESS_FAMILY_INTERNET; + Addr.Address = cSocket::INTERNET_ADDRESS_LOCALHOST(); + Addr.Port = 0; // Any free port is okay + if (m_ControlSocket2.Bind(Addr) != 0) + { + LOGERROR("Cannot bind a Control socket for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); + m_ControlSocket2.CloseSocket(); + return false; + } + if (m_ControlSocket2.Listen(1) != 0) + { + LOGERROR("Cannot listen on a Control socket for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); + m_ControlSocket2.CloseSocket(); + return false; + } + if (m_ControlSocket2.GetPort() == 0) + { + LOGERROR("Cannot determine Control socket port (\"%s\"); conitnuing, but the server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); + m_ControlSocket2.CloseSocket(); + return false; + } + + // Start the thread + if (!super::Start()) + { + LOGERROR("Cannot start new cSocketThread"); + m_ControlSocket2.CloseSocket(); + return false; + } + + // Finish connecting the control socket by accepting connection from the thread's socket + cSocket tmp = m_ControlSocket2.Accept(); + if (!tmp.IsValid()) + { + LOGERROR("Cannot link Control sockets for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); + m_ControlSocket2.CloseSocket(); + return false; + } + m_ControlSocket2.CloseSocket(); + m_ControlSocket2 = tmp; + + return true; +} + + + + + +void cSocketThreads::cSocketThread::Execute(void) +{ + // Connect the "client" part of the Control socket: + m_ControlSocket1 = cSocket::CreateSocket(); + cSocket::SockAddr_In Addr; + Addr.Family = cSocket::ADDRESS_FAMILY_INTERNET; + Addr.Address = cSocket::INTERNET_ADDRESS_LOCALHOST(); + Addr.Port = m_ControlSocket2.GetPort(); + ASSERT(Addr.Port != 0); // We checked in the Start() method, but let's be sure + if (m_ControlSocket1.Connect(Addr) != 0) + { + LOGERROR("Cannot connect Control sockets for a cSocketThread (\"%s\"); continuing, but the server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); + m_ControlSocket2.CloseSocket(); + return; + } + + // The main thread loop: + while (!m_ShouldTerminate) + { + // Put all sockets into the Read set: + fd_set fdRead; + cSocket::xSocket Highest = m_ControlSocket1.GetSocket(); + + PrepareSet(&fdRead, Highest); + + // Wait for the sockets: + if (select(Highest + 1, &fdRead, NULL, NULL, NULL) == -1) + { + LOG("select(R) call failed in cSocketThread: \"%s\"", cSocket::GetLastErrorString().c_str()); + continue; + } + + ReadFromSockets(&fdRead); + + // Test sockets for writing: + fd_set fdWrite; + Highest = m_ControlSocket1.GetSocket(); + PrepareSet(&fdWrite, Highest); + timeval Timeout; + Timeout.tv_sec = 0; + Timeout.tv_usec = 0; + if (select(Highest + 1, NULL, &fdWrite, NULL, &Timeout) == -1) + { + LOG("select(W) call failed in cSocketThread: \"%s\"", cSocket::GetLastErrorString().c_str()); + continue; + } + + WriteToSockets(&fdWrite); + + RemoveClosedSockets(); + } // while (!mShouldTerminate) +} + + + + + +void cSocketThreads::cSocketThread::PrepareSet(fd_set * a_Set, cSocket::xSocket & a_Highest) +{ + FD_ZERO(a_Set); + FD_SET(m_ControlSocket1.GetSocket(), a_Set); + + cCSLock Lock(m_Parent->m_CS); + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (!m_Slots[i].m_Socket->IsValid()) + { + continue; + } + cSocket::xSocket s = m_Slots[i].m_Socket->GetSocket(); + FD_SET(s, a_Set); + if (s > a_Highest) + { + a_Highest = s; + } + } // for i - m_Slots[] +} + + + + + +void cSocketThreads::cSocketThread::ReadFromSockets(fd_set * a_Read) +{ + // Read on available sockets: + + // Reset Control socket state: + if (FD_ISSET(m_ControlSocket1.GetSocket(), a_Read)) + { + char Dummy[128]; + m_ControlSocket1.Receive(Dummy, sizeof(Dummy), 0); + } + + // Read from clients: + cCSLock Lock(m_Parent->m_CS); + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (!FD_ISSET(m_Slots[i].m_Socket->GetSocket(), a_Read)) + { + continue; + } + char Buffer[1024]; + int Received = m_Slots[i].m_Socket->Receive(Buffer, ARRAYCOUNT(Buffer), 0); + if (Received == 0) + { + // The socket has been closed by the remote party, close our socket and let it be removed after we process all reading + m_Slots[i].m_Socket->CloseSocket(); + if (m_Slots[i].m_Client != NULL) + { + m_Slots[i].m_Client->SocketClosed(); + } + } + else if (Received > 0) + { + if (m_Slots[i].m_Client != NULL) + { + m_Slots[i].m_Client->DataReceived(Buffer, Received); + } + } + else + { + // The socket has encountered an error, close it and let it be removed after we process all reading + m_Slots[i].m_Socket->CloseSocket(); + if (m_Slots[i].m_Client != NULL) + { + m_Slots[i].m_Client->SocketClosed(); + } + } + } // for i - m_Slots[] +} + + + + + +void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) +{ + // Write to available client sockets: + cCSLock Lock(m_Parent->m_CS); + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (!FD_ISSET(m_Slots[i].m_Socket->GetSocket(), a_Write)) + { + continue; + } + if (m_Slots[i].m_Outgoing.empty()) + { + // Request another chunk of outgoing data: + if (m_Slots[i].m_Client != NULL) + { + m_Slots[i].m_Client->GetOutgoingData(m_Slots[i].m_Outgoing); + } + if (m_Slots[i].m_Outgoing.empty()) + { + // Nothing ready + if ((m_Slots[i].m_Client == NULL) && m_Slots[i].m_ShouldClose) + { + // Socket was queued for closing and there's no more data to send, close it now: + m_Slots[i].m_Socket->CloseSocket(); + m_Slots[i] = m_Slots[--m_NumSlots]; + } + continue; + } + } // if (outgoing data is empty) + + int Sent = m_Slots[i].m_Socket->Send(m_Slots[i].m_Outgoing.data(), m_Slots[i].m_Outgoing.size()); + if (Sent < 0) + { + int Err = cSocket::GetLastError(); + LOGWARNING("Error %d while writing to client \"%s\", disconnecting. \"%s\"", Err, m_Slots[i].m_Socket->GetIPString().c_str(), cSocket::GetErrorString(Err).c_str()); + m_Slots[i].m_Socket->CloseSocket(); + if (m_Slots[i].m_Client != NULL) + { + m_Slots[i].m_Client->SocketClosed(); + } + return; + } + m_Slots[i].m_Outgoing.erase(0, Sent); + + // _X: If there's data left, it means the client is not reading fast enough, the server would unnecessarily spin in the main loop with zero actions taken; so signalling is disabled + // This means that if there's data left, it will be sent only when there's incoming data or someone queues another packet (for any socket handled by this thread) + /* + // If there's any data left, signalize the Control socket: + if (!m_Slots[i].m_Outgoing.empty()) + { + ASSERT(m_ControlSocket2.IsValid()); + m_ControlSocket2.Send("q", 1); + } + */ + } // for i - m_Slots[i] +} + + + + + +void cSocketThreads::cSocketThread::RemoveClosedSockets(void) +{ + // Removes sockets that have closed from m_Slots[] + + cCSLock Lock(m_Parent->m_CS); + for (int i = m_NumSlots - 1; i >= 0; --i) + { + if (m_Slots[i].m_Socket->IsValid()) + { + continue; + } + m_Slots[i] = m_Slots[--m_NumSlots]; + } // for i - m_Slots[] +} + + + + diff --git a/source/cSocketThreads.h b/source/cSocketThreads.h index a8174a115..b13ecf02d 100644 --- a/source/cSocketThreads.h +++ b/source/cSocketThreads.h @@ -1,174 +1,174 @@ -
-// cSocketThreads.h
-
-// Interfaces to the cSocketThreads class representing the heart of MCS's client networking.
-// This object takes care of network communication, groups sockets into threads and uses as little threads as possible for full read / write support
-// For more detail, see http://forum.mc-server.org/showthread.php?tid=327
-
-/*
-Additional details:
-When a client is terminating a connection:
-- they call the StopReading() method to disable callbacks for the incoming data
-- they call the Write() method to queue any outstanding outgoing data
-- they call the QueueClose() method to queue the socket to close after outgoing data has been sent.
-When a socket slot is marked as having no callback, it is kept alive until its outgoing data queue is empty and its m_ShouldClose flag is set.
-This means that the socket can be written to several times before finally closing it via QueueClose()
-*/
-
-
-
-
-
-/// How many clients should one thread handle? (must be less than FD_SETSIZE - 1 for your platform)
-#define MAX_SLOTS 63
-
-
-
-
-
-#pragma once
-#ifndef CSOCKETTHREADS_H_INCLUDED
-#define CSOCKETTHREADS_H_INCLUDED
-
-#include "packets/cPacket.h"
-#include "cIsThread.h"
-
-
-
-
-// Check MAX_SLOTS:
-#if MAX_SLOTS >= FD_SETSIZE
- #error "MAX_SLOTS must be less than FD_SETSIZE - 1 for your platform! (otherwise select() won't work)"
-#endif
-
-
-
-
-
-// fwd:
-class cSocket;
-class cClientHandle;
-
-
-
-
-
-class cSocketThreads
-{
-public:
-
- // Clients of cSocketThreads must implement this interface to be able to communicate
- class cCallback
- {
- public:
- /// Called when data is received from the remote party
- virtual void DataReceived(const char * a_Data, int a_Size) = 0;
-
- /// Called when data can be sent to remote party; the function is supposed to append outgoing data to a_Data
- virtual void GetOutgoingData(AString & a_Data) = 0;
-
- /// Called when the socket has been closed for any reason
- virtual void SocketClosed(void) = 0;
- } ;
-
-
- cSocketThreads(void);
- ~cSocketThreads();
-
- /// Add a (socket, client) pair for processing, data from a_Socket is to be sent to a_Client; returns true if successful
- bool AddClient(cSocket * a_Socket, cCallback * a_Client);
-
- /// Remove the socket (and associated client) from processing
- void RemoveClient(const cSocket * a_Socket);
-
- /// Remove the associated socket and the client from processing
- void RemoveClient(const cCallback * a_Client);
-
- /// Notify the thread responsible for a_Client that the client has something to write
- void NotifyWrite(const cCallback * a_Client);
-
- /// Puts a_Data into outgoing data queue for a_Socket
- void Write(const cSocket * a_Socket, const AString & a_Data);
-
- /// Stops reading from the socket - when this call returns, no more calls to the callbacks are made
- void StopReading(const cCallback * a_Client);
-
- /// Queues the socket for closing, as soon as its outgoing data is sent
- void QueueClose(const cSocket * a_Socket);
-
-private:
-
- class cSocketThread :
- public cIsThread
- {
- typedef cIsThread super;
-
- public:
-
- cSocketThread(cSocketThreads * a_Parent);
- ~cSocketThread();
-
- // All these methods assume parent's m_CS is locked
- bool HasEmptySlot(void) const {return m_NumSlots < MAX_SLOTS; }
- bool IsEmpty (void) const {return m_NumSlots == 0; }
-
- void AddClient (cSocket * a_Socket, cCallback * a_Client);
- bool RemoveClient(const cCallback * a_Client); // Returns true if removed, false if not found
- bool RemoveSocket(const cSocket * a_Socket); // Returns true if removed, false if not found
- bool HasClient (const cCallback * a_Client) const;
- bool HasSocket (const cSocket * a_Socket) const;
- bool NotifyWrite (const cCallback * a_Client); // Returns true if client handled by this thread
- bool Write (const cSocket * a_Socket, const AString & a_Data); // Returns true if socket handled by this thread
- bool StopReading (const cCallback * a_Client); // Returns true if client handled by this thread
- bool QueueClose (const cSocket * a_Socket); // Returns true if socket handled by this thread
-
- bool Start(void); // Hide the cIsThread's Start method, we need to provide our own startup to create the control socket
-
- bool IsValid(void) const {return m_ControlSocket2.IsValid(); } // If the Control socket dies, the thread is not valid anymore
-
- private:
-
- cSocketThreads * m_Parent;
-
- // Two ends of the control socket, the first is select()-ed, the second is written to for notifications
- cSocket m_ControlSocket1;
- cSocket m_ControlSocket2;
-
- // Socket-client-packetqueues triplets.
- // Manipulation with these assumes that the parent's m_CS is locked
- struct sSlot
- {
- cSocket * m_Socket;
- cCallback * m_Client;
- AString m_Outgoing; // If sending writes only partial data, the rest is stored here for another send
- bool m_ShouldClose; // If true, the socket is to be closed after sending all outgoing data
- } ;
- sSlot m_Slots[MAX_SLOTS];
- int m_NumSlots; // Number of slots actually used
-
- virtual void Execute(void) override;
-
- void AddOrUpdatePacket(int a_Slot, cPacket * a_Packet); // Adds the packet to the specified slot, or updates an existing packet in that queue (EntityMoveLook filtering)
-
- void PrepareSet (fd_set * a_Set, cSocket::xSocket & a_Highest); // Puts all sockets into the set, along with m_ControlSocket1
- void ReadFromSockets(fd_set * a_Read); // Reads from sockets indicated in a_Read
- void WriteToSockets (fd_set * a_Write); // Writes to sockets indicated in a_Write
- void RemoveClosedSockets(void); // Removes sockets that have closed from m_Slots[]
- } ;
-
- typedef std::list<cSocketThread *> cSocketThreadList;
-
-
- cCriticalSection m_CS;
- cSocketThreadList m_Threads;
-} ;
-
-
-
-
-
-#endif // CSOCKETTHREADS_H_INCLUDED
-
-
-
-
+ +// cSocketThreads.h + +// Interfaces to the cSocketThreads class representing the heart of MCS's client networking. +// This object takes care of network communication, groups sockets into threads and uses as little threads as possible for full read / write support +// For more detail, see http://forum.mc-server.org/showthread.php?tid=327 + +/* +Additional details: +When a client is terminating a connection: +- they call the StopReading() method to disable callbacks for the incoming data +- they call the Write() method to queue any outstanding outgoing data +- they call the QueueClose() method to queue the socket to close after outgoing data has been sent. +When a socket slot is marked as having no callback, it is kept alive until its outgoing data queue is empty and its m_ShouldClose flag is set. +This means that the socket can be written to several times before finally closing it via QueueClose() +*/ + + + + + +/// How many clients should one thread handle? (must be less than FD_SETSIZE - 1 for your platform) +#define MAX_SLOTS 63 + + + + + +#pragma once +#ifndef CSOCKETTHREADS_H_INCLUDED +#define CSOCKETTHREADS_H_INCLUDED + +#include "packets/cPacket.h" +#include "cIsThread.h" + + + + +// Check MAX_SLOTS: +#if MAX_SLOTS >= FD_SETSIZE + #error "MAX_SLOTS must be less than FD_SETSIZE - 1 for your platform! (otherwise select() won't work)" +#endif + + + + + +// fwd: +class cSocket; +class cClientHandle; + + + + + +class cSocketThreads +{ +public: + + // Clients of cSocketThreads must implement this interface to be able to communicate + class cCallback + { + public: + /// Called when data is received from the remote party + virtual void DataReceived(const char * a_Data, int a_Size) = 0; + + /// Called when data can be sent to remote party; the function is supposed to append outgoing data to a_Data + virtual void GetOutgoingData(AString & a_Data) = 0; + + /// Called when the socket has been closed for any reason + virtual void SocketClosed(void) = 0; + } ; + + + cSocketThreads(void); + ~cSocketThreads(); + + /// Add a (socket, client) pair for processing, data from a_Socket is to be sent to a_Client; returns true if successful + bool AddClient(cSocket * a_Socket, cCallback * a_Client); + + /// Remove the socket (and associated client) from processing + void RemoveClient(const cSocket * a_Socket); + + /// Remove the associated socket and the client from processing + void RemoveClient(const cCallback * a_Client); + + /// Notify the thread responsible for a_Client that the client has something to write + void NotifyWrite(const cCallback * a_Client); + + /// Puts a_Data into outgoing data queue for a_Socket + void Write(const cSocket * a_Socket, const AString & a_Data); + + /// Stops reading from the socket - when this call returns, no more calls to the callbacks are made + void StopReading(const cCallback * a_Client); + + /// Queues the socket for closing, as soon as its outgoing data is sent + void QueueClose(const cSocket * a_Socket); + +private: + + class cSocketThread : + public cIsThread + { + typedef cIsThread super; + + public: + + cSocketThread(cSocketThreads * a_Parent); + ~cSocketThread(); + + // All these methods assume parent's m_CS is locked + bool HasEmptySlot(void) const {return m_NumSlots < MAX_SLOTS; } + bool IsEmpty (void) const {return m_NumSlots == 0; } + + void AddClient (cSocket * a_Socket, cCallback * a_Client); + bool RemoveClient(const cCallback * a_Client); // Returns true if removed, false if not found + bool RemoveSocket(const cSocket * a_Socket); // Returns true if removed, false if not found + bool HasClient (const cCallback * a_Client) const; + bool HasSocket (const cSocket * a_Socket) const; + bool NotifyWrite (const cCallback * a_Client); // Returns true if client handled by this thread + bool Write (const cSocket * a_Socket, const AString & a_Data); // Returns true if socket handled by this thread + bool StopReading (const cCallback * a_Client); // Returns true if client handled by this thread + bool QueueClose (const cSocket * a_Socket); // Returns true if socket handled by this thread + + bool Start(void); // Hide the cIsThread's Start method, we need to provide our own startup to create the control socket + + bool IsValid(void) const {return m_ControlSocket2.IsValid(); } // If the Control socket dies, the thread is not valid anymore + + private: + + cSocketThreads * m_Parent; + + // Two ends of the control socket, the first is select()-ed, the second is written to for notifications + cSocket m_ControlSocket1; + cSocket m_ControlSocket2; + + // Socket-client-packetqueues triplets. + // Manipulation with these assumes that the parent's m_CS is locked + struct sSlot + { + cSocket * m_Socket; + cCallback * m_Client; + AString m_Outgoing; // If sending writes only partial data, the rest is stored here for another send + bool m_ShouldClose; // If true, the socket is to be closed after sending all outgoing data + } ; + sSlot m_Slots[MAX_SLOTS]; + int m_NumSlots; // Number of slots actually used + + virtual void Execute(void) override; + + void AddOrUpdatePacket(int a_Slot, cPacket * a_Packet); // Adds the packet to the specified slot, or updates an existing packet in that queue (EntityMoveLook filtering) + + void PrepareSet (fd_set * a_Set, cSocket::xSocket & a_Highest); // Puts all sockets into the set, along with m_ControlSocket1 + void ReadFromSockets(fd_set * a_Read); // Reads from sockets indicated in a_Read + void WriteToSockets (fd_set * a_Write); // Writes to sockets indicated in a_Write + void RemoveClosedSockets(void); // Removes sockets that have closed from m_Slots[] + } ; + + typedef std::list<cSocketThread *> cSocketThreadList; + + + cCriticalSection m_CS; + cSocketThreadList m_Threads; +} ; + + + + + +#endif // CSOCKETTHREADS_H_INCLUDED + + + + diff --git a/source/cSpider.cpp b/source/cSpider.cpp index 47f4e2750..516a941d4 100644 --- a/source/cSpider.cpp +++ b/source/cSpider.cpp @@ -1,50 +1,50 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cSpider.h"
-
-
-
-
-
-cSpider::cSpider()
-{
- m_MobType = 52;
- GetMonsterConfig("Spider");
-}
-
-
-
-
-
-cSpider::~cSpider()
-{
-}
-
-
-
-
-
-bool cSpider::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cSpider" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
-
-
-
-
-
-void cSpider::KilledBy( cEntity* a_Killer )
-{
- cItems Drops;
- AddRandomDropItem(Drops, 0, 2, E_ITEM_STRING);
- AddRandomDropItem(Drops, 0, 1, E_ITEM_SPIDER_EYE);
- m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
-
- cMonster::KilledBy( a_Killer );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSpider.h" + + + + + +cSpider::cSpider() +{ + m_MobType = 52; + GetMonsterConfig("Spider"); +} + + + + + +cSpider::~cSpider() +{ +} + + + + + +bool cSpider::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cSpider" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cSpider::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_STRING); + AddRandomDropItem(Drops, 0, 1, E_ITEM_SPIDER_EYE); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cSpider.h b/source/cSpider.h index 7ffc818e4..ea7d4ba4f 100644 --- a/source/cSpider.h +++ b/source/cSpider.h @@ -1,14 +1,14 @@ -#pragma once
-
-#include "cAggressiveMonster.h"
-
-class cSpider : public cAggressiveMonster
-{
-public:
- cSpider();
- ~cSpider();
-
- virtual bool IsA( const char* a_EntityType );
-
- virtual void KilledBy( cEntity* a_Killer );
-};
+#pragma once + +#include "cAggressiveMonster.h" + +class cSpider : public cAggressiveMonster +{ +public: + cSpider(); + ~cSpider(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/cSquid.cpp b/source/cSquid.cpp index 52c0cbf30..735df1be0 100644 --- a/source/cSquid.cpp +++ b/source/cSquid.cpp @@ -1,60 +1,60 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cSquid.h"
-#include "Vector3d.h"
-
-
-
-
-
-cSquid::cSquid()
-{
- m_MobType = 94;
- GetMonsterConfig("Squid");
- m_NoWater = 0.f;
-}
-
-cSquid::~cSquid()
-{
-
-}
-
-bool cSquid::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cSquid" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
-
-
-
-
-
-void cSquid::KilledBy( cEntity* a_Killer )
-{
- // Drops 0-3 Ink Sacs
- cItems Drops;
- AddRandomDropItem(Drops, 0, 3, E_ITEM_DYE, E_META_DYE_BLACK);
- m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
-
- cMonster::KilledBy( a_Killer );
-}
-
-
-
-
-
-void cSquid::Tick(float a_Dt)
-{
- cPassiveMonster::Tick(a_Dt);
-
- Vector3d Pos = GetPosition();
-
-
- //TODO Not a real behavior, but cool :D
- if(!IsBlockWater(GetWorld()->GetBlock((int) Pos.x, (int) Pos.y, (int) Pos.z)) && GetMetaData() != BURNING)
- {
- SetMetaData(BURNING);
- }
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSquid.h" +#include "Vector3d.h" + + + + + +cSquid::cSquid() +{ + m_MobType = 94; + GetMonsterConfig("Squid"); + m_NoWater = 0.f; +} + +cSquid::~cSquid() +{ + +} + +bool cSquid::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cSquid" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cSquid::KilledBy( cEntity* a_Killer ) +{ + // Drops 0-3 Ink Sacs + cItems Drops; + AddRandomDropItem(Drops, 0, 3, E_ITEM_DYE, E_META_DYE_BLACK); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + + +void cSquid::Tick(float a_Dt) +{ + cPassiveMonster::Tick(a_Dt); + + Vector3d Pos = GetPosition(); + + + //TODO Not a real behavior, but cool :D + if(!IsBlockWater(GetWorld()->GetBlock((int) Pos.x, (int) Pos.y, (int) Pos.z)) && GetMetaData() != BURNING) + { + SetMetaData(BURNING); + } + }
\ No newline at end of file diff --git a/source/cSquid.h b/source/cSquid.h index 069172efd..93b82d0eb 100644 --- a/source/cSquid.h +++ b/source/cSquid.h @@ -1,18 +1,18 @@ -#pragma once
-
-#include "cPassiveMonster.h"
-
-class cSquid : public cPassiveMonster
-{
-public:
- cSquid();
- ~cSquid();
-
- virtual void Tick(float a_Dt);
-
- virtual bool IsA( const char* a_EntityType );
- virtual void KilledBy( cEntity* a_Killer );
-
-protected:
- float m_NoWater;
-};
+#pragma once + +#include "cPassiveMonster.h" + +class cSquid : public cPassiveMonster +{ +public: + cSquid(); + ~cSquid(); + + virtual void Tick(float a_Dt); + + virtual bool IsA( const char* a_EntityType ); + virtual void KilledBy( cEntity* a_Killer ); + +protected: + float m_NoWater; +}; diff --git a/source/cStairs.h b/source/cStairs.h index 01fe7017a..d796dc56d 100644 --- a/source/cStairs.h +++ b/source/cStairs.h @@ -1,28 +1,28 @@ -#pragma once
-
-class cStairs //tolua_export
-{ //tolua_export
-public:
- static char RotationToMetaData( float a_Rotation, int a_Direction ) //tolua_export
- { //tolua_export
- a_Rotation += 90 + 45; // So its not aligned with axis
- int result = 0x0;
- if( a_Direction == 0)
- {
-
- result = 0x4;
- }
-
- if( a_Rotation > 360.f ) a_Rotation -= 360.f;
- if( a_Rotation >= 0.f && a_Rotation < 90.f )
- return result;
- else if( a_Rotation >= 180 && a_Rotation < 270 )
- result += 0x1;
- else if( a_Rotation >= 90 && a_Rotation < 180 )
- result += 0x2;
- else
- result += 0x3;
-
- return result;
- } //tolua_export
-}; //tolua_export
+#pragma once + +class cStairs //tolua_export +{ //tolua_export +public: + static char RotationToMetaData( float a_Rotation, int a_Direction ) //tolua_export + { //tolua_export + a_Rotation += 90 + 45; // So its not aligned with axis + int result = 0x0; + if( a_Direction == 0) + { + + result = 0x4; + } + + if( a_Rotation > 360.f ) a_Rotation -= 360.f; + if( a_Rotation >= 0.f && a_Rotation < 90.f ) + return result; + else if( a_Rotation >= 180 && a_Rotation < 270 ) + result += 0x1; + else if( a_Rotation >= 90 && a_Rotation < 180 ) + result += 0x2; + else + result += 0x3; + + return result; + } //tolua_export +}; //tolua_export diff --git a/source/cStep.h b/source/cStep.h index 122a09191..9fe0131ed 100644 --- a/source/cStep.h +++ b/source/cStep.h @@ -1,15 +1,15 @@ -#pragma once
-
-class cStep //tolua_export
-{ //tolua_export
-public:
- static char DirectionToMetaData( int a_Direction ) //tolua_export
- { //tolua_export
- int result = 0x0;
- if( a_Direction == 0)
- {
- result = 0x8;
- }
- return result;
- } //tolua_export
-}; //tolua_export
+#pragma once + +class cStep //tolua_export +{ //tolua_export +public: + static char DirectionToMetaData( int a_Direction ) //tolua_export + { //tolua_export + int result = 0x0; + if( a_Direction == 0) + { + result = 0x8; + } + return result; + } //tolua_export +}; //tolua_export diff --git a/source/cStringMap.cpp b/source/cStringMap.cpp index 7907efc34..26b9cf5fe 100644 --- a/source/cStringMap.cpp +++ b/source/cStringMap.cpp @@ -1,23 +1,23 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cStringMap.h"
-
-
-
-
-
-unsigned int cStringMap::size() const
-{
- return m_StringMap.size();
-}
-
-void cStringMap::clear()
-{
- m_StringMap.clear();
-}
-
-std::string & cStringMap::get( const std::string & index )
-{
- return m_StringMap[index];
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cStringMap.h" + + + + + +unsigned int cStringMap::size() const +{ + return m_StringMap.size(); +} + +void cStringMap::clear() +{ + m_StringMap.clear(); +} + +std::string & cStringMap::get( const std::string & index ) +{ + return m_StringMap[index]; }
\ No newline at end of file diff --git a/source/cStringMap.h b/source/cStringMap.h index e6b61c171..1cf20048d 100644 --- a/source/cStringMap.h +++ b/source/cStringMap.h @@ -1,29 +1,29 @@ -
-// A std::map<string, string> interface for Lua
-
-#pragma once
-
-#include "tolua++.h"
-
-
-
-
-
-class cStringMap // tolua_export
-{ // tolua_export
-public: // tolua_export
- cStringMap(std::map< std::string, std::string > a_StringMap) : m_StringMap( a_StringMap ) {}
- void clear(); // tolua_export
-
- unsigned int size() const; // tolua_export
-
- std::string & get( const std::string & index ); //tolua_export
-
- std::map< std::string, std::string >& GetStringMap() { return m_StringMap; }
-private:
- std::map< std::string, std::string > m_StringMap;
-}; // tolua_export
-
-
-
-
+ +// A std::map<string, string> interface for Lua + +#pragma once + +#include "tolua++.h" + + + + + +class cStringMap // tolua_export +{ // tolua_export +public: // tolua_export + cStringMap(std::map< std::string, std::string > a_StringMap) : m_StringMap( a_StringMap ) {} + void clear(); // tolua_export + + unsigned int size() const; // tolua_export + + std::string & get( const std::string & index ); //tolua_export + + std::map< std::string, std::string >& GetStringMap() { return m_StringMap; } +private: + std::map< std::string, std::string > m_StringMap; +}; // tolua_export + + + + diff --git a/source/cSurvivalInventory.cpp b/source/cSurvivalInventory.cpp index 4a573572d..5ed91cf70 100644 --- a/source/cSurvivalInventory.cpp +++ b/source/cSurvivalInventory.cpp @@ -1,95 +1,95 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cSurvivalInventory.h"
-#include "cPlayer.h"
-#include "cClientHandle.h"
-#include "cWindow.h"
-#include "cItem.h"
-#include "CraftingRecipes.h"
-#include "cRoot.h"
-#include "packets/cPacket_WindowClick.h"
-
-
-
-
-
-cSurvivalInventory::~cSurvivalInventory()
-{
-
-}
-
-cSurvivalInventory::cSurvivalInventory(cPlayer* a_Owner)
- : cInventory(a_Owner)
-{
-
-}
-
-void cSurvivalInventory::Clicked( cPacket* a_ClickPacket )
-{
- cPacket_WindowClick *Packet = reinterpret_cast<cPacket_WindowClick *>(a_ClickPacket);
- bool bDontCook = false;
- if( GetWindow() )
- {
- // Override for craft result slot
- if( Packet->m_SlotNum == (short)c_CraftOffset )
- {
- LOG("In craft slot: %i x %i !!", m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemCount );
- cItem* DraggingItem = GetWindow()->GetDraggingItem();
- if( DraggingItem->IsEmpty() )
- {
- *DraggingItem = m_Slots[c_CraftOffset];
- m_Slots[c_CraftOffset].Empty();
- }
- else if( DraggingItem->Equals( m_Slots[c_CraftOffset] ) )
- {
- if( DraggingItem->m_ItemCount + m_Slots[c_CraftOffset].m_ItemCount <= 64 )
- {
- DraggingItem->m_ItemCount += m_Slots[c_CraftOffset].m_ItemCount;
- m_Slots[0].Empty();
- }
- else
- {
- bDontCook = true;
- }
- }
- else
- {
- bDontCook = true;
- }
- LOG("Dragging Dish %i", DraggingItem->m_ItemCount );
- }
- else
- {
- GetWindow()->Clicked( Packet, *m_Owner );
- }
- }
- else
- {
- LOG("No Inventory window! WTF");
- }
-
- if ((Packet->m_SlotNum >= (short)c_CraftOffset) && (Packet->m_SlotNum < (short)(c_CraftOffset + c_CraftSlots + 1)))
- {
- cCraftingGrid Grid(m_Slots + c_CraftOffset + 1, 2, 2);
- cCraftingRecipe Recipe(Grid);
-
- cRoot::Get()->GetCraftingRecipes()->GetRecipe(m_Owner, Grid, Recipe);
-
- if ((Packet->m_SlotNum == 0) && !bDontCook)
- {
- // Consume the items from the crafting grid:
- Recipe.ConsumeIngredients(Grid);
-
- // Propagate grid back to m_Slots:
- Grid.CopyToItems(m_Slots + c_CraftOffset + 1);
-
- // Get the recipe for the new grid contents:
- cRoot::Get()->GetCraftingRecipes()->GetRecipe(m_Owner, Grid, Recipe);
- }
- m_Slots[c_CraftOffset] = Recipe.GetResult();
- LOGD("%s cooked: %i x %i !!", m_Owner->GetName().c_str(), m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemCount );
- SendWholeInventory( m_Owner->GetClientHandle() );
- }
- SendSlot( 0 );
-}
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cSurvivalInventory.h" +#include "cPlayer.h" +#include "cClientHandle.h" +#include "cWindow.h" +#include "cItem.h" +#include "CraftingRecipes.h" +#include "cRoot.h" +#include "packets/cPacket_WindowClick.h" + + + + + +cSurvivalInventory::~cSurvivalInventory() +{ + +} + +cSurvivalInventory::cSurvivalInventory(cPlayer* a_Owner) + : cInventory(a_Owner) +{ + +} + +void cSurvivalInventory::Clicked( cPacket* a_ClickPacket ) +{ + cPacket_WindowClick *Packet = reinterpret_cast<cPacket_WindowClick *>(a_ClickPacket); + bool bDontCook = false; + if( GetWindow() ) + { + // Override for craft result slot + if( Packet->m_SlotNum == (short)c_CraftOffset ) + { + LOG("In craft slot: %i x %i !!", m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemCount ); + cItem* DraggingItem = GetWindow()->GetDraggingItem(); + if( DraggingItem->IsEmpty() ) + { + *DraggingItem = m_Slots[c_CraftOffset]; + m_Slots[c_CraftOffset].Empty(); + } + else if( DraggingItem->Equals( m_Slots[c_CraftOffset] ) ) + { + if( DraggingItem->m_ItemCount + m_Slots[c_CraftOffset].m_ItemCount <= 64 ) + { + DraggingItem->m_ItemCount += m_Slots[c_CraftOffset].m_ItemCount; + m_Slots[0].Empty(); + } + else + { + bDontCook = true; + } + } + else + { + bDontCook = true; + } + LOG("Dragging Dish %i", DraggingItem->m_ItemCount ); + } + else + { + GetWindow()->Clicked( Packet, *m_Owner ); + } + } + else + { + LOG("No Inventory window! WTF"); + } + + if ((Packet->m_SlotNum >= (short)c_CraftOffset) && (Packet->m_SlotNum < (short)(c_CraftOffset + c_CraftSlots + 1))) + { + cCraftingGrid Grid(m_Slots + c_CraftOffset + 1, 2, 2); + cCraftingRecipe Recipe(Grid); + + cRoot::Get()->GetCraftingRecipes()->GetRecipe(m_Owner, Grid, Recipe); + + if ((Packet->m_SlotNum == 0) && !bDontCook) + { + // Consume the items from the crafting grid: + Recipe.ConsumeIngredients(Grid); + + // Propagate grid back to m_Slots: + Grid.CopyToItems(m_Slots + c_CraftOffset + 1); + + // Get the recipe for the new grid contents: + cRoot::Get()->GetCraftingRecipes()->GetRecipe(m_Owner, Grid, Recipe); + } + m_Slots[c_CraftOffset] = Recipe.GetResult(); + LOGD("%s cooked: %i x %i !!", m_Owner->GetName().c_str(), m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemCount ); + SendWholeInventory( m_Owner->GetClientHandle() ); + } + SendSlot( 0 ); +} diff --git a/source/cSurvivalInventory.h b/source/cSurvivalInventory.h index 6c527f1d2..2061de2b0 100644 --- a/source/cSurvivalInventory.h +++ b/source/cSurvivalInventory.h @@ -1,22 +1,22 @@ -
-#pragma once
-
-#include "cInventory.h"
-
-
-
-
-
-class cSurvivalInventory //tolua_export
- : public cInventory
-{ //tolua_export
-public:
- cSurvivalInventory(cPlayer* a_Owner);
- ~cSurvivalInventory();
-
- virtual void Clicked( cPacket* a_ClickPacket );
-}; //tolua_export
-
-
-
-
+ +#pragma once + +#include "cInventory.h" + + + + + +class cSurvivalInventory //tolua_export + : public cInventory +{ //tolua_export +public: + cSurvivalInventory(cPlayer* a_Owner); + ~cSurvivalInventory(); + + virtual void Clicked( cPacket* a_ClickPacket ); +}; //tolua_export + + + + diff --git a/source/cTCPLink.cpp b/source/cTCPLink.cpp index 0ade65d55..22151b32a 100644 --- a/source/cTCPLink.cpp +++ b/source/cTCPLink.cpp @@ -1,129 +1,129 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cTCPLink.h"
-#include "cSocket.h"
-
-
-
-
-
-#ifdef _WIN32
- #define MSG_NOSIGNAL (0)
-#endif
-#ifdef __MACH__
- #define MSG_NOSIGNAL (0)
-#endif
-
-
-
-
-
-cTCPLink::cTCPLink()
- : m_Socket( 0 )
- , m_StopEvent( new cEvent() )
-{
-}
-
-cTCPLink::~cTCPLink()
-{
- if( m_Socket )
- {
- CloseSocket();
- m_StopEvent->Wait();
- }
- delete m_StopEvent;
-}
-
-void cTCPLink::CloseSocket()
-{
- if( m_Socket )
- {
- m_Socket.CloseSocket();
- m_Socket = 0;
- }
-}
-
-bool cTCPLink::Connect( const AString & a_Address, unsigned int a_Port )
-{
- if( m_Socket )
- {
- LOGWARN("WARNING: cTCPLink Connect() called while still connected. ALWAYS disconnect before re-connecting!");
- }
-
- m_Socket = cSocket::CreateSocket();
- if( !m_Socket.IsValid() )
- {
- LOGERROR("cTCPLink: Failed to create socket");
- return false;
- }
-
- if (m_Socket.Connect(a_Address, a_Port) != 0)
- {
- LOGWARN("cTCPLink: Cannot connect to server \"%s\" (%s)", m_Socket.GetLastErrorString().c_str());
- m_Socket.CloseSocket();
- return false;
- }
-
- cThread( ReceiveThread, this );
-
- return true;
-}
-
-
-
-
-
-int cTCPLink::Send(const char * a_Data, unsigned int a_Size, int a_Flags /* = 0 */ )
-{
- (void)a_Flags;
- if (!m_Socket.IsValid())
- {
- LOGWARN("cTCPLink: Trying to send data without a valid connection!");
- return -1;
- }
- return m_Socket.Send(a_Data, a_Size);
-}
-
-
-
-
-
-int cTCPLink::SendMessage(const char * a_Message, int a_Flags /* = 0 */ )
-{
- (void)a_Flags;
- if (!m_Socket.IsValid())
- {
- LOGWARN("cTCPLink: Trying to send message without a valid connection!");
- return -1;
- }
- return m_Socket.Send(a_Message, strlen(a_Message));
-}
-
-
-
-
-
-void cTCPLink::ReceiveThread( void* a_Param)
-{
- cTCPLink* self = (cTCPLink*)a_Param;
- cSocket Socket = self->m_Socket;
- int Received = 0;
- do
- {
- char Data[256];
- Received = Socket.Receive(Data, sizeof(Data), 0);
- self->ReceivedData( Data, ((Received > 0) ? Received : -1) );
- } while ( Received > 0 );
-
- LOGINFO("cTCPLink Disconnected (%i)", Received );
-
- if (Socket == self->m_Socket)
- {
- self->m_StopEvent->Set();
- }
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cTCPLink.h" +#include "cSocket.h" + + + + + +#ifdef _WIN32 + #define MSG_NOSIGNAL (0) +#endif +#ifdef __MACH__ + #define MSG_NOSIGNAL (0) +#endif + + + + + +cTCPLink::cTCPLink() + : m_Socket( 0 ) + , m_StopEvent( new cEvent() ) +{ +} + +cTCPLink::~cTCPLink() +{ + if( m_Socket ) + { + CloseSocket(); + m_StopEvent->Wait(); + } + delete m_StopEvent; +} + +void cTCPLink::CloseSocket() +{ + if( m_Socket ) + { + m_Socket.CloseSocket(); + m_Socket = 0; + } +} + +bool cTCPLink::Connect( const AString & a_Address, unsigned int a_Port ) +{ + if( m_Socket ) + { + LOGWARN("WARNING: cTCPLink Connect() called while still connected. ALWAYS disconnect before re-connecting!"); + } + + m_Socket = cSocket::CreateSocket(); + if( !m_Socket.IsValid() ) + { + LOGERROR("cTCPLink: Failed to create socket"); + return false; + } + + if (m_Socket.Connect(a_Address, a_Port) != 0) + { + LOGWARN("cTCPLink: Cannot connect to server \"%s\" (%s)", m_Socket.GetLastErrorString().c_str()); + m_Socket.CloseSocket(); + return false; + } + + cThread( ReceiveThread, this ); + + return true; +} + + + + + +int cTCPLink::Send(const char * a_Data, unsigned int a_Size, int a_Flags /* = 0 */ ) +{ + (void)a_Flags; + if (!m_Socket.IsValid()) + { + LOGWARN("cTCPLink: Trying to send data without a valid connection!"); + return -1; + } + return m_Socket.Send(a_Data, a_Size); +} + + + + + +int cTCPLink::SendMessage(const char * a_Message, int a_Flags /* = 0 */ ) +{ + (void)a_Flags; + if (!m_Socket.IsValid()) + { + LOGWARN("cTCPLink: Trying to send message without a valid connection!"); + return -1; + } + return m_Socket.Send(a_Message, strlen(a_Message)); +} + + + + + +void cTCPLink::ReceiveThread( void* a_Param) +{ + cTCPLink* self = (cTCPLink*)a_Param; + cSocket Socket = self->m_Socket; + int Received = 0; + do + { + char Data[256]; + Received = Socket.Receive(Data, sizeof(Data), 0); + self->ReceivedData( Data, ((Received > 0) ? Received : -1) ); + } while ( Received > 0 ); + + LOGINFO("cTCPLink Disconnected (%i)", Received ); + + if (Socket == self->m_Socket) + { + self->m_StopEvent->Set(); + } +} + + + + diff --git a/source/cTCPLink.h b/source/cTCPLink.h index ea38f9b7b..0bba84243 100644 --- a/source/cTCPLink.h +++ b/source/cTCPLink.h @@ -1,22 +1,22 @@ -#pragma once
-
-#include "cSocket.h"
-
-class cTCPLink //tolua_export
-{ //tolua_export
-public: //tolua_export
- cTCPLink(); //tolua_export
- ~cTCPLink(); //tolua_export
-
- bool Connect (const AString & a_Address, unsigned int a_Port ); //tolua_export
- int Send (const char * a_Data, unsigned int a_Size, int a_Flags = 0 ); //tolua_export
- int SendMessage(const char * a_Message, int a_Flags = 0 ); //tolua_export
- void CloseSocket(); //tolua_export
-protected: //tolua_export
- virtual void ReceivedData( char a_Data[256], int a_Size ) = 0; //tolua_export
-
- static void ReceiveThread( void* a_Param );
-
- cSocket m_Socket;
- cEvent* m_StopEvent;
-}; //tolua_export
+#pragma once + +#include "cSocket.h" + +class cTCPLink //tolua_export +{ //tolua_export +public: //tolua_export + cTCPLink(); //tolua_export + ~cTCPLink(); //tolua_export + + bool Connect (const AString & a_Address, unsigned int a_Port ); //tolua_export + int Send (const char * a_Data, unsigned int a_Size, int a_Flags = 0 ); //tolua_export + int SendMessage(const char * a_Message, int a_Flags = 0 ); //tolua_export + void CloseSocket(); //tolua_export +protected: //tolua_export + virtual void ReceivedData( char a_Data[256], int a_Size ) = 0; //tolua_export + + static void ReceiveThread( void* a_Param ); + + cSocket m_Socket; + cEvent* m_StopEvent; +}; //tolua_export diff --git a/source/cThread.cpp b/source/cThread.cpp index 3197fdcd6..f07a973b5 100644 --- a/source/cThread.cpp +++ b/source/cThread.cpp @@ -1,118 +1,118 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-
-
-
-
-// When in MSVC, the debugger provides "thread naming" by catching special exceptions. Interface here:
-#ifdef _MSC_VER
-//
-// Usage: SetThreadName (-1, "MainThread");
-//
-typedef struct tagTHREADNAME_INFO
-{
- DWORD dwType; // must be 0x1000
- LPCSTR szName; // pointer to name (in user addr space)
- DWORD dwThreadID; // thread ID (-1=caller thread)
- DWORD dwFlags; // reserved for future use, must be zero
-} THREADNAME_INFO;
-
-void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName)
-{
- THREADNAME_INFO info;
- info.dwType = 0x1000;
- info.szName = szThreadName;
- info.dwThreadID = dwThreadID;
- info.dwFlags = 0;
-
- __try
- {
- RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info );
- }
- __except(EXCEPTION_CONTINUE_EXECUTION)
- {
- }
-}
-#endif // _MSC_VER
-
-
-
-
-
-cThread::cThread( ThreadFunc a_ThreadFunction, void* a_Param, const char* a_ThreadName /* = 0 */ )
- : m_ThreadFunction( a_ThreadFunction )
- , m_Param( a_Param )
- , m_Event( new cEvent() )
- , m_StopEvent( 0 )
- , m_ThreadName( 0 )
-{
- if( a_ThreadName )
- {
- m_ThreadName = new char[ strlen(a_ThreadName)+1 ];
- strcpy(m_ThreadName, a_ThreadName);
- }
-}
-
-cThread::~cThread()
-{
- delete m_Event;
-
- if( m_StopEvent )
- {
- m_StopEvent->Wait();
- delete m_StopEvent;
- }
-
- delete [] m_ThreadName;
-}
-
-void cThread::Start( bool a_bWaitOnDelete /* = true */ )
-{
- if( a_bWaitOnDelete )
- m_StopEvent = new cEvent();
-
-#ifndef _WIN32
- pthread_t SndThread;
- if( pthread_create( &SndThread, NULL, MyThread, this) )
- LOGERROR("ERROR: Could not create thread!");
-#else
- DWORD ThreadID = 0;
- HANDLE hThread = CreateThread( 0 // security
- ,0 // stack size
- , (LPTHREAD_START_ROUTINE) MyThread // function name
- ,this // parameters
- ,0 // flags
- ,&ThreadID ); // thread id
- CloseHandle( hThread );
-
- if( m_ThreadName )
- {
- SetThreadName(ThreadID, m_ThreadName );
- }
-#endif
-
- // Wait until thread has actually been created
- m_Event->Wait();
-}
-
-#ifdef _WIN32
-unsigned long cThread::MyThread(void* a_Param )
-#else
-void *cThread::MyThread( void *a_Param )
-#endif
-{
- cThread* self = (cThread*)a_Param;
- cEvent* StopEvent = self->m_StopEvent;
-
- ThreadFunc* ThreadFunction = self->m_ThreadFunction;
- void* ThreadParam = self->m_Param;
-
- // Set event to let other thread know this thread has been created and it's safe to delete the cThread object
- self->m_Event->Set();
-
- ThreadFunction( ThreadParam );
-
- if( StopEvent ) StopEvent->Set();
- return 0;
-}
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + + + + + +// When in MSVC, the debugger provides "thread naming" by catching special exceptions. Interface here: +#ifdef _MSC_VER +// +// Usage: SetThreadName (-1, "MainThread"); +// +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; // must be 0x1000 + LPCSTR szName; // pointer to name (in user addr space) + DWORD dwThreadID; // thread ID (-1=caller thread) + DWORD dwFlags; // reserved for future use, must be zero +} THREADNAME_INFO; + +void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName) +{ + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = szThreadName; + info.dwThreadID = dwThreadID; + info.dwFlags = 0; + + __try + { + RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info ); + } + __except(EXCEPTION_CONTINUE_EXECUTION) + { + } +} +#endif // _MSC_VER + + + + + +cThread::cThread( ThreadFunc a_ThreadFunction, void* a_Param, const char* a_ThreadName /* = 0 */ ) + : m_ThreadFunction( a_ThreadFunction ) + , m_Param( a_Param ) + , m_Event( new cEvent() ) + , m_StopEvent( 0 ) + , m_ThreadName( 0 ) +{ + if( a_ThreadName ) + { + m_ThreadName = new char[ strlen(a_ThreadName)+1 ]; + strcpy(m_ThreadName, a_ThreadName); + } +} + +cThread::~cThread() +{ + delete m_Event; + + if( m_StopEvent ) + { + m_StopEvent->Wait(); + delete m_StopEvent; + } + + delete [] m_ThreadName; +} + +void cThread::Start( bool a_bWaitOnDelete /* = true */ ) +{ + if( a_bWaitOnDelete ) + m_StopEvent = new cEvent(); + +#ifndef _WIN32 + pthread_t SndThread; + if( pthread_create( &SndThread, NULL, MyThread, this) ) + LOGERROR("ERROR: Could not create thread!"); +#else + DWORD ThreadID = 0; + HANDLE hThread = CreateThread( 0 // security + ,0 // stack size + , (LPTHREAD_START_ROUTINE) MyThread // function name + ,this // parameters + ,0 // flags + ,&ThreadID ); // thread id + CloseHandle( hThread ); + + if( m_ThreadName ) + { + SetThreadName(ThreadID, m_ThreadName ); + } +#endif + + // Wait until thread has actually been created + m_Event->Wait(); +} + +#ifdef _WIN32 +unsigned long cThread::MyThread(void* a_Param ) +#else +void *cThread::MyThread( void *a_Param ) +#endif +{ + cThread* self = (cThread*)a_Param; + cEvent* StopEvent = self->m_StopEvent; + + ThreadFunc* ThreadFunction = self->m_ThreadFunction; + void* ThreadParam = self->m_Param; + + // Set event to let other thread know this thread has been created and it's safe to delete the cThread object + self->m_Event->Set(); + + ThreadFunction( ThreadParam ); + + if( StopEvent ) StopEvent->Set(); + return 0; +} diff --git a/source/cThread.h b/source/cThread.h index 4fb001e67..5707e4bac 100644 --- a/source/cThread.h +++ b/source/cThread.h @@ -1,26 +1,26 @@ -#pragma once
-
-class cThread
-{
-public:
- typedef void (ThreadFunc)(void*);
- cThread( ThreadFunc a_ThreadFunction, void* a_Param, const char* a_ThreadName = 0 );
- ~cThread();
-
- void Start( bool a_bWaitOnDelete = true );
- void WaitForThread();
-private:
- ThreadFunc* m_ThreadFunction;
-
-#ifdef _WIN32
- static unsigned long MyThread(void* a_Param );
-#else
- static void *MyThread( void *lpParam );
-#endif
-
- void* m_Param;
- cEvent* m_Event;
- cEvent* m_StopEvent;
-
- char* m_ThreadName;
+#pragma once + +class cThread +{ +public: + typedef void (ThreadFunc)(void*); + cThread( ThreadFunc a_ThreadFunction, void* a_Param, const char* a_ThreadName = 0 ); + ~cThread(); + + void Start( bool a_bWaitOnDelete = true ); + void WaitForThread(); +private: + ThreadFunc* m_ThreadFunction; + +#ifdef _WIN32 + static unsigned long MyThread(void* a_Param ); +#else + static void *MyThread( void *lpParam ); +#endif + + void* m_Param; + cEvent* m_Event; + cEvent* m_StopEvent; + + char* m_ThreadName; };
\ No newline at end of file diff --git a/source/cTimer.cpp b/source/cTimer.cpp index 8fa0c2715..a68ad2480 100644 --- a/source/cTimer.cpp +++ b/source/cTimer.cpp @@ -1,40 +1,40 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cTimer.h"
-
-
-
-
-
-
-cTimer::cTimer()
-#ifdef _WIN32
- : m_TicksPerSecond( new LARGE_INTEGER )
-#endif
-{
-#ifdef _WIN32
- QueryPerformanceFrequency( (LARGE_INTEGER*)m_TicksPerSecond );
-#endif
-}
-
-cTimer::~cTimer()
-{
-#ifdef _WIN32
- delete (LARGE_INTEGER*)m_TicksPerSecond;
-#endif
-}
-
-long long cTimer::GetNowTime()
-{
-#ifdef _WIN32
- LARGE_INTEGER now;
- QueryPerformanceCounter( &now );
- LARGE_INTEGER & tps = *((LARGE_INTEGER*)m_TicksPerSecond);
- return ((now.QuadPart*1000) / tps.QuadPart );
-#else
- struct timeval now;
- gettimeofday(&now, NULL);
- return (long long)(now.tv_sec*1000 + now.tv_usec/1000);
-#endif
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cTimer.h" + + + + + + +cTimer::cTimer() +#ifdef _WIN32 + : m_TicksPerSecond( new LARGE_INTEGER ) +#endif +{ +#ifdef _WIN32 + QueryPerformanceFrequency( (LARGE_INTEGER*)m_TicksPerSecond ); +#endif +} + +cTimer::~cTimer() +{ +#ifdef _WIN32 + delete (LARGE_INTEGER*)m_TicksPerSecond; +#endif +} + +long long cTimer::GetNowTime() +{ +#ifdef _WIN32 + LARGE_INTEGER now; + QueryPerformanceCounter( &now ); + LARGE_INTEGER & tps = *((LARGE_INTEGER*)m_TicksPerSecond); + return ((now.QuadPart*1000) / tps.QuadPart ); +#else + struct timeval now; + gettimeofday(&now, NULL); + return (long long)(now.tv_sec*1000 + now.tv_usec/1000); +#endif }
\ No newline at end of file diff --git a/source/cTimer.h b/source/cTimer.h index 52afda8bb..5969d0fc9 100644 --- a/source/cTimer.h +++ b/source/cTimer.h @@ -1,15 +1,15 @@ -#pragma once
-
-class cTimer
-{
-public:
- cTimer();
- ~cTimer();
-
- long long GetNowTime();
-private:
-
-#ifdef _WIN32
- void* m_TicksPerSecond; // LARGE_INTEGER*
-#endif
+#pragma once + +class cTimer +{ +public: + cTimer(); + ~cTimer(); + + long long GetNowTime(); +private: + +#ifdef _WIN32 + void* m_TicksPerSecond; // LARGE_INTEGER* +#endif };
\ No newline at end of file diff --git a/source/cTorch.h b/source/cTorch.h index 6bb2291b2..c45916dbf 100644 --- a/source/cTorch.h +++ b/source/cTorch.h @@ -1,94 +1,94 @@ -#pragma once
-
-#include "Vector3i.h"
-
-class cTorch //tolua_export
-{ //tolua_export
-public:
-
- static char DirectionToMetaData( char a_Direction ) //tolua_export
- { //tolua_export
- switch( a_Direction )
- {
- case 0x0:
- return 0x0;
- case 0x1:
- return 0x5; //standing on floor
- case 0x2:
- return 0x4; // south
- case 0x3:
- return 0x3; // north
- case 0x4:
- return 0x2; // west
- case 0x5:
- return 0x1; // east
- default:
- break;
- };
- return 0x0;
- } //tolua_export
-
- static char MetaDataToDirection( char a_MetaData ) //tolua_export
- { //tolua_export
- switch( a_MetaData )
- {
- case 0x0:
- return 0x0;
- case 0x1:
- return 0x5;
- case 0x2:
- return 0x4;
- case 0x3:
- return 0x3;
- case 0x4:
- return 0x2;
- case 0x5:
- return 0x1;
- default:
- break;
- };
- return 0x0;
- } //tolua_export
-
- static bool IsAttachedTo( const Vector3i & a_TorchPos, char a_TorchMeta, const Vector3i & a_BlockPos )
- {
- switch( a_TorchMeta )
- {
- case 0x0:
- case 0x5: // On floor
- if( (a_TorchPos - a_BlockPos).Equals( Vector3i(0, 1, 0 ) ) )
- {
- return true;
- }
- break;
- case 0x4: // South -Z
- if( (a_TorchPos - a_BlockPos).Equals( Vector3i(0, 0, -1 ) ) )
- {
- return true;
- }
- break;
- case 0x3: // North +Z
- if( (a_TorchPos - a_BlockPos).Equals( Vector3i(0, 0, 1 ) ) )
- {
- return true;
- }
- break;
- case 0x2: // West -X
- if( (a_TorchPos - a_BlockPos).Equals( Vector3i(-1, 0, 0 ) ) )
- {
- return true;
- }
- break;
- case 0x1: // East +X
- if( (a_TorchPos - a_BlockPos).Equals( Vector3i( 1, 0, 0 ) ) )
- {
- return true;
- }
- break;
- default:
- break;
- };
- return false;
- }
-
+#pragma once + +#include "Vector3i.h" + +class cTorch //tolua_export +{ //tolua_export +public: + + static char DirectionToMetaData( char a_Direction ) //tolua_export + { //tolua_export + switch( a_Direction ) + { + case 0x0: + return 0x0; + case 0x1: + return 0x5; //standing on floor + case 0x2: + return 0x4; // south + case 0x3: + return 0x3; // north + case 0x4: + return 0x2; // west + case 0x5: + return 0x1; // east + default: + break; + }; + return 0x0; + } //tolua_export + + static char MetaDataToDirection( char a_MetaData ) //tolua_export + { //tolua_export + switch( a_MetaData ) + { + case 0x0: + return 0x0; + case 0x1: + return 0x5; + case 0x2: + return 0x4; + case 0x3: + return 0x3; + case 0x4: + return 0x2; + case 0x5: + return 0x1; + default: + break; + }; + return 0x0; + } //tolua_export + + static bool IsAttachedTo( const Vector3i & a_TorchPos, char a_TorchMeta, const Vector3i & a_BlockPos ) + { + switch( a_TorchMeta ) + { + case 0x0: + case 0x5: // On floor + if( (a_TorchPos - a_BlockPos).Equals( Vector3i(0, 1, 0 ) ) ) + { + return true; + } + break; + case 0x4: // South -Z + if( (a_TorchPos - a_BlockPos).Equals( Vector3i(0, 0, -1 ) ) ) + { + return true; + } + break; + case 0x3: // North +Z + if( (a_TorchPos - a_BlockPos).Equals( Vector3i(0, 0, 1 ) ) ) + { + return true; + } + break; + case 0x2: // West -X + if( (a_TorchPos - a_BlockPos).Equals( Vector3i(-1, 0, 0 ) ) ) + { + return true; + } + break; + case 0x1: // East +X + if( (a_TorchPos - a_BlockPos).Equals( Vector3i( 1, 0, 0 ) ) ) + { + return true; + } + break; + default: + break; + }; + return false; + } + }; //tolua_export
\ No newline at end of file diff --git a/source/cTracer.cpp b/source/cTracer.cpp index 5cfc41b60..fba0f908c 100644 --- a/source/cTracer.cpp +++ b/source/cTracer.cpp @@ -1,350 +1,350 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cTracer.h"
-#include "cWorld.h"
-
-#include "Vector3f.h"
-#include "Vector3i.h"
-#include "Vector3d.h"
-
-#include "BlockID.h"
-#include "cEntity.h"
-
-#include "Defines.h"
-
-#ifndef _WIN32
- #include <stdlib.h> // abs()
-#endif
-
-cTracer::cTracer(cWorld* a_World)
- : m_World( a_World )
-{
- m_NormalTable[0].Set(-1, 0, 0);
- m_NormalTable[1].Set( 0, 0,-1);
- m_NormalTable[2].Set( 1, 0, 0);
- m_NormalTable[3].Set( 0, 0, 1);
- m_NormalTable[4].Set( 0, 1, 0);
- m_NormalTable[5].Set( 0,-1, 0);
-}
-
-cTracer::~cTracer()
-{
-}
-
-float cTracer::SigNum( float a_Num )
-{
- if (a_Num < 0.f) return -1.f;
- if (a_Num > 0.f) return 1.f;
- return 0.f;
-}
-
-void cTracer::SetValues( const Vector3f & a_Start, const Vector3f & a_Direction )
-{
- // calculate the direction of the ray (linear algebra)
- dir = a_Direction;
-
- // decide which direction to start walking in
- step.x = (int) SigNum(dir.x);
- step.y = (int) SigNum(dir.y);
- step.z = (int) SigNum(dir.z);
-
- // normalize the direction vector
- if( dir.SqrLength() > 0.f ) dir.Normalize();
-
- // how far we must move in the ray direction before
- // we encounter a new voxel in x-direction
- // same but y-direction
- if( dir.x != 0.f ) tDelta.x = 1/fabs(dir.x);
- else tDelta.x = 0;
- if( dir.y != 0.f ) tDelta.y = 1/fabs(dir.y);
- else tDelta.y = 0;
- if( dir.z != 0.f ) tDelta.z = 1/fabs(dir.z);
- else tDelta.z = 0;
-
- // start voxel coordinates
- // use your
- // transformer
- // function here
- pos.x = (int)floorf(a_Start.x);
- pos.y = (int)floorf(a_Start.y);
- pos.z = (int)floorf(a_Start.z);
-
- // calculate distance to first intersection in the voxel we start from
- if(dir.x < 0)
- {
- tMax.x = ((float)pos.x - a_Start.x) / dir.x;
- }
- else
- {
- tMax.x = (((float)pos.x + 1) - a_Start.x) / dir.x;
- }
-
- if(dir.y < 0)
- {
- tMax.y = ((float)pos.y - a_Start.y) / dir.y;
- }
- else
- {
- tMax.y = (((float)pos.y + 1) - a_Start.y) / dir.y;
- }
-
- if(dir.z < 0)
- {
- tMax.z = ((float)pos.z - a_Start.z) / dir.z;
- }
- else
- {
- tMax.z = (((float)pos.z + 1) - a_Start.z) / dir.z;
- }
-}
-
-int cTracer::Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int a_Distance)
-{
- SetValues( a_Start, a_Direction );
-
- const Vector3f End = a_Start + (dir * (float)a_Distance);
-
- // end voxel coordinates
- end1.x = (int)floorf(End.x);
- end1.y = (int)floorf(End.y);
- end1.z = (int)floorf(End.z);
-
- // check if first is occupied
- if( pos.Equals( end1 ) )
- {
- LOG("WARNING: cTracer: Start and end in same block");
- return 0;
- }
-
- bool reachedX = false, reachedY = false, reachedZ = false;
-
- int Iterations = 0;
- while ( Iterations < a_Distance )
- {
- Iterations++;
- if(tMax.x < tMax.y && tMax.x < tMax.z)
- {
- tMax.x += tDelta.x;
- pos.x += step.x;
- }
- else if(tMax.y < tMax.z)
- {
- tMax.y += tDelta.y;
- pos.y += step.y;
- }
- else
- {
- tMax.z += tDelta.z;
- pos.z += step.z;
- }
-
- if(step.x > 0.0f)
- {
- if(pos.x >= end1.x)
- {
- reachedX = true;
- }
- }
- else if(pos.x <= end1.x)
- {
- reachedX = true;
- }
-
- if(step.y > 0.0f)
- {
- if(pos.y >= end1.y)
- {
- reachedY = true;
- }
- }
- else if(pos.y <= end1.y)
- {
- reachedY = true;
- }
-
- if(step.z > 0.0f)
- {
- if(pos.z >= end1.z)
- {
- reachedZ = true;
- }
- }
- else if(pos.z <= end1.z)
- {
- reachedZ = true;
- }
-
- if (reachedX && reachedY && reachedZ)
- {
- return false;
- }
-
- char BlockID = m_World->GetBlock( pos.x, pos.y, pos.z );
- //No collision with water ;)
- if ( BlockID != E_BLOCK_AIR || IsBlockWater(BlockID))
- {
- BlockHitPosition = pos;
- int Normal = GetHitNormal(a_Start, End, pos );
- if(Normal > 0)
- {
- HitNormal = m_NormalTable[Normal-1];
- }
- return 1;
- }
- }
- return 0;
-}
-
-// return 1 = hit, other is not hit
-int LinesCross(float x0,float y0,float x1,float y1,float x2,float y2,float x3,float y3)
-{
- //float linx, liny;
-
- float d=(x1-x0)*(y3-y2)-(y1-y0)*(x3-x2);
- if (abs(d)<0.001) {return 0;}
- float AB=((y0-y2)*(x3-x2)-(x0-x2)*(y3-y2))/d;
- if (AB>=0.0 && AB<=1.0)
- {
- float CD=((y0-y2)*(x1-x0)-(x0-x2)*(y1-y0))/d;
- if (CD>=0.0 && CD<=1.0)
- {
- //linx=x0+AB*(x1-x0);
- //liny=y0+AB*(y1-y0);
- return 1;
- }
- }
- return 0;
-}
-
-// intersect3D_SegmentPlane(): intersect a segment and a plane
-// Input: a_Ray = a segment, and a_Plane = a plane = {Point V0; Vector n;}
-// Output: *I0 = the intersect point (when it exists)
-// Return: 0 = disjoint (no intersection)
-// 1 = intersection in the unique point *I0
-// 2 = the segment lies in the plane
-int cTracer::intersect3D_SegmentPlane( const Vector3f & a_Origin, const Vector3f & a_End, const Vector3f & a_PlanePos, const Vector3f & a_PlaneNormal )
-{
- Vector3f u = a_End - a_Origin;//a_Ray.P1 - S.P0;
- Vector3f w = a_Origin - a_PlanePos;//S.P0 - Pn.V0;
-
- float D = a_PlaneNormal.Dot( u );//dot(Pn.n, u);
- float N = -(a_PlaneNormal.Dot( w ) );//-dot(a_Plane.n, w);
-
- const float EPSILON = 0.0001f;
- if (fabs(D) < EPSILON) { // segment is parallel to plane
- if (N == 0) // segment lies in plane
- return 2;
- return 0; // no intersection
- }
- // they are not parallel
- // compute intersect param
- float sI = N / D;
- if (sI < 0 || sI > 1)
- return 0; // no intersection
-
- //Vector3f I ( a_Ray->GetOrigin() + sI * u );//S.P0 + sI * u; // compute segment intersect point
- RealHit = a_Origin + u * sI;
- return 1;
-}
-
-int cTracer::GetHitNormal(const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos)
-{
- Vector3i SmallBlockPos = a_BlockPos;
- char BlockID = m_World->GetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z );
-
- if( BlockID == E_BLOCK_AIR || IsBlockWater(BlockID))
- return 0;
-
- Vector3f BlockPos;
- BlockPos = Vector3f(SmallBlockPos);
-
- Vector3f Look = (end - start);
- Look.Normalize();
-
- float dot = Look.Dot( Vector3f(-1, 0, 0) ); // first face normal is x -1
- if(dot < 0)
- {
- int Lines = LinesCross( start.x, start.y, end.x, end.y, BlockPos.x, BlockPos.y, BlockPos.x, BlockPos.y + 1 );
- if(Lines == 1)
- {
- Lines = LinesCross( start.x, start.z, end.x, end.z, BlockPos.x, BlockPos.z, BlockPos.x, BlockPos.z + 1 );
- if(Lines == 1)
- {
- intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(-1, 0, 0) );
- return 1;
- }
- }
- }
- dot = Look.Dot( Vector3f(0, 0, -1) ); // second face normal is z -1
- if(dot < 0)
- {
- int Lines = LinesCross( start.z, start.y, end.z, end.y, BlockPos.z, BlockPos.y, BlockPos.z, BlockPos.y + 1 );
- if(Lines == 1)
- {
- Lines = LinesCross( start.z, start.x, end.z, end.x, BlockPos.z, BlockPos.x, BlockPos.z, BlockPos.x + 1 );
- if(Lines == 1)
- {
- intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(0, 0, -1) );
- return 2;
- }
- }
- }
- dot = Look.Dot( Vector3f(1, 0, 0) ); // third face normal is x 1
- if(dot < 0)
- {
- int Lines = LinesCross( start.x, start.y, end.x, end.y, BlockPos.x + 1, BlockPos.y, BlockPos.x + 1, BlockPos.y + 1 );
- if(Lines == 1)
- {
- Lines = LinesCross( start.x, start.z, end.x, end.z, BlockPos.x + 1, BlockPos.z, BlockPos.x + 1, BlockPos.z + 1 );
- if(Lines == 1)
- {
- intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(1, 0, 0), Vector3f(1, 0, 0) );
- return 3;
- }
- }
- }
- dot = Look.Dot( Vector3f(0, 0, 1) ); // fourth face normal is z 1
- if(dot < 0)
- {
- int Lines = LinesCross( start.z, start.y, end.z, end.y, BlockPos.z + 1, BlockPos.y, BlockPos.z + 1, BlockPos.y + 1 );
- if(Lines == 1)
- {
- Lines = LinesCross( start.z, start.x, end.z, end.x, BlockPos.z + 1, BlockPos.x, BlockPos.z + 1, BlockPos.x + 1 );
- if(Lines == 1)
- {
- intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(0, 0, 1), Vector3f(0, 0, 1) );
- return 4;
- }
- }
- }
- dot = Look.Dot( Vector3f(0, 1, 0) ); // fifth face normal is y 1
- if(dot < 0)
- {
- int Lines = LinesCross( start.y, start.x, end.y, end.x, BlockPos.y + 1, BlockPos.x, BlockPos.y + 1, BlockPos.x + 1 );
- if(Lines == 1)
- {
- Lines = LinesCross( start.y, start.z, end.y, end.z, BlockPos.y + 1, BlockPos.z, BlockPos.y + 1, BlockPos.z + 1 );
- if(Lines == 1)
- {
- intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(0, 1, 0), Vector3f(0, 1, 0) );
- return 5;
- }
- }
- }
- dot = Look.Dot( Vector3f(0, -1, 0) ); // sixth face normal is y -1
- if(dot < 0)
- {
- int Lines = LinesCross( start.y, start.x, end.y, end.x, BlockPos.y, BlockPos.x, BlockPos.y, BlockPos.x + 1 );
- if(Lines == 1)
- {
- Lines = LinesCross( start.y, start.z, end.y, end.z, BlockPos.y, BlockPos.z, BlockPos.y, BlockPos.z + 1 );
- if(Lines == 1)
- {
- intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(0, -1, 0) );
- return 6;
- }
- }
- }
- return 0;
-}
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cTracer.h" +#include "cWorld.h" + +#include "Vector3f.h" +#include "Vector3i.h" +#include "Vector3d.h" + +#include "BlockID.h" +#include "cEntity.h" + +#include "Defines.h" + +#ifndef _WIN32 + #include <stdlib.h> // abs() +#endif + +cTracer::cTracer(cWorld* a_World) + : m_World( a_World ) +{ + m_NormalTable[0].Set(-1, 0, 0); + m_NormalTable[1].Set( 0, 0,-1); + m_NormalTable[2].Set( 1, 0, 0); + m_NormalTable[3].Set( 0, 0, 1); + m_NormalTable[4].Set( 0, 1, 0); + m_NormalTable[5].Set( 0,-1, 0); +} + +cTracer::~cTracer() +{ +} + +float cTracer::SigNum( float a_Num ) +{ + if (a_Num < 0.f) return -1.f; + if (a_Num > 0.f) return 1.f; + return 0.f; +} + +void cTracer::SetValues( const Vector3f & a_Start, const Vector3f & a_Direction ) +{ + // calculate the direction of the ray (linear algebra) + dir = a_Direction; + + // decide which direction to start walking in + step.x = (int) SigNum(dir.x); + step.y = (int) SigNum(dir.y); + step.z = (int) SigNum(dir.z); + + // normalize the direction vector + if( dir.SqrLength() > 0.f ) dir.Normalize(); + + // how far we must move in the ray direction before + // we encounter a new voxel in x-direction + // same but y-direction + if( dir.x != 0.f ) tDelta.x = 1/fabs(dir.x); + else tDelta.x = 0; + if( dir.y != 0.f ) tDelta.y = 1/fabs(dir.y); + else tDelta.y = 0; + if( dir.z != 0.f ) tDelta.z = 1/fabs(dir.z); + else tDelta.z = 0; + + // start voxel coordinates + // use your + // transformer + // function here + pos.x = (int)floorf(a_Start.x); + pos.y = (int)floorf(a_Start.y); + pos.z = (int)floorf(a_Start.z); + + // calculate distance to first intersection in the voxel we start from + if(dir.x < 0) + { + tMax.x = ((float)pos.x - a_Start.x) / dir.x; + } + else + { + tMax.x = (((float)pos.x + 1) - a_Start.x) / dir.x; + } + + if(dir.y < 0) + { + tMax.y = ((float)pos.y - a_Start.y) / dir.y; + } + else + { + tMax.y = (((float)pos.y + 1) - a_Start.y) / dir.y; + } + + if(dir.z < 0) + { + tMax.z = ((float)pos.z - a_Start.z) / dir.z; + } + else + { + tMax.z = (((float)pos.z + 1) - a_Start.z) / dir.z; + } +} + +int cTracer::Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int a_Distance) +{ + SetValues( a_Start, a_Direction ); + + const Vector3f End = a_Start + (dir * (float)a_Distance); + + // end voxel coordinates + end1.x = (int)floorf(End.x); + end1.y = (int)floorf(End.y); + end1.z = (int)floorf(End.z); + + // check if first is occupied + if( pos.Equals( end1 ) ) + { + LOG("WARNING: cTracer: Start and end in same block"); + return 0; + } + + bool reachedX = false, reachedY = false, reachedZ = false; + + int Iterations = 0; + while ( Iterations < a_Distance ) + { + Iterations++; + if(tMax.x < tMax.y && tMax.x < tMax.z) + { + tMax.x += tDelta.x; + pos.x += step.x; + } + else if(tMax.y < tMax.z) + { + tMax.y += tDelta.y; + pos.y += step.y; + } + else + { + tMax.z += tDelta.z; + pos.z += step.z; + } + + if(step.x > 0.0f) + { + if(pos.x >= end1.x) + { + reachedX = true; + } + } + else if(pos.x <= end1.x) + { + reachedX = true; + } + + if(step.y > 0.0f) + { + if(pos.y >= end1.y) + { + reachedY = true; + } + } + else if(pos.y <= end1.y) + { + reachedY = true; + } + + if(step.z > 0.0f) + { + if(pos.z >= end1.z) + { + reachedZ = true; + } + } + else if(pos.z <= end1.z) + { + reachedZ = true; + } + + if (reachedX && reachedY && reachedZ) + { + return false; + } + + char BlockID = m_World->GetBlock( pos.x, pos.y, pos.z ); + //No collision with water ;) + if ( BlockID != E_BLOCK_AIR || IsBlockWater(BlockID)) + { + BlockHitPosition = pos; + int Normal = GetHitNormal(a_Start, End, pos ); + if(Normal > 0) + { + HitNormal = m_NormalTable[Normal-1]; + } + return 1; + } + } + return 0; +} + +// return 1 = hit, other is not hit +int LinesCross(float x0,float y0,float x1,float y1,float x2,float y2,float x3,float y3) +{ + //float linx, liny; + + float d=(x1-x0)*(y3-y2)-(y1-y0)*(x3-x2); + if (abs(d)<0.001) {return 0;} + float AB=((y0-y2)*(x3-x2)-(x0-x2)*(y3-y2))/d; + if (AB>=0.0 && AB<=1.0) + { + float CD=((y0-y2)*(x1-x0)-(x0-x2)*(y1-y0))/d; + if (CD>=0.0 && CD<=1.0) + { + //linx=x0+AB*(x1-x0); + //liny=y0+AB*(y1-y0); + return 1; + } + } + return 0; +} + +// intersect3D_SegmentPlane(): intersect a segment and a plane +// Input: a_Ray = a segment, and a_Plane = a plane = {Point V0; Vector n;} +// Output: *I0 = the intersect point (when it exists) +// Return: 0 = disjoint (no intersection) +// 1 = intersection in the unique point *I0 +// 2 = the segment lies in the plane +int cTracer::intersect3D_SegmentPlane( const Vector3f & a_Origin, const Vector3f & a_End, const Vector3f & a_PlanePos, const Vector3f & a_PlaneNormal ) +{ + Vector3f u = a_End - a_Origin;//a_Ray.P1 - S.P0; + Vector3f w = a_Origin - a_PlanePos;//S.P0 - Pn.V0; + + float D = a_PlaneNormal.Dot( u );//dot(Pn.n, u); + float N = -(a_PlaneNormal.Dot( w ) );//-dot(a_Plane.n, w); + + const float EPSILON = 0.0001f; + if (fabs(D) < EPSILON) { // segment is parallel to plane + if (N == 0) // segment lies in plane + return 2; + return 0; // no intersection + } + // they are not parallel + // compute intersect param + float sI = N / D; + if (sI < 0 || sI > 1) + return 0; // no intersection + + //Vector3f I ( a_Ray->GetOrigin() + sI * u );//S.P0 + sI * u; // compute segment intersect point + RealHit = a_Origin + u * sI; + return 1; +} + +int cTracer::GetHitNormal(const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos) +{ + Vector3i SmallBlockPos = a_BlockPos; + char BlockID = m_World->GetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); + + if( BlockID == E_BLOCK_AIR || IsBlockWater(BlockID)) + return 0; + + Vector3f BlockPos; + BlockPos = Vector3f(SmallBlockPos); + + Vector3f Look = (end - start); + Look.Normalize(); + + float dot = Look.Dot( Vector3f(-1, 0, 0) ); // first face normal is x -1 + if(dot < 0) + { + int Lines = LinesCross( start.x, start.y, end.x, end.y, BlockPos.x, BlockPos.y, BlockPos.x, BlockPos.y + 1 ); + if(Lines == 1) + { + Lines = LinesCross( start.x, start.z, end.x, end.z, BlockPos.x, BlockPos.z, BlockPos.x, BlockPos.z + 1 ); + if(Lines == 1) + { + intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(-1, 0, 0) ); + return 1; + } + } + } + dot = Look.Dot( Vector3f(0, 0, -1) ); // second face normal is z -1 + if(dot < 0) + { + int Lines = LinesCross( start.z, start.y, end.z, end.y, BlockPos.z, BlockPos.y, BlockPos.z, BlockPos.y + 1 ); + if(Lines == 1) + { + Lines = LinesCross( start.z, start.x, end.z, end.x, BlockPos.z, BlockPos.x, BlockPos.z, BlockPos.x + 1 ); + if(Lines == 1) + { + intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(0, 0, -1) ); + return 2; + } + } + } + dot = Look.Dot( Vector3f(1, 0, 0) ); // third face normal is x 1 + if(dot < 0) + { + int Lines = LinesCross( start.x, start.y, end.x, end.y, BlockPos.x + 1, BlockPos.y, BlockPos.x + 1, BlockPos.y + 1 ); + if(Lines == 1) + { + Lines = LinesCross( start.x, start.z, end.x, end.z, BlockPos.x + 1, BlockPos.z, BlockPos.x + 1, BlockPos.z + 1 ); + if(Lines == 1) + { + intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(1, 0, 0), Vector3f(1, 0, 0) ); + return 3; + } + } + } + dot = Look.Dot( Vector3f(0, 0, 1) ); // fourth face normal is z 1 + if(dot < 0) + { + int Lines = LinesCross( start.z, start.y, end.z, end.y, BlockPos.z + 1, BlockPos.y, BlockPos.z + 1, BlockPos.y + 1 ); + if(Lines == 1) + { + Lines = LinesCross( start.z, start.x, end.z, end.x, BlockPos.z + 1, BlockPos.x, BlockPos.z + 1, BlockPos.x + 1 ); + if(Lines == 1) + { + intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(0, 0, 1), Vector3f(0, 0, 1) ); + return 4; + } + } + } + dot = Look.Dot( Vector3f(0, 1, 0) ); // fifth face normal is y 1 + if(dot < 0) + { + int Lines = LinesCross( start.y, start.x, end.y, end.x, BlockPos.y + 1, BlockPos.x, BlockPos.y + 1, BlockPos.x + 1 ); + if(Lines == 1) + { + Lines = LinesCross( start.y, start.z, end.y, end.z, BlockPos.y + 1, BlockPos.z, BlockPos.y + 1, BlockPos.z + 1 ); + if(Lines == 1) + { + intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(0, 1, 0), Vector3f(0, 1, 0) ); + return 5; + } + } + } + dot = Look.Dot( Vector3f(0, -1, 0) ); // sixth face normal is y -1 + if(dot < 0) + { + int Lines = LinesCross( start.y, start.x, end.y, end.x, BlockPos.y, BlockPos.x, BlockPos.y, BlockPos.x + 1 ); + if(Lines == 1) + { + Lines = LinesCross( start.y, start.z, end.y, end.z, BlockPos.y, BlockPos.z, BlockPos.y, BlockPos.z + 1 ); + if(Lines == 1) + { + intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(0, -1, 0) ); + return 6; + } + } + } + return 0; +} diff --git a/source/cTracer.h b/source/cTracer.h index 08ebc72e5..fa9d3c673 100644 --- a/source/cTracer.h +++ b/source/cTracer.h @@ -1,34 +1,34 @@ -#pragma once
-
-#include "Vector3i.h"
-#include "Vector3f.h"
-
-
-class cWorld;
-class cTracer //tolua_export
-{ //tolua_export
-public: //tolua_export
- Vector3f DotPos;
- Vector3f BoxOffset;
- cTracer( cWorld* a_World); //tolua_export
- ~cTracer(); //tolua_export
- int Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int a_Distance ); //tolua_export
- void SetValues( const Vector3f & a_Start, const Vector3f & a_Direction ); //tolua_export
- Vector3f BlockHitPosition; //tolua_export
- Vector3f HitNormal; //tolua_export
- Vector3f RealHit; //tolua_export
-private:
- int intersect3D_SegmentPlane( const Vector3f & a_Origin, const Vector3f & a_End, const Vector3f & a_PlanePos, const Vector3f & a_PlaneNormal );
- int GetHitNormal( const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos);
- float SigNum( float a_Num );
- cWorld* m_World;
-
- Vector3f m_NormalTable[6];
-
- Vector3f dir;
- Vector3f tDelta;
- Vector3i pos;
- Vector3i end1;
- Vector3i step;
- Vector3f tMax;
+#pragma once + +#include "Vector3i.h" +#include "Vector3f.h" + + +class cWorld; +class cTracer //tolua_export +{ //tolua_export +public: //tolua_export + Vector3f DotPos; + Vector3f BoxOffset; + cTracer( cWorld* a_World); //tolua_export + ~cTracer(); //tolua_export + int Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int a_Distance ); //tolua_export + void SetValues( const Vector3f & a_Start, const Vector3f & a_Direction ); //tolua_export + Vector3f BlockHitPosition; //tolua_export + Vector3f HitNormal; //tolua_export + Vector3f RealHit; //tolua_export +private: + int intersect3D_SegmentPlane( const Vector3f & a_Origin, const Vector3f & a_End, const Vector3f & a_PlanePos, const Vector3f & a_PlaneNormal ); + int GetHitNormal( const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos); + float SigNum( float a_Num ); + cWorld* m_World; + + Vector3f m_NormalTable[6]; + + Vector3f dir; + Vector3f tDelta; + Vector3i pos; + Vector3i end1; + Vector3i step; + Vector3f tMax; }; //tolua_export
\ No newline at end of file diff --git a/source/cWaterSimulator.cpp b/source/cWaterSimulator.cpp index 22f4ece00..642d54aac 100644 --- a/source/cWaterSimulator.cpp +++ b/source/cWaterSimulator.cpp @@ -1,22 +1,22 @@ -#include "Globals.h"
-#include "cWaterSimulator.h"
-#include "Defines.h"
-#include "cWorld.h"
-
-
-
-cWaterSimulator::cWaterSimulator(cWorld *a_World)
- : cFluidSimulator(a_World)
-{
- m_FluidBlock = E_BLOCK_WATER;
- m_StationaryFluidBlock = E_BLOCK_STATIONARY_WATER;
- m_MaxHeight = 7;
- m_FlowReduction = 1;
-}
-
-
-bool cWaterSimulator::IsAllowedBlock(char a_BlockID)
-{
- return IsBlockWater(a_BlockID);
-}
-
+#include "Globals.h" +#include "cWaterSimulator.h" +#include "Defines.h" +#include "cWorld.h" + + + +cWaterSimulator::cWaterSimulator(cWorld *a_World) + : cFluidSimulator(a_World) +{ + m_FluidBlock = E_BLOCK_WATER; + m_StationaryFluidBlock = E_BLOCK_STATIONARY_WATER; + m_MaxHeight = 7; + m_FlowReduction = 1; +} + + +bool cWaterSimulator::IsAllowedBlock(char a_BlockID) +{ + return IsBlockWater(a_BlockID); +} + diff --git a/source/cWaterSimulator.h b/source/cWaterSimulator.h index c00481482..7d4a4a19b 100644 --- a/source/cWaterSimulator.h +++ b/source/cWaterSimulator.h @@ -1,11 +1,11 @@ -#pragma once
-#include "cFluidSimulator.h"
-
-class cWaterSimulator : public cFluidSimulator
-{
-public:
- cWaterSimulator( cWorld* a_World );
-
- virtual bool IsAllowedBlock( char a_BlockID );
-
+#pragma once +#include "cFluidSimulator.h" + +class cWaterSimulator : public cFluidSimulator +{ +public: + cWaterSimulator( cWorld* a_World ); + + virtual bool IsAllowedBlock( char a_BlockID ); + };
\ No newline at end of file diff --git a/source/cWebAdmin.cpp b/source/cWebAdmin.cpp index b05eedb16..33068ec38 100644 --- a/source/cWebAdmin.cpp +++ b/source/cWebAdmin.cpp @@ -1,383 +1,383 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cWebAdmin.h"
-#include "cStringMap.h"
-
-#include "cWebPlugin.h"
-#include "cWebPlugin_Lua.h"
-
-#include "cPluginManager.h"
-#include "cPlugin.h"
-
-#include "cWorld.h"
-#include "cPlayer.h"
-#include "cServer.h"
-#include "cRoot.h"
-
-#include "../iniFile/iniFile.h"
-
-#ifdef _WIN32
- #include <psapi.h>
-#else
- #include <sys/resource.h>
-#endif
-
-
-
-
-
-/// Helper class - appends all player names together in a HTML list
-class cPlayerAccum :
- public cPlayerListCallback
-{
- virtual bool Item(cPlayer * a_Player) override
- {
- m_Contents.append("<li>");
- m_Contents.append(a_Player->GetName());
- m_Contents.append("</li>");
- return false;
- }
-
-public:
-
- AString m_Contents;
-} ;
-
-
-
-
-
-cWebAdmin * WebAdmin = NULL;
-
-
-
-
-
-cWebAdmin::cWebAdmin( int a_Port /* = 8080 */ )
- : m_Port( a_Port )
- , m_bConnected( false )
-{
- WebAdmin = this;
- m_Event = new cEvent();
- Init( m_Port );
-}
-
-cWebAdmin::~cWebAdmin()
-{
- WebAdmin = 0;
- m_WebServer->Stop();
-
- while( m_Plugins.begin() != m_Plugins.end() )
- {
- delete *m_Plugins.begin();
- //m_Plugins.remove( *m_Plugins.begin() );
- }
- delete m_WebServer;
- delete m_IniFile;
-
- m_Event->Wait();
- delete m_Event;
-}
-
-void cWebAdmin::AddPlugin( cWebPlugin* a_Plugin )
-{
- m_Plugins.remove( a_Plugin );
- m_Plugins.push_back( a_Plugin );
-}
-
-void cWebAdmin::RemovePlugin( cWebPlugin* a_Plugin )
-{
- m_Plugins.remove( a_Plugin );
-}
-
-
-
-
-
-void cWebAdmin::Request_Handler(webserver::http_request* r)
-{
- if( WebAdmin == 0 ) return;
- LOG("Path: %s", r->path_.c_str() );
-
- if (r->path_ == "/")
- {
- r->answer_ += "<h1>MCServer WebAdmin</h1>";
- r->answer_ += "<center>";
- r->answer_ += "<form method='get' action='webadmin/'>";
- r->answer_ += "<input type='submit' value='Log in'>";
- r->answer_ += "</form>";
- r->answer_ += "</center>";
- return;
- }
-
- if (r->path_.empty() || r->path_[0] != '/')
- {
- r->answer_ += "<h1>Bad request</h1>";
- r->answer_ += "<p>";
- r->answer_ = r->path_; // TODO: Shouldn't we sanitize this? Possible security issue.
- r->answer_ += "</p>";
- return;
- }
-
- AStringVector Split = StringSplit(r->path_.substr(1), "/");
-
- if (Split.empty() || (Split[0] != "webadmin"))
- {
- r->answer_ += "<h1>Bad request</h1>";
- return;
- }
-
- if (!r->authentication_given_)
- {
- r->answer_ += "no auth";
- r->auth_realm_ = "MCServer WebAdmin";
- }
-
- std::string UserPassword = WebAdmin->m_IniFile->GetValue( "User:"+r->username_, "Password", "");
- if ((UserPassword != "") && (r->password_ == UserPassword))
- {
- std::string BaseURL = "./";
- if (Split.size() > 1)
- {
- for (unsigned int i = 0; i < Split.size(); i++)
- {
- BaseURL += "../";
- }
- BaseURL += "webadmin/";
- }
-
- std::string Menu;
- std::string Content;
- std::string Template = WebAdmin->GetTemplate();
- std::string FoundPlugin;
-
- for (PluginList::iterator itr = WebAdmin->m_Plugins.begin(); itr != WebAdmin->m_Plugins.end(); ++itr)
- {
- cWebPlugin* WebPlugin = *itr;
- cWebPlugin_Lua* LuaPlugin = dynamic_cast< cWebPlugin_Lua* >( WebPlugin );
- if( LuaPlugin )
- {
- std::list< std::pair<std::string, std::string> > NameList = LuaPlugin->GetTabNames();
- for( std::list< std::pair<std::string, std::string> >::iterator Names = NameList.begin(); Names != NameList.end(); ++Names )
- {
- Menu += "<li><a href='" + BaseURL + WebPlugin->GetName() + "/" + (*Names).second + "'>" + (*Names).first + "</a></li>";
- }
- }
- else
- {
- Menu += "<li><a href='" + BaseURL + WebPlugin->GetName() + "'>" + WebPlugin->GetName() + "</a></li>";
- }
- }
-
- HTTPRequest Request;
- Request.Username = r->username_;
- Request.Method = r->method_;
- Request.Params = r->params_;
- Request.PostParams = r->params_post_;
- Request.Path = r->path_.substr(1);
-
- for( unsigned int i = 0; i < r->multipart_formdata_.size(); ++i )
- {
- webserver::formdata& fd = r->multipart_formdata_[i];
-
- HTTPFormData HTTPfd;//( fd.value_ );
- HTTPfd.Value = fd.value_;
- HTTPfd.Type = fd.content_type_;
- HTTPfd.Name = fd.name_;
- LOGINFO("Form data name: %s", fd.name_.c_str() );
- Request.FormData[ fd.name_ ] = HTTPfd;
- }
-
- if( Split.size() > 1 )
- {
- for( PluginList::iterator itr = WebAdmin->m_Plugins.begin(); itr != WebAdmin->m_Plugins.end(); ++itr )
- {
- if( (*itr)->GetName() == Split[1] )
- {
- Content = (*itr)->HandleRequest( &Request );
- cWebPlugin* WebPlugin = *itr;
- FoundPlugin = WebPlugin->GetName();
- cWebPlugin_Lua* LuaPlugin = dynamic_cast< cWebPlugin_Lua* >( WebPlugin );
- if( LuaPlugin )
- {
- FoundPlugin += " - " + LuaPlugin->GetTabNameForRequest( &Request ).first;
- }
- break;
- }
- }
- }
-
- if( FoundPlugin.empty() ) // Default page
- {
- Content.clear();
- FoundPlugin = "Current Game";
- Content += "<h4>Server Name:</h4>";
- Content += "<p>" + std::string( cRoot::Get()->GetServer()->GetServerID() ) + "</p>";
-
- Content += "<h4>Plugins:</h4><ul>";
- cPluginManager* PM = cRoot::Get()->GetPluginManager();
- if( PM )
- {
- const cPluginManager::PluginList & List = PM->GetAllPlugins();
- for( cPluginManager::PluginList::const_iterator itr = List.begin(); itr != List.end(); ++itr )
- {
- AString VersionNum;
- AppendPrintf(Content, "<li>%s V.%i</li>", (*itr)->GetName(), (*itr)->GetVersion());
- }
- }
- Content += "</ul>";
- Content += "<h4>Players:</h4><ul>";
-
- cPlayerAccum PlayerAccum;
- cWorld * World = cRoot::Get()->GetDefaultWorld(); // TODO - Create a list of worlds and players
- World->ForEachPlayer(PlayerAccum);
- Content.append(PlayerAccum.m_Contents);
- Content += "</ul><br>";
- }
-
-
-
- if( Split.size() > 1 )
- {
- Content += "\n<p><a href='" + BaseURL + "'>Go back</a></p>";
- }
-
- // mem usage
-#ifndef _WIN32
- rusage resource_usage;
- if (getrusage(RUSAGE_SELF, &resource_usage) != 0)
- {
- ReplaceString( Template, std::string("{MEM}"), "Error :(" );
- }
- else
- {
- AString MemUsage;
- Printf(MemUsage, "%0.2f", ((double)resource_usage.ru_maxrss / 1024 / 1024) );
- ReplaceString(Template, std::string("{MEM}"), MemUsage);
- }
-#else
- HANDLE hProcess = GetCurrentProcess();
- PROCESS_MEMORY_COUNTERS pmc;
- if( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc) ) )
- {
- AString MemUsage;
- Printf(MemUsage, "%0.2f", (pmc.WorkingSetSize / 1024.f / 1024.f) );
- ReplaceString( Template, "{MEM}", MemUsage );
- }
-#endif
- // end mem usage
-
- ReplaceString( Template, "{USERNAME}", r->username_ );
- ReplaceString( Template, "{MENU}", Menu );
- ReplaceString( Template, "{PLUGIN_NAME}", FoundPlugin );
- ReplaceString( Template, "{CONTENT}", Content );
- ReplaceString( Template, "{TITLE}", "MCServer" );
-
- AString NumChunks;
- Printf(NumChunks, "%d", cRoot::Get()->GetTotalChunkCount());
- ReplaceString(Template, "{NUMCHUNKS}", NumChunks);
-
- r->answer_ = Template;
- }
- else
- {
- r->answer_ += "Wrong username/password";
- r->auth_realm_ = "MCServer WebAdmin";
- }
-}
-
-
-
-
-
-bool cWebAdmin::Init( int a_Port )
-{
- m_Port = a_Port;
-
- m_IniFile = new cIniFile("webadmin.ini");
- if( m_IniFile->ReadFile() )
- {
- m_Port = m_IniFile->GetValueI("WebAdmin", "Port", 8080 );
- }
-
- LOG("Starting WebAdmin on port %i", m_Port);
-
-#ifdef _WIN32
- HANDLE hThread = CreateThread(
- NULL, // default security
- 0, // default stack size
- ListenThread, // name of the thread function
- this, // thread parameters
- 0, // default startup flags
- NULL);
- CloseHandle( hThread ); // Just close the handle immediately
-#else
- pthread_t LstnThread;
- pthread_create( &LstnThread, 0, ListenThread, this);
-#endif
-
- return true;
-}
-
-
-
-
-
-#ifdef _WIN32
-DWORD WINAPI cWebAdmin::ListenThread(LPVOID lpParam)
-#else
-void *cWebAdmin::ListenThread( void *lpParam )
-#endif
-{
- cWebAdmin* self = (cWebAdmin*)lpParam;
-
- self->m_WebServer = new webserver(self->m_Port, Request_Handler );
- if (!self->m_WebServer->Begin())
- {
- LOGWARN("WebServer failed to start! WebAdmin is disabled");
- }
-
- self->m_Event->Set();
- return 0;
-}
-
-
-
-
-
-std::string cWebAdmin::GetTemplate()
-{
- std::string retVal = "";
-
- char SourceFile[] = "webadmin/template.html";
-
- cFile f;
- if (!f.Open(SourceFile, cFile::fmRead))
- {
- return "";
- }
-
- // copy the file into the buffer:
- f.ReadRestOfFile(retVal);
-
- return retVal;
-}
-
-
-
-
-
-void cWebAdmin::RemovePlugin( lua_State* L )
-{
- for( PluginList::iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); )
- {
- if( (*itr)->GetLuaState() == L )
- {
- PluginList::iterator prev = itr++;
- delete *prev; // deleting a dereferenced iterator also takes it out of the list, so no need for erase()
- }
- else
- ++itr;
- }
-}
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cWebAdmin.h" +#include "cStringMap.h" + +#include "cWebPlugin.h" +#include "cWebPlugin_Lua.h" + +#include "cPluginManager.h" +#include "cPlugin.h" + +#include "cWorld.h" +#include "cPlayer.h" +#include "cServer.h" +#include "cRoot.h" + +#include "../iniFile/iniFile.h" + +#ifdef _WIN32 + #include <psapi.h> +#else + #include <sys/resource.h> +#endif + + + + + +/// Helper class - appends all player names together in a HTML list +class cPlayerAccum : + public cPlayerListCallback +{ + virtual bool Item(cPlayer * a_Player) override + { + m_Contents.append("<li>"); + m_Contents.append(a_Player->GetName()); + m_Contents.append("</li>"); + return false; + } + +public: + + AString m_Contents; +} ; + + + + + +cWebAdmin * WebAdmin = NULL; + + + + + +cWebAdmin::cWebAdmin( int a_Port /* = 8080 */ ) + : m_Port( a_Port ) + , m_bConnected( false ) +{ + WebAdmin = this; + m_Event = new cEvent(); + Init( m_Port ); +} + +cWebAdmin::~cWebAdmin() +{ + WebAdmin = 0; + m_WebServer->Stop(); + + while( m_Plugins.begin() != m_Plugins.end() ) + { + delete *m_Plugins.begin(); + //m_Plugins.remove( *m_Plugins.begin() ); + } + delete m_WebServer; + delete m_IniFile; + + m_Event->Wait(); + delete m_Event; +} + +void cWebAdmin::AddPlugin( cWebPlugin* a_Plugin ) +{ + m_Plugins.remove( a_Plugin ); + m_Plugins.push_back( a_Plugin ); +} + +void cWebAdmin::RemovePlugin( cWebPlugin* a_Plugin ) +{ + m_Plugins.remove( a_Plugin ); +} + + + + + +void cWebAdmin::Request_Handler(webserver::http_request* r) +{ + if( WebAdmin == 0 ) return; + LOG("Path: %s", r->path_.c_str() ); + + if (r->path_ == "/") + { + r->answer_ += "<h1>MCServer WebAdmin</h1>"; + r->answer_ += "<center>"; + r->answer_ += "<form method='get' action='webadmin/'>"; + r->answer_ += "<input type='submit' value='Log in'>"; + r->answer_ += "</form>"; + r->answer_ += "</center>"; + return; + } + + if (r->path_.empty() || r->path_[0] != '/') + { + r->answer_ += "<h1>Bad request</h1>"; + r->answer_ += "<p>"; + r->answer_ = r->path_; // TODO: Shouldn't we sanitize this? Possible security issue. + r->answer_ += "</p>"; + return; + } + + AStringVector Split = StringSplit(r->path_.substr(1), "/"); + + if (Split.empty() || (Split[0] != "webadmin")) + { + r->answer_ += "<h1>Bad request</h1>"; + return; + } + + if (!r->authentication_given_) + { + r->answer_ += "no auth"; + r->auth_realm_ = "MCServer WebAdmin"; + } + + std::string UserPassword = WebAdmin->m_IniFile->GetValue( "User:"+r->username_, "Password", ""); + if ((UserPassword != "") && (r->password_ == UserPassword)) + { + std::string BaseURL = "./"; + if (Split.size() > 1) + { + for (unsigned int i = 0; i < Split.size(); i++) + { + BaseURL += "../"; + } + BaseURL += "webadmin/"; + } + + std::string Menu; + std::string Content; + std::string Template = WebAdmin->GetTemplate(); + std::string FoundPlugin; + + for (PluginList::iterator itr = WebAdmin->m_Plugins.begin(); itr != WebAdmin->m_Plugins.end(); ++itr) + { + cWebPlugin* WebPlugin = *itr; + cWebPlugin_Lua* LuaPlugin = dynamic_cast< cWebPlugin_Lua* >( WebPlugin ); + if( LuaPlugin ) + { + std::list< std::pair<std::string, std::string> > NameList = LuaPlugin->GetTabNames(); + for( std::list< std::pair<std::string, std::string> >::iterator Names = NameList.begin(); Names != NameList.end(); ++Names ) + { + Menu += "<li><a href='" + BaseURL + WebPlugin->GetName() + "/" + (*Names).second + "'>" + (*Names).first + "</a></li>"; + } + } + else + { + Menu += "<li><a href='" + BaseURL + WebPlugin->GetName() + "'>" + WebPlugin->GetName() + "</a></li>"; + } + } + + HTTPRequest Request; + Request.Username = r->username_; + Request.Method = r->method_; + Request.Params = r->params_; + Request.PostParams = r->params_post_; + Request.Path = r->path_.substr(1); + + for( unsigned int i = 0; i < r->multipart_formdata_.size(); ++i ) + { + webserver::formdata& fd = r->multipart_formdata_[i]; + + HTTPFormData HTTPfd;//( fd.value_ ); + HTTPfd.Value = fd.value_; + HTTPfd.Type = fd.content_type_; + HTTPfd.Name = fd.name_; + LOGINFO("Form data name: %s", fd.name_.c_str() ); + Request.FormData[ fd.name_ ] = HTTPfd; + } + + if( Split.size() > 1 ) + { + for( PluginList::iterator itr = WebAdmin->m_Plugins.begin(); itr != WebAdmin->m_Plugins.end(); ++itr ) + { + if( (*itr)->GetName() == Split[1] ) + { + Content = (*itr)->HandleRequest( &Request ); + cWebPlugin* WebPlugin = *itr; + FoundPlugin = WebPlugin->GetName(); + cWebPlugin_Lua* LuaPlugin = dynamic_cast< cWebPlugin_Lua* >( WebPlugin ); + if( LuaPlugin ) + { + FoundPlugin += " - " + LuaPlugin->GetTabNameForRequest( &Request ).first; + } + break; + } + } + } + + if( FoundPlugin.empty() ) // Default page + { + Content.clear(); + FoundPlugin = "Current Game"; + Content += "<h4>Server Name:</h4>"; + Content += "<p>" + std::string( cRoot::Get()->GetServer()->GetServerID() ) + "</p>"; + + Content += "<h4>Plugins:</h4><ul>"; + cPluginManager* PM = cRoot::Get()->GetPluginManager(); + if( PM ) + { + const cPluginManager::PluginList & List = PM->GetAllPlugins(); + for( cPluginManager::PluginList::const_iterator itr = List.begin(); itr != List.end(); ++itr ) + { + AString VersionNum; + AppendPrintf(Content, "<li>%s V.%i</li>", (*itr)->GetName(), (*itr)->GetVersion()); + } + } + Content += "</ul>"; + Content += "<h4>Players:</h4><ul>"; + + cPlayerAccum PlayerAccum; + cWorld * World = cRoot::Get()->GetDefaultWorld(); // TODO - Create a list of worlds and players + World->ForEachPlayer(PlayerAccum); + Content.append(PlayerAccum.m_Contents); + Content += "</ul><br>"; + } + + + + if( Split.size() > 1 ) + { + Content += "\n<p><a href='" + BaseURL + "'>Go back</a></p>"; + } + + // mem usage +#ifndef _WIN32 + rusage resource_usage; + if (getrusage(RUSAGE_SELF, &resource_usage) != 0) + { + ReplaceString( Template, std::string("{MEM}"), "Error :(" ); + } + else + { + AString MemUsage; + Printf(MemUsage, "%0.2f", ((double)resource_usage.ru_maxrss / 1024 / 1024) ); + ReplaceString(Template, std::string("{MEM}"), MemUsage); + } +#else + HANDLE hProcess = GetCurrentProcess(); + PROCESS_MEMORY_COUNTERS pmc; + if( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc) ) ) + { + AString MemUsage; + Printf(MemUsage, "%0.2f", (pmc.WorkingSetSize / 1024.f / 1024.f) ); + ReplaceString( Template, "{MEM}", MemUsage ); + } +#endif + // end mem usage + + ReplaceString( Template, "{USERNAME}", r->username_ ); + ReplaceString( Template, "{MENU}", Menu ); + ReplaceString( Template, "{PLUGIN_NAME}", FoundPlugin ); + ReplaceString( Template, "{CONTENT}", Content ); + ReplaceString( Template, "{TITLE}", "MCServer" ); + + AString NumChunks; + Printf(NumChunks, "%d", cRoot::Get()->GetTotalChunkCount()); + ReplaceString(Template, "{NUMCHUNKS}", NumChunks); + + r->answer_ = Template; + } + else + { + r->answer_ += "Wrong username/password"; + r->auth_realm_ = "MCServer WebAdmin"; + } +} + + + + + +bool cWebAdmin::Init( int a_Port ) +{ + m_Port = a_Port; + + m_IniFile = new cIniFile("webadmin.ini"); + if( m_IniFile->ReadFile() ) + { + m_Port = m_IniFile->GetValueI("WebAdmin", "Port", 8080 ); + } + + LOG("Starting WebAdmin on port %i", m_Port); + +#ifdef _WIN32 + HANDLE hThread = CreateThread( + NULL, // default security + 0, // default stack size + ListenThread, // name of the thread function + this, // thread parameters + 0, // default startup flags + NULL); + CloseHandle( hThread ); // Just close the handle immediately +#else + pthread_t LstnThread; + pthread_create( &LstnThread, 0, ListenThread, this); +#endif + + return true; +} + + + + + +#ifdef _WIN32 +DWORD WINAPI cWebAdmin::ListenThread(LPVOID lpParam) +#else +void *cWebAdmin::ListenThread( void *lpParam ) +#endif +{ + cWebAdmin* self = (cWebAdmin*)lpParam; + + self->m_WebServer = new webserver(self->m_Port, Request_Handler ); + if (!self->m_WebServer->Begin()) + { + LOGWARN("WebServer failed to start! WebAdmin is disabled"); + } + + self->m_Event->Set(); + return 0; +} + + + + + +std::string cWebAdmin::GetTemplate() +{ + std::string retVal = ""; + + char SourceFile[] = "webadmin/template.html"; + + cFile f; + if (!f.Open(SourceFile, cFile::fmRead)) + { + return ""; + } + + // copy the file into the buffer: + f.ReadRestOfFile(retVal); + + return retVal; +} + + + + + +void cWebAdmin::RemovePlugin( lua_State* L ) +{ + for( PluginList::iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ) + { + if( (*itr)->GetLuaState() == L ) + { + PluginList::iterator prev = itr++; + delete *prev; // deleting a dereferenced iterator also takes it out of the list, so no need for erase() + } + else + ++itr; + } +} diff --git a/source/cWebAdmin.h b/source/cWebAdmin.h index 3be9426ad..9eca47105 100644 --- a/source/cWebAdmin.h +++ b/source/cWebAdmin.h @@ -1,69 +1,69 @@ -#pragma once
-
-#include "../WebServer/WebServer.h"
-#include "cSocket.h"
-
-class cStringMap;
-
-struct HTTPFormData //tolua_export
-{ //tolua_export
- std::string Name; //tolua_export
- std::string Value; //tolua_export
- std::string Type; //tolua_export
-};//tolua_export
-
-struct HTTPRequest //tolua_export
-{ //tolua_export
- typedef std::map< std::string, std::string > StringStringMap;
- typedef std::map< std::string, HTTPFormData > FormDataMap;
- std::string Method; //tolua_export
- std::string Path; //tolua_export
- StringStringMap Params; // >> EXPORTED IN MANUALBINDINGS <<
- StringStringMap PostParams; // >> EXPORTED IN MANUALBINDINGS <<
- std::string Username; //tolua_export
- FormDataMap FormData; // >> EXPORTED IN MANUALBINDINGS <<
-}; //tolua_export
-
-struct lua_State;
-class cEvent;
-class cIniFile;
-class cWebPlugin;
-class cWebAdmin
-{
-public:
- cWebAdmin( int a_Port = 8080 );
- ~cWebAdmin();
-
- bool Init( int a_Port );
-
- void AddPlugin( cWebPlugin* a_Plugin );
- void RemovePlugin( cWebPlugin* a_Plugin );
-
- typedef std::list< cWebPlugin* > PluginList;
- PluginList GetPlugins() { return m_Plugins; }
-
- static void Request_Handler(webserver::http_request* r);
-
- void RemovePlugin( lua_State* L );
-private:
-
-#ifdef _WIN32
- static DWORD WINAPI ListenThread(LPVOID lpParam);
-#else
- static void *ListenThread( void *lpParam );
-#endif
-
- std::string GetTemplate();
-
- int m_Port;
-
- bool m_bConnected;
- cSocket m_ListenSocket;
-
- cIniFile* m_IniFile;
- PluginList m_Plugins;
-
- cEvent* m_Event;
-
- webserver* m_WebServer;
+#pragma once + +#include "../WebServer/WebServer.h" +#include "cSocket.h" + +class cStringMap; + +struct HTTPFormData //tolua_export +{ //tolua_export + std::string Name; //tolua_export + std::string Value; //tolua_export + std::string Type; //tolua_export +};//tolua_export + +struct HTTPRequest //tolua_export +{ //tolua_export + typedef std::map< std::string, std::string > StringStringMap; + typedef std::map< std::string, HTTPFormData > FormDataMap; + std::string Method; //tolua_export + std::string Path; //tolua_export + StringStringMap Params; // >> EXPORTED IN MANUALBINDINGS << + StringStringMap PostParams; // >> EXPORTED IN MANUALBINDINGS << + std::string Username; //tolua_export + FormDataMap FormData; // >> EXPORTED IN MANUALBINDINGS << +}; //tolua_export + +struct lua_State; +class cEvent; +class cIniFile; +class cWebPlugin; +class cWebAdmin +{ +public: + cWebAdmin( int a_Port = 8080 ); + ~cWebAdmin(); + + bool Init( int a_Port ); + + void AddPlugin( cWebPlugin* a_Plugin ); + void RemovePlugin( cWebPlugin* a_Plugin ); + + typedef std::list< cWebPlugin* > PluginList; + PluginList GetPlugins() { return m_Plugins; } + + static void Request_Handler(webserver::http_request* r); + + void RemovePlugin( lua_State* L ); +private: + +#ifdef _WIN32 + static DWORD WINAPI ListenThread(LPVOID lpParam); +#else + static void *ListenThread( void *lpParam ); +#endif + + std::string GetTemplate(); + + int m_Port; + + bool m_bConnected; + cSocket m_ListenSocket; + + cIniFile* m_IniFile; + PluginList m_Plugins; + + cEvent* m_Event; + + webserver* m_WebServer; };
\ No newline at end of file diff --git a/source/cWebPlugin.cpp b/source/cWebPlugin.cpp index 923c48722..186662ba8 100644 --- a/source/cWebPlugin.cpp +++ b/source/cWebPlugin.cpp @@ -1,26 +1,26 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cWebPlugin.h"
-#include "cWebAdmin.h"
-#include "cServer.h"
-#include "cRoot.h"
-
-
-
-
-
-cWebPlugin::cWebPlugin( lua_State* L )
-{
- LOG("cWebPlugin::cWebPlugin()");
- m_LuaState = L;
- cWebAdmin* WebAdmin = cRoot::Get()->GetWebAdmin();
- if( WebAdmin ) WebAdmin->AddPlugin( this );
-}
-
-cWebPlugin::~cWebPlugin()
-{
- LOG("~cWebPlugin::cWebPlugin()");
- cWebAdmin* WebAdmin = cRoot::Get()->GetWebAdmin();
- if( WebAdmin ) WebAdmin->RemovePlugin( this );
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cWebPlugin.h" +#include "cWebAdmin.h" +#include "cServer.h" +#include "cRoot.h" + + + + + +cWebPlugin::cWebPlugin( lua_State* L ) +{ + LOG("cWebPlugin::cWebPlugin()"); + m_LuaState = L; + cWebAdmin* WebAdmin = cRoot::Get()->GetWebAdmin(); + if( WebAdmin ) WebAdmin->AddPlugin( this ); +} + +cWebPlugin::~cWebPlugin() +{ + LOG("~cWebPlugin::cWebPlugin()"); + cWebAdmin* WebAdmin = cRoot::Get()->GetWebAdmin(); + if( WebAdmin ) WebAdmin->RemovePlugin( this ); }
\ No newline at end of file diff --git a/source/cWebPlugin.h b/source/cWebPlugin.h index 1faf4e9ae..e6eb00559 100644 --- a/source/cWebPlugin.h +++ b/source/cWebPlugin.h @@ -1,24 +1,24 @@ -
-#pragma once
-
-struct lua_State;
-struct HTTPRequest;
-//tolua_begin
-class cWebPlugin
-{
-public:
- cWebPlugin( lua_State* L );
- virtual ~cWebPlugin();
-
- void SetName( std::string a_Name ) { m_Name = a_Name; }
- std::string GetName() { return m_Name; }
-
- virtual std::string HandleRequest( HTTPRequest* a_Request ) = 0;
- virtual void Initialize() = 0;
- //tolua_end
-
- lua_State* GetLuaState() { return m_LuaState; }
-private:
- lua_State* m_LuaState;
- std::string m_Name;
+ +#pragma once + +struct lua_State; +struct HTTPRequest; +//tolua_begin +class cWebPlugin +{ +public: + cWebPlugin( lua_State* L ); + virtual ~cWebPlugin(); + + void SetName( std::string a_Name ) { m_Name = a_Name; } + std::string GetName() { return m_Name; } + + virtual std::string HandleRequest( HTTPRequest* a_Request ) = 0; + virtual void Initialize() = 0; + //tolua_end + + lua_State* GetLuaState() { return m_LuaState; } +private: + lua_State* m_LuaState; + std::string m_Name; }; //tolua_export
\ No newline at end of file diff --git a/source/cWebPlugin_Lua.cpp b/source/cWebPlugin_Lua.cpp index ab397173e..e22c59961 100644 --- a/source/cWebPlugin_Lua.cpp +++ b/source/cWebPlugin_Lua.cpp @@ -1,185 +1,185 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cWebPlugin_Lua.h"
-#include "cPlugin_NewLua.h"
-
-#include "tolua++.h"
-#include "cWebAdmin.h"
-
-
-
-
-
-extern bool report_errors(lua_State* lua, int status);
-
-
-
-
-
-static std::string SafeString( const std::string& a_String )
-{
- std::string RetVal;
- for( unsigned int i = 0; i < a_String.size(); ++i )
- {
- char c = a_String[i];
- if( c == ' ' )
- {
- c = '_';
- }
- RetVal.push_back( c );
- }
- return RetVal;
-}
-
-
-
-
-
-struct cWebPlugin_Lua::sWebPluginTab
-{
- std::string Title;
- std::string SafeTitle;
-
- int Reference;
-};
-
-cWebPlugin_Lua::cWebPlugin_Lua( cPlugin_NewLua* a_Plugin )
- : cWebPlugin( a_Plugin->GetLuaState() )
- , m_Plugin( a_Plugin )
-{
-
-}
-
-cWebPlugin_Lua::~cWebPlugin_Lua()
-{
- for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr )
- {
- delete *itr;
- }
- m_Tabs.clear();
-}
-
-bool cWebPlugin_Lua::AddTab( const char* a_Title, lua_State * a_LuaState, int a_FunctionReference )
-{
- if( a_LuaState != m_Plugin->GetLuaState() )
- {
- LOGERROR("Only allowed to add a tab to a WebPlugin of your own Plugin!");
- return false;
- }
- sWebPluginTab* Tab = new sWebPluginTab();
- Tab->Title = a_Title;
- Tab->SafeTitle = SafeString( a_Title );
-
- Tab->Reference = a_FunctionReference;
-
- m_Tabs.push_back( Tab );
- return true;
-}
-
-std::string cWebPlugin_Lua::HandleRequest( HTTPRequest* a_Request )
-{
- lua_State* LuaState = m_Plugin->GetLuaState();
- std::string RetVal = "";
-
- std::pair< std::string, std::string > TabName = GetTabNameForRequest(a_Request);
- std::string SafeTabName = TabName.second;
- if( SafeTabName.empty() )
- return "";
-
- sWebPluginTab* Tab = 0;
- for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr )
- {
- if( (*itr)->SafeTitle.compare( SafeTabName ) == 0 ) // This is the one! Rawr
- {
- Tab = *itr;
- break;
- }
- }
-
- if( Tab )
- {
- //LOGINFO("1. Stack size: %i", lua_gettop(LuaState) );
- lua_rawgeti( LuaState, LUA_REGISTRYINDEX, Tab->Reference); // same as lua_getref()
-
- //LOGINFO("2. Stack size: %i", lua_gettop(LuaState) );
- // Push HTTPRequest
- tolua_pushusertype( LuaState, a_Request, "HTTPRequest" );
- //LOGINFO("Calling bound function! :D");
- int s = lua_pcall( LuaState, 1, 1, 0);
-
- if ( s != 0 )
- {
- std::string err = lua_tostring(LuaState, -1);
- LOGERROR("-- %s", err.c_str() );
- lua_pop(LuaState, 1);
- LOGINFO("error. Stack size: %i", lua_gettop(LuaState) );
- return err; // Show the error message in the web page, looks cool
- }
-
- if( !lua_isstring( LuaState, -1 ) )
- {
- LOGWARN("WARNING: WebPlugin tab '%s' did not return a string!", Tab->Title.c_str() );
- lua_pop(LuaState, 1); // Pop return value
- return std::string("WARNING: WebPlugin tab '") + Tab->Title + std::string("' did not return a string!");
- }
-
- RetVal += tolua_tostring(LuaState, -1, 0);
- lua_pop(LuaState, 1); // Pop return value
- //LOGINFO("ok. Stack size: %i", lua_gettop(LuaState) );
- }
-
- return RetVal;
-}
-
-void cWebPlugin_Lua::Initialize()
-{
-}
-
-std::pair< std::string, std::string > cWebPlugin_Lua::GetTabNameForRequest( HTTPRequest* a_Request )
-{
- std::pair< std::string, std::string > Names;
- AStringVector Split = StringSplit(a_Request->Path, "/");
-
- if( Split.size() > 1 )
- {
- sWebPluginTab* Tab = 0;
- if( Split.size() > 2 ) // If we got the tab name, show that page
- {
- for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr )
- {
- if( (*itr)->SafeTitle.compare( Split[2] ) == 0 ) // This is the one! Rawr
- {
- Tab = *itr;
- break;
- }
- }
- }
- else // Otherwise show the first tab
- {
- if( m_Tabs.size() > 0 )
- Tab = *m_Tabs.begin();
- }
-
- if( Tab )
- {
- Names.first = Tab->Title;
- Names.second = Tab->SafeTitle;
- }
- }
-
- return Names;
-}
-
-std::list< std::pair<std::string, std::string> > cWebPlugin_Lua::GetTabNames()
-{
- std::list< std::pair< std::string, std::string > > NameList;
- for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr )
- {
- std::pair< std::string, std::string > StringPair;
- StringPair.first = (*itr)->Title;
- StringPair.second = (*itr)->SafeTitle;
- NameList.push_back( StringPair );
- }
- return NameList;
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cWebPlugin_Lua.h" +#include "cPlugin_NewLua.h" + +#include "tolua++.h" +#include "cWebAdmin.h" + + + + + +extern bool report_errors(lua_State* lua, int status); + + + + + +static std::string SafeString( const std::string& a_String ) +{ + std::string RetVal; + for( unsigned int i = 0; i < a_String.size(); ++i ) + { + char c = a_String[i]; + if( c == ' ' ) + { + c = '_'; + } + RetVal.push_back( c ); + } + return RetVal; +} + + + + + +struct cWebPlugin_Lua::sWebPluginTab +{ + std::string Title; + std::string SafeTitle; + + int Reference; +}; + +cWebPlugin_Lua::cWebPlugin_Lua( cPlugin_NewLua* a_Plugin ) + : cWebPlugin( a_Plugin->GetLuaState() ) + , m_Plugin( a_Plugin ) +{ + +} + +cWebPlugin_Lua::~cWebPlugin_Lua() +{ + for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr ) + { + delete *itr; + } + m_Tabs.clear(); +} + +bool cWebPlugin_Lua::AddTab( const char* a_Title, lua_State * a_LuaState, int a_FunctionReference ) +{ + if( a_LuaState != m_Plugin->GetLuaState() ) + { + LOGERROR("Only allowed to add a tab to a WebPlugin of your own Plugin!"); + return false; + } + sWebPluginTab* Tab = new sWebPluginTab(); + Tab->Title = a_Title; + Tab->SafeTitle = SafeString( a_Title ); + + Tab->Reference = a_FunctionReference; + + m_Tabs.push_back( Tab ); + return true; +} + +std::string cWebPlugin_Lua::HandleRequest( HTTPRequest* a_Request ) +{ + lua_State* LuaState = m_Plugin->GetLuaState(); + std::string RetVal = ""; + + std::pair< std::string, std::string > TabName = GetTabNameForRequest(a_Request); + std::string SafeTabName = TabName.second; + if( SafeTabName.empty() ) + return ""; + + sWebPluginTab* Tab = 0; + for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr ) + { + if( (*itr)->SafeTitle.compare( SafeTabName ) == 0 ) // This is the one! Rawr + { + Tab = *itr; + break; + } + } + + if( Tab ) + { + //LOGINFO("1. Stack size: %i", lua_gettop(LuaState) ); + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, Tab->Reference); // same as lua_getref() + + //LOGINFO("2. Stack size: %i", lua_gettop(LuaState) ); + // Push HTTPRequest + tolua_pushusertype( LuaState, a_Request, "HTTPRequest" ); + //LOGINFO("Calling bound function! :D"); + int s = lua_pcall( LuaState, 1, 1, 0); + + if ( s != 0 ) + { + std::string err = lua_tostring(LuaState, -1); + LOGERROR("-- %s", err.c_str() ); + lua_pop(LuaState, 1); + LOGINFO("error. Stack size: %i", lua_gettop(LuaState) ); + return err; // Show the error message in the web page, looks cool + } + + if( !lua_isstring( LuaState, -1 ) ) + { + LOGWARN("WARNING: WebPlugin tab '%s' did not return a string!", Tab->Title.c_str() ); + lua_pop(LuaState, 1); // Pop return value + return std::string("WARNING: WebPlugin tab '") + Tab->Title + std::string("' did not return a string!"); + } + + RetVal += tolua_tostring(LuaState, -1, 0); + lua_pop(LuaState, 1); // Pop return value + //LOGINFO("ok. Stack size: %i", lua_gettop(LuaState) ); + } + + return RetVal; +} + +void cWebPlugin_Lua::Initialize() +{ +} + +std::pair< std::string, std::string > cWebPlugin_Lua::GetTabNameForRequest( HTTPRequest* a_Request ) +{ + std::pair< std::string, std::string > Names; + AStringVector Split = StringSplit(a_Request->Path, "/"); + + if( Split.size() > 1 ) + { + sWebPluginTab* Tab = 0; + if( Split.size() > 2 ) // If we got the tab name, show that page + { + for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr ) + { + if( (*itr)->SafeTitle.compare( Split[2] ) == 0 ) // This is the one! Rawr + { + Tab = *itr; + break; + } + } + } + else // Otherwise show the first tab + { + if( m_Tabs.size() > 0 ) + Tab = *m_Tabs.begin(); + } + + if( Tab ) + { + Names.first = Tab->Title; + Names.second = Tab->SafeTitle; + } + } + + return Names; +} + +std::list< std::pair<std::string, std::string> > cWebPlugin_Lua::GetTabNames() +{ + std::list< std::pair< std::string, std::string > > NameList; + for( TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr ) + { + std::pair< std::string, std::string > StringPair; + StringPair.first = (*itr)->Title; + StringPair.second = (*itr)->SafeTitle; + NameList.push_back( StringPair ); + } + return NameList; }
\ No newline at end of file diff --git a/source/cWebPlugin_Lua.h b/source/cWebPlugin_Lua.h index 0444fb44f..a63ddf323 100644 --- a/source/cWebPlugin_Lua.h +++ b/source/cWebPlugin_Lua.h @@ -1,29 +1,29 @@ -#pragma once
-
-#include "cWebPlugin.h"
-
-class cPlugin_NewLua;
-typedef struct lua_State lua_State;
-
-// a WebPlugin class more specialized for Lua
-class cWebPlugin_Lua : public cWebPlugin //tolua_export
-{ //tolua_export
-public: //tolua_export
- cWebPlugin_Lua( cPlugin_NewLua* a_Plugin );
- virtual ~cWebPlugin_Lua();
-
- bool AddTab( const char* a_Title, lua_State * a_LuaState, int a_FunctionReference ); // >> EXPORTED IN MANUALBINDINGS <<
-
- virtual std::string HandleRequest( HTTPRequest* a_Request );
- virtual void Initialize();
-
- std::pair< std::string, std::string > GetTabNameForRequest( HTTPRequest* a_Request );
-
- std::list< std::pair<std::string, std::string> > GetTabNames();
-private:
- cPlugin_NewLua* m_Plugin;
-
- struct sWebPluginTab;
- typedef std::list< sWebPluginTab* > TabList;
- TabList m_Tabs;
+#pragma once + +#include "cWebPlugin.h" + +class cPlugin_NewLua; +typedef struct lua_State lua_State; + +// a WebPlugin class more specialized for Lua +class cWebPlugin_Lua : public cWebPlugin //tolua_export +{ //tolua_export +public: //tolua_export + cWebPlugin_Lua( cPlugin_NewLua* a_Plugin ); + virtual ~cWebPlugin_Lua(); + + bool AddTab( const char* a_Title, lua_State * a_LuaState, int a_FunctionReference ); // >> EXPORTED IN MANUALBINDINGS << + + virtual std::string HandleRequest( HTTPRequest* a_Request ); + virtual void Initialize(); + + std::pair< std::string, std::string > GetTabNameForRequest( HTTPRequest* a_Request ); + + std::list< std::pair<std::string, std::string> > GetTabNames(); +private: + cPlugin_NewLua* m_Plugin; + + struct sWebPluginTab; + typedef std::list< sWebPluginTab* > TabList; + TabList m_Tabs; }; //tolua_export
\ No newline at end of file diff --git a/source/cWindow.cpp b/source/cWindow.cpp index 8c5d78495..fe029cfd9 100644 --- a/source/cWindow.cpp +++ b/source/cWindow.cpp @@ -1,332 +1,332 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cWindow.h"
-#include "cItem.h"
-#include "cClientHandle.h"
-#include "cPlayer.h"
-#include "cPickup.h"
-#include "cInventory.h"
-#include "cWindowOwner.h"
-
-#include "packets/cPacket_WindowClick.h"
-#include "packets/cPacket_WholeInventory.h"
-#include "packets/cPacket_WindowOpen.h"
-#include "packets/cPacket_WindowClose.h"
-
-
-
-
-
-cWindow::cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible )
- : m_WindowID( 0 )
- , m_WindowType( 0 )
- , m_Owner( a_Owner )
- , m_bInventoryVisible( a_bInventoryVisible )
- , m_NumSlots( 0 )
- , m_Slots( 0 )
- , m_DraggingItem( 0 )
- , m_IsDestroyed(false)
-{
- LOGD("Created a window at %p", this);
- if( !m_bInventoryVisible ) m_DraggingItem = new cItem();
-}
-
-
-
-
-
-cWindow::~cWindow()
-{
- LOGD("Deleting a window at %p", this);
- if( !m_bInventoryVisible && m_DraggingItem )
- {
- delete m_DraggingItem;
- m_DraggingItem = 0;
- }
- LOGD("Deleted a window at %p", this);
-}
-
-
-
-
-
-cItem* cWindow::GetSlot( int a_Slot )
-{
- if(a_Slot > -1 && a_Slot < m_NumSlots)
- {
- return (m_Slots + a_Slot);
- }
- return 0;
-}
-
-
-
-
-
-cItem* cWindow::GetDraggingItem( cPlayer * a_Player /* = 0 */ )
-{
- if( m_bInventoryVisible && a_Player )
- {
- cWindow* Window = a_Player->GetInventory().GetWindow();
- if( Window )
- {
- return Window->GetDraggingItem();
- }
- }
- return m_DraggingItem;
-}
-
-
-
-
-
-void cWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player )
-{
- if( a_ClickPacket->m_WindowID != m_WindowID )
- {
- LOG("WRONG WINDOW ID! (exp %d, got %d)", m_WindowID, a_ClickPacket->m_WindowID);
- return;
- }
-
- if( m_bInventoryVisible )
- {
- cWindow* Window = a_Player.GetInventory().GetWindow();
- if( Window )
- {
- m_DraggingItem = Window->GetDraggingItem();
- }
- }
- bool bAsync = false;
- if( a_ClickPacket->m_SlotNum == -999 ) // Outside window click
- {
- if( a_ClickPacket->m_RightMouse )
- a_Player.TossItem( true );
- else
- a_Player.TossItem( true, m_DraggingItem->m_ItemCount );
- }
- else if( GetSlot( a_ClickPacket->m_SlotNum ) != 0 )
- {
- cItem* Item = GetSlot( a_ClickPacket->m_SlotNum );
- if( a_ClickPacket->m_ItemID != Item->m_ItemID
- || a_ClickPacket->m_ItemCount != Item->m_ItemCount
- || a_ClickPacket->m_ItemUses != Item->m_ItemHealth )
- {
- if( !((a_ClickPacket->m_ItemID == -1 || a_ClickPacket->m_ItemID == 0) && (Item->m_ItemID == -1 || Item->m_ItemID == 0 )) )
- {
- LOGD("My ID: %i Their ID: %i", Item->m_ItemID, a_ClickPacket->m_ItemID );
- LOGD("My Count: %i Their Count: %i", Item->m_ItemCount, a_ClickPacket->m_ItemCount );
- LOGD("My Uses: %i Their Uses: %i", Item->m_ItemHealth, a_ClickPacket->m_ItemUses );
- bAsync = true;
- }
- }
- }
- if( m_DraggingItem && a_ClickPacket->m_SlotNum > -1 && a_ClickPacket->m_SlotNum < m_NumSlots )
- {
- if( a_ClickPacket->m_RightMouse == 0 )
- {
- if( !m_DraggingItem->Equals( m_Slots[a_ClickPacket->m_SlotNum] ) )
- {
- cItem tmp( *m_DraggingItem );
- *m_DraggingItem = m_Slots[a_ClickPacket->m_SlotNum];
- m_Slots[a_ClickPacket->m_SlotNum] = tmp; // Switch contents
- }
- else
- {
- int FreeSlots = 64 - m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount;
- int Filling = (FreeSlots > m_DraggingItem->m_ItemCount) ? m_DraggingItem->m_ItemCount : FreeSlots;
- m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount += (char)Filling;
- m_DraggingItem->m_ItemCount -= (char)Filling;
- if( m_DraggingItem->m_ItemCount <= 0 )
- m_DraggingItem->Empty();
- }
- }
- else // Right clicked
- {
- if( m_DraggingItem->m_ItemID <= 0 ) // Empty?
- {
- m_DraggingItem->m_ItemCount = (char)(((float)m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount)/2.f + 0.5f);
- m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount -= m_DraggingItem->m_ItemCount;
- m_DraggingItem->m_ItemID = m_Slots[a_ClickPacket->m_SlotNum].m_ItemID;
- m_DraggingItem->m_ItemHealth = m_Slots[a_ClickPacket->m_SlotNum].m_ItemHealth;
-
- if( m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount <= 0 )
- {
- m_Slots[a_ClickPacket->m_SlotNum].Empty();
- }
- }
- else if( m_Slots[a_ClickPacket->m_SlotNum].m_ItemID <= 0 || m_DraggingItem->Equals( m_Slots[a_ClickPacket->m_SlotNum] ) )
- { // Drop one item in slot
- if( m_DraggingItem->m_ItemCount > 0 && m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount < 64 )
- {
- m_Slots[a_ClickPacket->m_SlotNum].m_ItemID = m_DraggingItem->m_ItemID;
- m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount++;
- m_Slots[a_ClickPacket->m_SlotNum].m_ItemHealth = m_DraggingItem->m_ItemHealth;
- m_DraggingItem->m_ItemCount--;
- }
- if( m_DraggingItem->m_ItemCount <= 0 )
- {
- m_DraggingItem->Empty();
- }
- }
- else if( !m_DraggingItem->Equals( m_Slots[a_ClickPacket->m_SlotNum]) ) // Swap contents
- {
- cItem tmp( *m_DraggingItem );
- *m_DraggingItem = m_Slots[a_ClickPacket->m_SlotNum];
- m_Slots[a_ClickPacket->m_SlotNum] = tmp; // Switch contents
- }
- }
- if( bAsync )
- {
- LOG("Window is not synchonous with client. Sending whole window. ID: %i", m_WindowID);
- for( std::list< cPlayer* >::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr )
- {
- SendWholeWindow( (*itr)->GetClientHandle() );
- }
- if( m_bInventoryVisible || m_OpenedBy.size() == 0 )
- {
- a_Player.GetInventory().SendWholeInventory( a_Player.GetClientHandle() );
- }
- }
- }
- else if( m_bInventoryVisible ) // Click in player inventory
- {
- a_ClickPacket->m_WindowID = 0;
- a_ClickPacket->m_SlotNum -= (short)(m_NumSlots - 9);
- cWindow* Window = a_Player.GetInventory().GetWindow();
- if( Window )
- {
- Window->Clicked( a_ClickPacket, a_Player );
- }
- }
- if (m_DraggingItem != NULL)
- {
- LOGD("Dragging: %i", m_DraggingItem->m_ItemCount );
- }
-}
-
-
-
-
-
-void cWindow::Open( cPlayer & a_Player )
-{
- {
- cCSLock Lock(m_CS);
- // If player is already in OpenedBy remove player first
- m_OpenedBy.remove( &a_Player );
- // Then add player
- m_OpenedBy.push_back( &a_Player );
- }
-
- cPacket_WindowOpen WindowOpen;
- WindowOpen.m_WindowID = (char)m_WindowID;
- WindowOpen.m_InventoryType = (char)m_WindowType;
- WindowOpen.m_WindowTitle = m_WindowTitle;
- WindowOpen.m_NumSlots = (char)m_NumSlots;
- a_Player.GetClientHandle()->Send( WindowOpen );
-}
-
-
-
-
-
-void cWindow::Close( cPlayer & a_Player )
-{
- //Checks wheather the player is still holding an item
- if(m_DraggingItem && m_DraggingItem->m_ItemCount > 0)
- {
- LOG("Player holds item! Dropping it...");
- a_Player.TossItem( true, m_DraggingItem->m_ItemCount );
- }
-
- cPacket_WindowClose WindowClose;
- WindowClose.m_Close = (char)m_WindowID;
- cClientHandle * ClientHandle = a_Player.GetClientHandle();
- if ( ClientHandle != NULL)
- {
- ClientHandle->Send( WindowClose );
- }
-
- {
- cCSLock Lock(m_CS);
- m_OpenedBy.remove( &a_Player );
- if( m_OpenedBy.size() == 0 )
- {
- Destroy();
- }
- }
- if (m_IsDestroyed)
- {
- delete this;
- }
-}
-
-
-
-
-
-void cWindow::OwnerDestroyed()
-{
- m_Owner = 0;
- while( m_OpenedBy.size() > 1 )
- {
- (*m_OpenedBy.begin() )->CloseWindow((char)GetWindowType());
- }
- (*m_OpenedBy.begin() )->CloseWindow((char)GetWindowType());
-}
-
-
-
-
-
-void cWindow::Destroy()
-{
- LOGD("Destroying window %p (type %d)", this, m_WindowType);
- if (m_Owner != NULL)
- {
- m_Owner->CloseWindow();
- m_Owner = NULL;
- }
- m_IsDestroyed = true;
-}
-
-
-
-
-
-void cWindow::SendWholeWindow( cClientHandle* a_Client )
-{
- cPacket_WholeInventory Inventory( this );
- a_Client->Send( Inventory );
-}
-
-
-
-
-
-void cWindow::BroadcastWholeWindow(void)
-{
- cCSLock Lock(m_CS);
- for (cPlayerList::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr)
- {
- SendWholeWindow((*itr)->GetClientHandle());
- } // for itr - m_OpenedBy[]
-}
-
-
-
-
-
-void cWindow::Broadcast(const cPacket & a_Packet)
-{
- cCSLock Lock(m_CS);
- for (cPlayerList::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr)
- {
- (*itr)->GetClientHandle()->Send(a_Packet);
- } // for itr - m_OpenedBy[]
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cWindow.h" +#include "cItem.h" +#include "cClientHandle.h" +#include "cPlayer.h" +#include "cPickup.h" +#include "cInventory.h" +#include "cWindowOwner.h" + +#include "packets/cPacket_WindowClick.h" +#include "packets/cPacket_WholeInventory.h" +#include "packets/cPacket_WindowOpen.h" +#include "packets/cPacket_WindowClose.h" + + + + + +cWindow::cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible ) + : m_WindowID( 0 ) + , m_WindowType( 0 ) + , m_Owner( a_Owner ) + , m_bInventoryVisible( a_bInventoryVisible ) + , m_NumSlots( 0 ) + , m_Slots( 0 ) + , m_DraggingItem( 0 ) + , m_IsDestroyed(false) +{ + LOGD("Created a window at %p", this); + if( !m_bInventoryVisible ) m_DraggingItem = new cItem(); +} + + + + + +cWindow::~cWindow() +{ + LOGD("Deleting a window at %p", this); + if( !m_bInventoryVisible && m_DraggingItem ) + { + delete m_DraggingItem; + m_DraggingItem = 0; + } + LOGD("Deleted a window at %p", this); +} + + + + + +cItem* cWindow::GetSlot( int a_Slot ) +{ + if(a_Slot > -1 && a_Slot < m_NumSlots) + { + return (m_Slots + a_Slot); + } + return 0; +} + + + + + +cItem* cWindow::GetDraggingItem( cPlayer * a_Player /* = 0 */ ) +{ + if( m_bInventoryVisible && a_Player ) + { + cWindow* Window = a_Player->GetInventory().GetWindow(); + if( Window ) + { + return Window->GetDraggingItem(); + } + } + return m_DraggingItem; +} + + + + + +void cWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ) +{ + if( a_ClickPacket->m_WindowID != m_WindowID ) + { + LOG("WRONG WINDOW ID! (exp %d, got %d)", m_WindowID, a_ClickPacket->m_WindowID); + return; + } + + if( m_bInventoryVisible ) + { + cWindow* Window = a_Player.GetInventory().GetWindow(); + if( Window ) + { + m_DraggingItem = Window->GetDraggingItem(); + } + } + bool bAsync = false; + if( a_ClickPacket->m_SlotNum == -999 ) // Outside window click + { + if( a_ClickPacket->m_RightMouse ) + a_Player.TossItem( true ); + else + a_Player.TossItem( true, m_DraggingItem->m_ItemCount ); + } + else if( GetSlot( a_ClickPacket->m_SlotNum ) != 0 ) + { + cItem* Item = GetSlot( a_ClickPacket->m_SlotNum ); + if( a_ClickPacket->m_ItemID != Item->m_ItemID + || a_ClickPacket->m_ItemCount != Item->m_ItemCount + || a_ClickPacket->m_ItemUses != Item->m_ItemHealth ) + { + if( !((a_ClickPacket->m_ItemID == -1 || a_ClickPacket->m_ItemID == 0) && (Item->m_ItemID == -1 || Item->m_ItemID == 0 )) ) + { + LOGD("My ID: %i Their ID: %i", Item->m_ItemID, a_ClickPacket->m_ItemID ); + LOGD("My Count: %i Their Count: %i", Item->m_ItemCount, a_ClickPacket->m_ItemCount ); + LOGD("My Uses: %i Their Uses: %i", Item->m_ItemHealth, a_ClickPacket->m_ItemUses ); + bAsync = true; + } + } + } + if( m_DraggingItem && a_ClickPacket->m_SlotNum > -1 && a_ClickPacket->m_SlotNum < m_NumSlots ) + { + if( a_ClickPacket->m_RightMouse == 0 ) + { + if( !m_DraggingItem->Equals( m_Slots[a_ClickPacket->m_SlotNum] ) ) + { + cItem tmp( *m_DraggingItem ); + *m_DraggingItem = m_Slots[a_ClickPacket->m_SlotNum]; + m_Slots[a_ClickPacket->m_SlotNum] = tmp; // Switch contents + } + else + { + int FreeSlots = 64 - m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount; + int Filling = (FreeSlots > m_DraggingItem->m_ItemCount) ? m_DraggingItem->m_ItemCount : FreeSlots; + m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount += (char)Filling; + m_DraggingItem->m_ItemCount -= (char)Filling; + if( m_DraggingItem->m_ItemCount <= 0 ) + m_DraggingItem->Empty(); + } + } + else // Right clicked + { + if( m_DraggingItem->m_ItemID <= 0 ) // Empty? + { + m_DraggingItem->m_ItemCount = (char)(((float)m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount)/2.f + 0.5f); + m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount -= m_DraggingItem->m_ItemCount; + m_DraggingItem->m_ItemID = m_Slots[a_ClickPacket->m_SlotNum].m_ItemID; + m_DraggingItem->m_ItemHealth = m_Slots[a_ClickPacket->m_SlotNum].m_ItemHealth; + + if( m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount <= 0 ) + { + m_Slots[a_ClickPacket->m_SlotNum].Empty(); + } + } + else if( m_Slots[a_ClickPacket->m_SlotNum].m_ItemID <= 0 || m_DraggingItem->Equals( m_Slots[a_ClickPacket->m_SlotNum] ) ) + { // Drop one item in slot + if( m_DraggingItem->m_ItemCount > 0 && m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount < 64 ) + { + m_Slots[a_ClickPacket->m_SlotNum].m_ItemID = m_DraggingItem->m_ItemID; + m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount++; + m_Slots[a_ClickPacket->m_SlotNum].m_ItemHealth = m_DraggingItem->m_ItemHealth; + m_DraggingItem->m_ItemCount--; + } + if( m_DraggingItem->m_ItemCount <= 0 ) + { + m_DraggingItem->Empty(); + } + } + else if( !m_DraggingItem->Equals( m_Slots[a_ClickPacket->m_SlotNum]) ) // Swap contents + { + cItem tmp( *m_DraggingItem ); + *m_DraggingItem = m_Slots[a_ClickPacket->m_SlotNum]; + m_Slots[a_ClickPacket->m_SlotNum] = tmp; // Switch contents + } + } + if( bAsync ) + { + LOG("Window is not synchonous with client. Sending whole window. ID: %i", m_WindowID); + for( std::list< cPlayer* >::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr ) + { + SendWholeWindow( (*itr)->GetClientHandle() ); + } + if( m_bInventoryVisible || m_OpenedBy.size() == 0 ) + { + a_Player.GetInventory().SendWholeInventory( a_Player.GetClientHandle() ); + } + } + } + else if( m_bInventoryVisible ) // Click in player inventory + { + a_ClickPacket->m_WindowID = 0; + a_ClickPacket->m_SlotNum -= (short)(m_NumSlots - 9); + cWindow* Window = a_Player.GetInventory().GetWindow(); + if( Window ) + { + Window->Clicked( a_ClickPacket, a_Player ); + } + } + if (m_DraggingItem != NULL) + { + LOGD("Dragging: %i", m_DraggingItem->m_ItemCount ); + } +} + + + + + +void cWindow::Open( cPlayer & a_Player ) +{ + { + cCSLock Lock(m_CS); + // If player is already in OpenedBy remove player first + m_OpenedBy.remove( &a_Player ); + // Then add player + m_OpenedBy.push_back( &a_Player ); + } + + cPacket_WindowOpen WindowOpen; + WindowOpen.m_WindowID = (char)m_WindowID; + WindowOpen.m_InventoryType = (char)m_WindowType; + WindowOpen.m_WindowTitle = m_WindowTitle; + WindowOpen.m_NumSlots = (char)m_NumSlots; + a_Player.GetClientHandle()->Send( WindowOpen ); +} + + + + + +void cWindow::Close( cPlayer & a_Player ) +{ + //Checks wheather the player is still holding an item + if(m_DraggingItem && m_DraggingItem->m_ItemCount > 0) + { + LOG("Player holds item! Dropping it..."); + a_Player.TossItem( true, m_DraggingItem->m_ItemCount ); + } + + cPacket_WindowClose WindowClose; + WindowClose.m_Close = (char)m_WindowID; + cClientHandle * ClientHandle = a_Player.GetClientHandle(); + if ( ClientHandle != NULL) + { + ClientHandle->Send( WindowClose ); + } + + { + cCSLock Lock(m_CS); + m_OpenedBy.remove( &a_Player ); + if( m_OpenedBy.size() == 0 ) + { + Destroy(); + } + } + if (m_IsDestroyed) + { + delete this; + } +} + + + + + +void cWindow::OwnerDestroyed() +{ + m_Owner = 0; + while( m_OpenedBy.size() > 1 ) + { + (*m_OpenedBy.begin() )->CloseWindow((char)GetWindowType()); + } + (*m_OpenedBy.begin() )->CloseWindow((char)GetWindowType()); +} + + + + + +void cWindow::Destroy() +{ + LOGD("Destroying window %p (type %d)", this, m_WindowType); + if (m_Owner != NULL) + { + m_Owner->CloseWindow(); + m_Owner = NULL; + } + m_IsDestroyed = true; +} + + + + + +void cWindow::SendWholeWindow( cClientHandle* a_Client ) +{ + cPacket_WholeInventory Inventory( this ); + a_Client->Send( Inventory ); +} + + + + + +void cWindow::BroadcastWholeWindow(void) +{ + cCSLock Lock(m_CS); + for (cPlayerList::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr) + { + SendWholeWindow((*itr)->GetClientHandle()); + } // for itr - m_OpenedBy[] +} + + + + + +void cWindow::Broadcast(const cPacket & a_Packet) +{ + cCSLock Lock(m_CS); + for (cPlayerList::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr) + { + (*itr)->GetClientHandle()->Send(a_Packet); + } // for itr - m_OpenedBy[] +} + + + + diff --git a/source/cWindow.h b/source/cWindow.h index d9f4226a6..7d31d71e3 100644 --- a/source/cWindow.h +++ b/source/cWindow.h @@ -1,86 +1,86 @@ -#pragma once
-
-
-class cPacket_WindowClick;
-class cPlayer;
-class cItem;
-class cWindowOwner;
-class cClientHandle;
-class cPacket;
-
-typedef std::list<cPlayer *> cPlayerList;
-
-
-
-
-
-class cWindow
-{
-public:
- cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible );
- ~cWindow();
-
- int GetWindowID() { return m_WindowID; }
- void SetWindowID( int a_WindowID ) { m_WindowID = a_WindowID; }
-
- enum WindowType {
- Chest,
- Workbench,
- Furnace,
- Dispenser,
- Enchantment,
- Brewery
- };
-
- int GetWindowType() { return m_WindowType; }
- void SetWindowType( int a_WindowType ) { m_WindowType = a_WindowType; }
-
- cItem* GetSlots() { return m_Slots; }
- int GetNumSlots() { return m_NumSlots; }
-
- cItem* GetSlot( int a_Slot );
-
- cItem* GetDraggingItem( cPlayer * a_Player = 0 );
-
- // a_Slots is an array of slots of size a_NumSlots
- void SetSlots(cItem* a_Slots, int a_NumSlots) { m_Slots = a_Slots; m_NumSlots = a_NumSlots; }
-
- bool IsInventoryVisible() { return m_bInventoryVisible; }
- void SetInventoryVisible( bool a_bVisible ) { m_bInventoryVisible = a_bVisible; }
-
- virtual void Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player );
-
- virtual void Open( cPlayer & a_Player );
- virtual void Close( cPlayer & a_Player );
-
- cWindowOwner* GetOwner() { return m_Owner; }
- void SetOwner( cWindowOwner* a_Owner ) { m_Owner = a_Owner; }
-
- void SendWholeWindow( cClientHandle* a_Client );
- void BroadcastWholeWindow(void);
- void Broadcast(const cPacket & a_Packet);
-
- const AString & GetWindowTitle() const { return m_WindowTitle; }
- void SetWindowTitle( const std::string & a_WindowTitle ) { m_WindowTitle = a_WindowTitle; }
-
- void OwnerDestroyed();
-
-private:
-
- void Destroy();
-
- int m_WindowID;
- int m_WindowType;
- AString m_WindowTitle;
-
- cWindowOwner * m_Owner;
-
- cCriticalSection m_CS;
- cPlayerList m_OpenedBy;
-
- bool m_bInventoryVisible;
- int m_NumSlots;
- cItem * m_Slots;
- cItem * m_DraggingItem;
- bool m_IsDestroyed;
+#pragma once + + +class cPacket_WindowClick; +class cPlayer; +class cItem; +class cWindowOwner; +class cClientHandle; +class cPacket; + +typedef std::list<cPlayer *> cPlayerList; + + + + + +class cWindow +{ +public: + cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible ); + ~cWindow(); + + int GetWindowID() { return m_WindowID; } + void SetWindowID( int a_WindowID ) { m_WindowID = a_WindowID; } + + enum WindowType { + Chest, + Workbench, + Furnace, + Dispenser, + Enchantment, + Brewery + }; + + int GetWindowType() { return m_WindowType; } + void SetWindowType( int a_WindowType ) { m_WindowType = a_WindowType; } + + cItem* GetSlots() { return m_Slots; } + int GetNumSlots() { return m_NumSlots; } + + cItem* GetSlot( int a_Slot ); + + cItem* GetDraggingItem( cPlayer * a_Player = 0 ); + + // a_Slots is an array of slots of size a_NumSlots + void SetSlots(cItem* a_Slots, int a_NumSlots) { m_Slots = a_Slots; m_NumSlots = a_NumSlots; } + + bool IsInventoryVisible() { return m_bInventoryVisible; } + void SetInventoryVisible( bool a_bVisible ) { m_bInventoryVisible = a_bVisible; } + + virtual void Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ); + + virtual void Open( cPlayer & a_Player ); + virtual void Close( cPlayer & a_Player ); + + cWindowOwner* GetOwner() { return m_Owner; } + void SetOwner( cWindowOwner* a_Owner ) { m_Owner = a_Owner; } + + void SendWholeWindow( cClientHandle* a_Client ); + void BroadcastWholeWindow(void); + void Broadcast(const cPacket & a_Packet); + + const AString & GetWindowTitle() const { return m_WindowTitle; } + void SetWindowTitle( const std::string & a_WindowTitle ) { m_WindowTitle = a_WindowTitle; } + + void OwnerDestroyed(); + +private: + + void Destroy(); + + int m_WindowID; + int m_WindowType; + AString m_WindowTitle; + + cWindowOwner * m_Owner; + + cCriticalSection m_CS; + cPlayerList m_OpenedBy; + + bool m_bInventoryVisible; + int m_NumSlots; + cItem * m_Slots; + cItem * m_DraggingItem; + bool m_IsDestroyed; };
\ No newline at end of file diff --git a/source/cWindowOwner.h b/source/cWindowOwner.h index 71691aaed..3a1797f74 100644 --- a/source/cWindowOwner.h +++ b/source/cWindowOwner.h @@ -1,29 +1,29 @@ -#pragma once
-
-
-class cWindow;
-class cBlockEntity;
-
-
-
-
-
-class cWindowOwner
-{
-public:
- cWindowOwner() : m_Window( NULL ) {}
- void CloseWindow() { m_Window = NULL; }
- void OpenWindow( cWindow* a_Window ) { m_Window = a_Window; }
-
- cWindow* GetWindow() { return m_Window; }
-
- void SetEntity(cBlockEntity *a_Entity) { m_Entity = a_Entity; }
- cBlockEntity *GetEntity() { return m_Entity; }
-private:
- cWindow* m_Window;
- cBlockEntity *m_Entity;
-};
-
-
-
-
+#pragma once + + +class cWindow; +class cBlockEntity; + + + + + +class cWindowOwner +{ +public: + cWindowOwner() : m_Window( NULL ) {} + void CloseWindow() { m_Window = NULL; } + void OpenWindow( cWindow* a_Window ) { m_Window = a_Window; } + + cWindow* GetWindow() { return m_Window; } + + void SetEntity(cBlockEntity *a_Entity) { m_Entity = a_Entity; } + cBlockEntity *GetEntity() { return m_Entity; } +private: + cWindow* m_Window; + cBlockEntity *m_Entity; +}; + + + + diff --git a/source/cWolf.cpp b/source/cWolf.cpp index 8226b06ac..fa693bcbd 100644 --- a/source/cWolf.cpp +++ b/source/cWolf.cpp @@ -1,20 +1,20 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cWolf.h"
-
-cWolf::cWolf()
-{
- m_MobType = 95;
- GetMonsterConfig("Wolf");
-}
-
-cWolf::~cWolf()
-{
-}
-
-bool cWolf::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cWolf" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cWolf.h" + +cWolf::cWolf() +{ + m_MobType = 95; + GetMonsterConfig("Wolf"); +} + +cWolf::~cWolf() +{ +} + +bool cWolf::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cWolf" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} diff --git a/source/cWolf.h b/source/cWolf.h index b3bca1e47..174968cdb 100644 --- a/source/cWolf.h +++ b/source/cWolf.h @@ -1,12 +1,12 @@ -#pragma once
-
-#include "cPassiveAggressiveMonster.h"
-
-class cWolf : public cPassiveAggressiveMonster
-{
-public:
- cWolf();
- ~cWolf();
-
- virtual bool IsA( const char* a_EntityType );
-};
+#pragma once + +#include "cPassiveAggressiveMonster.h" + +class cWolf : public cPassiveAggressiveMonster +{ +public: + cWolf(); + ~cWolf(); + + virtual bool IsA( const char* a_EntityType ); +}; diff --git a/source/cWorld.cpp b/source/cWorld.cpp index 27f85bf90..b5ed59ccb 100644 --- a/source/cWorld.cpp +++ b/source/cWorld.cpp @@ -1,1845 +1,1845 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "BlockID.h"
-#include "cWorld.h"
-#include "cRedstone.h"
-#include "ChunkDef.h"
-#include "cClientHandle.h"
-#include "cPickup.h"
-#include "cBlockToPickup.h"
-#include "cPlayer.h"
-#include "cServer.h"
-#include "cItem.h"
-#include "cRoot.h"
-#include "../iniFile/iniFile.h"
-#include "cChunkMap.h"
-#include "cSimulatorManager.h"
-#include "cWaterSimulator.h"
-#include "cLavaSimulator.h"
-#include "cFireSimulator.h"
-#include "cSandSimulator.h"
-#include "cRedstoneSimulator.h"
-#include "cChicken.h"
-#include "cSpider.h"
-#include "cCow.h" //cow
-#include "cSquid.h" //Squid
-#include "cWolf.h" //wolf
-#include "cSlime.h" //slime
-#include "cSkeleton.h" //Skeleton
-#include "cSilverfish.h" //Silverfish
-#include "cPig.h" //pig
-#include "cSheep.h" //sheep
-#include "cZombie.h" //zombie
-#include "cEnderman.h" //enderman
-#include "cCreeper.h" //creeper
-#include "cCavespider.h" //cavespider
-#include "cGhast.h" //Ghast
-#include "cZombiepigman.h" //Zombiepigman
-#include "cMakeDir.h"
-#include "cChunkGenerator.h"
-#include "MersenneTwister.h"
-#include "cTracer.h"
-#include "Trees.h"
-#include "cPluginManager.h"
-
-
-#include "packets/cPacket_TimeUpdate.h"
-#include "packets/cPacket_NewInvalidState.h"
-#include "packets/cPacket_Thunderbolt.h"
-
-#include "Vector3d.h"
-
-#include <time.h>
-
-#include "tolua++.h"
-
-#ifndef _WIN32
- #include <stdlib.h>
-#endif
-
-
-
-
-
-/// Up to this many m_SpreadQueue elements are handled each world tick
-const int MAX_LIGHTING_SPREAD_PER_TICK = 10;
-
-
-
-
-
-float cWorld::m_Time = 0.f;
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cWorldLoadProgress:
-
-/// A simple thread that displays the progress of world loading / saving in cWorld::InitializeSpawn()
-class cWorldLoadProgress :
- public cIsThread
-{
-public:
- cWorldLoadProgress(cWorld * a_World) :
- cIsThread("cWorldLoadProgress"),
- m_World(a_World)
- {
- Start();
- }
-
- void Stop(void)
- {
- m_ShouldTerminate = true;
- Wait();
- }
-
-protected:
-
- cWorld * m_World;
-
- virtual void Execute(void) override
- {
- for (;;)
- {
- LOG("%d chunks to load, %d chunks to generate",
- m_World->GetStorage().GetLoadQueueLength(),
- m_World->GetGenerator().GetQueueLength()
- );
-
- // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish
- for (int i = 0; i < 20; i++)
- {
- cSleep::MilliSleep(100);
- if (m_ShouldTerminate)
- {
- return;
- }
- }
- } // for (-ever)
- }
-
-} ;
-
-
-
-
-
-/// A simple thread that displays the progress of world lighting in cWorld::InitializeSpawn()
-class cWorldLightingProgress :
- public cIsThread
-{
-public:
- cWorldLightingProgress(cLightingThread * a_Lighting) :
- cIsThread("cWorldLightingProgress"),
- m_Lighting(a_Lighting)
- {
- Start();
- }
-
- void Stop(void)
- {
- m_ShouldTerminate = true;
- Wait();
- }
-
-protected:
-
- cLightingThread * m_Lighting;
-
- virtual void Execute(void) override
- {
- for (;;)
- {
- LOG("%d chunks remaining to light", m_Lighting->GetQueueLength()
- );
-
- // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish
- for (int i = 0; i < 20; i++)
- {
- cSleep::MilliSleep(100);
- if (m_ShouldTerminate)
- {
- return;
- }
- }
- } // for (-ever)
- }
-
-} ;
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cWorld:
-
-cWorld* cWorld::GetWorld()
-{
- LOGWARN("WARNING: Using deprecated function cWorld::GetWorld() use cRoot::Get()->GetDefaultWorld() instead!");
- return cRoot::Get()->GetDefaultWorld();
-}
-
-
-
-
-
-cWorld::~cWorld()
-{
- {
- cCSLock Lock(m_CSEntities);
- while( m_AllEntities.begin() != m_AllEntities.end() )
- {
- cEntity* Entity = *m_AllEntities.begin();
- m_AllEntities.remove( Entity );
- if ( !Entity->IsDestroyed() )
- {
- Entity->Destroy();
- }
- delete Entity;
- }
- }
-
- delete m_SimulatorManager;
- delete m_SandSimulator;
- delete m_WaterSimulator;
- delete m_LavaSimulator;
- delete m_FireSimulator;
- delete m_RedstoneSimulator;
-
- m_Generator.Stop();
- m_ChunkSender.Stop();
-
- UnloadUnusedChunks();
-
- m_Storage.WaitForFinish();
-
- delete m_ChunkMap;
-}
-
-
-
-
-
-cWorld::cWorld( const AString & a_WorldName )
- : m_SpawnMonsterTime( 0.f )
- , m_RSList ( 0 )
- , m_Weather ( eWeather_Sunny )
-{
- LOG("cWorld::cWorld(%s)", a_WorldName.c_str());
- m_WorldName = a_WorldName;
- m_IniFileName = m_WorldName + "/world.ini";
-
- cMakeDir::MakeDir(m_WorldName.c_str());
-
- MTRand r1;
- m_SpawnX = (double)((r1.randInt() % 1000) - 500);
- m_SpawnY = cChunkDef::Height;
- m_SpawnZ = (double)((r1.randInt() % 1000) - 500);
- m_GameMode = eGameMode_Creative;
-
- AString StorageSchema("Default");
-
- cIniFile IniFile(m_IniFileName);
- IniFile.ReadFile();
- m_SpawnX = IniFile.GetValueSetF("SpawnPosition", "X", m_SpawnX);
- m_SpawnY = IniFile.GetValueSetF("SpawnPosition", "Y", m_SpawnY);
- m_SpawnZ = IniFile.GetValueSetF("SpawnPosition", "Z", m_SpawnZ);
- StorageSchema = IniFile.GetValueSet ("Storage", "Schema", StorageSchema);
- m_MaxCactusHeight = IniFile.GetValueSetI("Plants", "MaxCactusHeight", 3);
- m_MaxSugarcaneHeight = IniFile.GetValueSetI("Plants", "MaxSugarcaneHeight", 3);
- m_IsCropsBonemealable = IniFile.GetValueSetB("Plants", "IsCropsBonemealable", true);
- m_IsGrassBonemealable = IniFile.GetValueSetB("Plants", "IsGrassBonemealable", true);
- m_IsSaplingBonemealable = IniFile.GetValueSetB("Plants", "IsSaplingBonemealable", true);
- m_IsMelonStemBonemealable = IniFile.GetValueSetB("Plants", "IsMelonStemBonemealable", true);
- m_IsMelonBonemealable = IniFile.GetValueSetB("Plants", "IsMelonBonemealable", false);
- m_IsPumpkinStemBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinStemBonemealable", true);
- m_IsPumpkinBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinBonemealable", false);
- m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false);
- m_IsCactusBonemealable = IniFile.GetValueSetB("Plants", "IsCactusBonemealable", false);
-
- m_GameMode = (eGameMode)IniFile.GetValueSetI("GameMode", "GameMode", m_GameMode );
-
- if (!IniFile.WriteFile())
- {
- LOG("WARNING: Could not write to %s", m_IniFileName.c_str());
- }
-
- m_Lighting.Start(this);
- m_Storage.Start(this, StorageSchema);
- m_Generator.Start(this, IniFile);
-
- m_bAnimals = true;
- m_SpawnMonsterRate = 10;
- cIniFile IniFile2("settings.ini");
- if( IniFile2.ReadFile() )
- {
- m_bAnimals = IniFile2.GetValueB("Monsters", "AnimalsOn", true );
- m_SpawnMonsterRate = (float)IniFile2.GetValueF("Monsters", "AnimalSpawnInterval", 10);
- SetMaxPlayers(IniFile2.GetValueI("Server", "MaxPlayers", 9001));
- m_Description = IniFile2.GetValue("Server", "Description", "MCServer! - It's OVER 9000!").c_str();
- }
-
- m_ChunkMap = new cChunkMap(this );
-
- m_ChunkSender.Start(this);
-
- m_Time = 0;
- m_WorldTimeFraction = 0.f;
- m_WorldTime = 0;
- m_LastSave = 0;
- m_LastUnload = 0;
-
- //Simulators:
- m_WaterSimulator = new cWaterSimulator( this );
- m_LavaSimulator = new cLavaSimulator( this );
- m_SandSimulator = new cSandSimulator(this);
- m_FireSimulator = new cFireSimulator(this);
- m_RedstoneSimulator = new cRedstoneSimulator(this);
-
- m_SimulatorManager = new cSimulatorManager();
- m_SimulatorManager->RegisterSimulator(m_WaterSimulator, 6);
- m_SimulatorManager->RegisterSimulator(m_LavaSimulator, 12);
- m_SimulatorManager->RegisterSimulator(m_SandSimulator, 1);
- m_SimulatorManager->RegisterSimulator(m_FireSimulator, 10);
- m_SimulatorManager->RegisterSimulator(m_RedstoneSimulator, 1);
-}
-
-
-
-
-
-void cWorld::SetWeather( eWeather a_Weather )
-{
- switch( a_Weather )
- {
- case eWeather_Sunny:
- {
- m_Weather = a_Weather;
- cPacket_NewInvalidState WeatherPacket;
- WeatherPacket.m_Reason = 2; //stop rain
- Broadcast ( WeatherPacket );
- }
- break;
- case eWeather_Rain:
- {
- m_Weather = a_Weather;
- cPacket_NewInvalidState WeatherPacket;
- WeatherPacket.m_Reason = 1; //begin rain
- Broadcast ( WeatherPacket );
- }
- break;
- case eWeather_ThunderStorm:
- {
- m_Weather = a_Weather;
- cPacket_NewInvalidState WeatherPacket;
- WeatherPacket.m_Reason = 1; //begin rain
- Broadcast ( WeatherPacket );
- CastThunderbolt ( 0, 0, 0 ); //start thunderstorm with a lightning strike at 0, 0, 0. >:D
- }
- break;
- default:
- LOGWARN("Trying to set unknown weather %d", a_Weather );
- break;
- }
-}
-
-
-
-
-
-void cWorld::CastThunderbolt ( int a_X, int a_Y, int a_Z )
-{
- cPacket_Thunderbolt ThunderboltPacket;
- ThunderboltPacket.m_xLBPos = a_X;
- ThunderboltPacket.m_yLBPos = a_Y;
- ThunderboltPacket.m_zLBPos = a_Z;
- BroadcastToChunkOfBlock(a_X, a_Y, a_Z, &ThunderboltPacket);
-}
-
-
-
-
-
-bool cWorld::IsPlacingItemLegal(Int16 a_ItemType, int a_BlockX, int a_BlockY, int a_BlockZ)
-{
- BLOCKTYPE SurfaceBlock = GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ);
- switch (a_ItemType)
- {
- case E_BLOCK_YELLOW_FLOWER: // Can ONLY be placed on dirt/grass
- case E_BLOCK_RED_ROSE:
- case E_BLOCK_SAPLING:
- {
- switch (SurfaceBlock)
- {
- case E_BLOCK_DIRT:
- case E_BLOCK_GRASS:
- case E_BLOCK_FARMLAND:
- {
- return true;
- }
- }
- return false;
- }
-
- case E_BLOCK_BROWN_MUSHROOM: // Can be placed on pretty much anything, with exceptions
- case E_BLOCK_RED_MUSHROOM:
- {
- switch (SurfaceBlock)
- {
- case E_BLOCK_GLASS:
- case E_BLOCK_YELLOW_FLOWER:
- case E_BLOCK_RED_ROSE:
- case E_BLOCK_BROWN_MUSHROOM:
- case E_BLOCK_RED_MUSHROOM:
- case E_BLOCK_CACTUS:
- {
- return false;
- }
- }
- return true;
- }
-
- case E_BLOCK_CACTUS:
- {
- if ((SurfaceBlock != E_BLOCK_SAND) && (SurfaceBlock != E_BLOCK_CACTUS))
- {
- // Cactus can only be placed on sand and itself
- return false;
- }
-
- // Check surroundings. Cacti may ONLY be surrounded by air
- if (
- (GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) != E_BLOCK_AIR) ||
- (GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) != E_BLOCK_AIR) ||
- (GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) != E_BLOCK_AIR) ||
- (GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) != E_BLOCK_AIR)
- )
- {
- return false;
- }
- return true;
- }
-
- case E_ITEM_SEEDS:
- case E_ITEM_MELON_SEEDS:
- case E_ITEM_PUMPKIN_SEEDS:
- {
- // Seeds can go only on the farmland block:
- return (SurfaceBlock == E_BLOCK_FARMLAND);
- }
- } // switch (a_Packet->m_ItemType)
- return true;
-}
-
-
-
-
-
-void cWorld::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ)
-{
- return m_ChunkMap->SetNextBlockTick(a_BlockX, a_BlockY, a_BlockZ);
-}
-
-
-
-
-
-void cWorld::InitializeSpawn(void)
-{
- int ChunkX = 0, ChunkY = 0, ChunkZ = 0;
- BlockToChunk( (int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ, ChunkX, ChunkY, ChunkZ );
-
- // For the debugging builds, don't make the server build too much world upon start:
- #ifdef _DEBUG
- int ViewDist = 9;
- #else
- int ViewDist = 20; // Always prepare an area 20 chunks across, no matter what the actual cClientHandle::VIEWDISTANCE is
- #endif // _DEBUG
-
- LOG("Preparing spawn area in world \"%s\"...", m_WorldName.c_str());
- for (int x = 0; x < ViewDist; x++)
- {
- for (int z = 0; z < ViewDist; z++)
- {
- m_ChunkMap->TouchChunk( x + ChunkX-(ViewDist - 1) / 2, ZERO_CHUNK_Y, z + ChunkZ-(ViewDist - 1) / 2 ); // Queue the chunk in the generator / loader
- }
- }
-
- {
- // Display progress during this process:
- cWorldLoadProgress Progress(this);
-
- // Wait for the loader to finish loading
- m_Storage.WaitForQueuesEmpty();
-
- // Wait for the generator to finish generating
- m_Generator.WaitForQueueEmpty();
-
- Progress.Stop();
- }
-
- // Light all chunks that have been newly generated:
- LOG("Lighting spawn area in world \"%s\"...", m_WorldName.c_str());
-
- for (int x = 0; x < ViewDist; x++)
- {
- int ChX = x + ChunkX-(ViewDist - 1) / 2;
- for (int z = 0; z < ViewDist; z++)
- {
- int ChZ = z + ChunkZ-(ViewDist - 1) / 2;
- if (!m_ChunkMap->IsChunkLighted(ChX, ChZ))
- {
- m_Lighting.QueueChunk(ChX, ChZ); // Queue the chunk in the lighting thread
- }
- } // for z
- } // for x
-
- {
- cWorldLightingProgress Progress(&m_Lighting);
- m_Lighting.WaitForQueueEmpty();
- Progress.Stop();
- }
-
- // TODO: Better spawn detection - move spawn out of the water if it isn't set in the INI already
- m_SpawnY = (double)GetHeight( (int)m_SpawnX, (int)m_SpawnZ ) + 1.6f; // +1.6f eye height
-}
-
-
-
-
-
-void cWorld::Tick(float a_Dt)
-{
- m_Time += a_Dt / 1000.f;
-
- CurrentTick++;
-
- bool bSendTime = false;
- m_WorldTimeFraction += a_Dt / 1000.f;
- while ( m_WorldTimeFraction > 1.f )
- {
- m_WorldTimeFraction -= 1.f;
- m_WorldTime += 20;
- bSendTime = true;
- }
- m_WorldTime %= 24000; // 24000 units in a day
- if ( bSendTime )
- {
- Broadcast( cPacket_TimeUpdate( (m_WorldTime) ) );
- }
-
- {
- cCSLock Lock(m_CSEntities);
- for (cEntityList::iterator itr = m_AllEntities.begin(); itr != m_AllEntities.end();)
- {
- if ((*itr)->IsDestroyed())
- {
- LOG("Destroying entity #%i", (*itr)->GetUniqueID());
- cEntity * RemoveMe = *itr;
- itr = m_AllEntities.erase( itr );
- m_RemoveEntityQueue.push_back( RemoveMe );
- continue;
- }
- (*itr)->Tick(a_Dt);
- itr++;
- }
- }
-
- m_ChunkMap->Tick(a_Dt, m_TickRand);
-
- GetSimulatorManager()->Simulate(a_Dt);
-
- TickWeather(a_Dt);
-
- // Asynchronously set blocks:
- sSetBlockList FastSetBlockQueueCopy;
- {
- cCSLock Lock(m_CSFastSetBlock);
- std::swap(FastSetBlockQueueCopy, m_FastSetBlockQueue);
- }
- m_ChunkMap->FastSetBlocks(FastSetBlockQueueCopy);
- if (!FastSetBlockQueueCopy.empty())
- {
- // Some blocks failed, store them for next tick:
- cCSLock Lock(m_CSFastSetBlock);
- m_FastSetBlockQueue.splice(m_FastSetBlockQueue.end(), FastSetBlockQueueCopy);
- }
-
- if( m_Time - m_LastSave > 60 * 5 ) // Save each 5 minutes
- {
- SaveAllChunks();
- }
-
- if( m_Time - m_LastUnload > 10 ) // Unload every 10 seconds
- {
- UnloadUnusedChunks();
- }
-
- // Delete entities queued for removal:
- for (cEntityList::iterator itr = m_RemoveEntityQueue.begin(); itr != m_RemoveEntityQueue.end(); ++itr)
- {
- delete *itr;
- }
- m_RemoveEntityQueue.clear();
-
- TickSpawnMobs(a_Dt);
-
- std::vector<int> m_RSList_copy(m_RSList);
-
- m_RSList.clear();
-
- std::vector<int>::const_iterator cii; // FIXME - Please rename this variable, WTF is cii??? Use human readable variable names or common abbreviations (i, idx, itr, iter)
- for(cii=m_RSList_copy.begin(); cii!=m_RSList_copy.end();)
- {
- int tempX = *cii;cii++;
- int tempY = *cii;cii++;
- int tempZ = *cii;cii++;
- int state = *cii;cii++;
-
- if ( (state == 11111) && ( (int)GetBlock( tempX, tempY, tempZ ) == E_BLOCK_REDSTONE_TORCH_OFF ) )
- {
- FastSetBlock( tempX, tempY, tempZ, E_BLOCK_REDSTONE_TORCH_ON, (int)GetBlockMeta( tempX, tempY, tempZ ) );
- cRedstone Redstone(this);
- Redstone.ChangeRedstone( tempX, tempY, tempZ, true );
- }
- else if ( (state == 00000) && ( (int)GetBlock( tempX, tempY, tempZ ) == E_BLOCK_REDSTONE_TORCH_ON ) )
- {
- FastSetBlock( tempX, tempY, tempZ, E_BLOCK_REDSTONE_TORCH_OFF, (int)GetBlockMeta( tempX, tempY, tempZ ) );
- cRedstone Redstone(this);
- Redstone.ChangeRedstone( tempX, tempY, tempZ, false );
- }
- }
- m_RSList_copy.erase(m_RSList_copy.begin(),m_RSList_copy.end());
-}
-
-
-
-
-
-void cWorld::ChangeWeather()
-{
- unsigned randWeather = (m_TickRand.randInt() % 99);
-
- if (GetWeather() == eWeather_Sunny)
- {
- if (randWeather < 20)
- {
- LOG("Starting rainstorm!");
- SetWeather( eWeather_Rain );
- }
- }
-
- else if (GetWeather() == eWeather_Rain)
- {
- if (randWeather < 5)
- {
- LOG("Thunderstorm!");
- SetWeather( eWeather_ThunderStorm );
- }
-
- else if (randWeather < 60)
- {
- LOG("Back to sunshine");
- SetWeather( eWeather_Sunny );
- }
- }
-
- else if (GetWeather() == eWeather_ThunderStorm)
- {
- if (randWeather < 70)
- {
- SetWeather(eWeather_Sunny);
- LOG("Thunder ended abruptly, returning to lovely sunshine");
- }
- else if (randWeather < 85)
- {
- SetWeather(eWeather_Rain);
- LOG("Thunder ended, but rain persists.");
- }
- else
- {
- return;
- }
- }
-}
-
-
-
-
-
-void cWorld::TickWeather(float a_Dt)
-{
- if(m_WeatherInterval == 0)
- {
- ChangeWeather();
-
- cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::HOOK_WEATHER_CHANGE, 0 );
-
- switch(GetWeather())
- {
- case eWeather_Sunny:
- m_WeatherInterval = 14400 + (m_TickRand.randInt() % 4800); // 12 - 16 minutes
- break;
- case eWeather_Rain:
- m_WeatherInterval = 9600 + (m_TickRand.randInt() % 7200); // 8 - 14 minutes
- break;
- case eWeather_ThunderStorm:
- m_WeatherInterval = 2400 + (m_TickRand.randInt() % 4800); // 2 - 6 minutes
- break;
- default:
- LOG("Unknown weather occurred");
- break;
- }
- }
-
- else
- {
- m_WeatherInterval--;
- }
-
- if ( GetWeather() == 2 ) // if thunderstorm
- {
- if (m_TickRand.randInt() % 199 == 0) // 0.5% chance per tick of thunderbolt
- {
- CastThunderbolt ( 0, 0, 0 ); // TODO: find random possitions near players to cast thunderbolts.
- }
- }
-}
-
-
-
-
-
-void cWorld::TickSpawnMobs(float a_Dt)
-{
- if (!m_bAnimals || (m_Time - m_SpawnMonsterTime <= m_SpawnMonsterRate))
- {
- return;
- }
-
- m_SpawnMonsterTime = m_Time;
- Vector3d SpawnPos;
- {
- cCSLock Lock(m_CSPlayers);
- if ( m_Players.size() <= 0)
- {
- return;
- }
- int RandomPlayerIdx = m_TickRand.randInt() & m_Players.size();
- cPlayerList::iterator itr = m_Players.begin();
- for( int i = 1; i < RandomPlayerIdx; i++ )
- {
- itr++;
- }
- SpawnPos = (*itr)->GetPosition();
- }
-
- cMonster * Monster = NULL;
- int dayRand = m_TickRand.randInt() % 6;
- int nightRand = m_TickRand.randInt() % 10;
-
- SpawnPos += Vector3d( (double)(m_TickRand.randInt() % 64) - 32, (double)(m_TickRand.randInt() % 64) - 32, (double)(m_TickRand.randInt() % 64) - 32 );
- int Height = GetHeight( (int)SpawnPos.x, (int)SpawnPos.z );
-
- if (m_WorldTime >= 12000 + 1000)
- {
- if (nightRand == 0) //random percent to spawn for night
- Monster = new cSpider();
- else if (nightRand == 1)
- Monster = new cZombie();
- else if (nightRand == 2)
- Monster = new cEnderman();
- else if (nightRand == 3)
- Monster = new cCreeper();
- else if (nightRand == 4)
- Monster = new cCavespider();
- else if (nightRand == 5)
- Monster = new cGhast();
- else if (nightRand == 6)
- Monster = new cZombiepigman();
- else if (nightRand == 7)
- Monster = new cSlime();
- else if (nightRand == 8)
- Monster = new cSilverfish();
- else if (nightRand == 9)
- Monster = new cSkeleton();
- //end random percent to spawn for night
- }
- else
- {
- if (dayRand == 0) //random percent to spawn for day
- Monster = new cChicken();
- else if (dayRand == 1)
- Monster = new cCow();
- else if (dayRand == 2)
- Monster = new cPig();
- else if (dayRand == 3)
- Monster = new cSheep();
- else if (dayRand == 4)
- Monster = new cSquid();
- else if (dayRand == 5)
- Monster = new cWolf();
- //end random percent to spawn for day
- }
-
- if( Monster )
- {
- Monster->Initialize( this );
- Monster->TeleportTo( SpawnPos.x, (double)(Height) + 2, SpawnPos.z );
- Monster->SpawnOn(0);
- }
-}
-
-
-
-
-
-void cWorld::GrowTree( int a_X, int a_Y, int a_Z )
-{
- if (GetBlock(a_X, a_Y, a_Z) == E_BLOCK_SAPLING)
- {
- // There is a sapling here, grow a tree according to its type:
- GrowTreeFromSapling(a_X, a_Y, a_Z, GetBlockMeta(a_X, a_Y, a_Z));
- }
- else
- {
- // There is nothing here, grow a tree based on the current biome here:
- GrowTreeByBiome(a_X, a_Y, a_Z);
- }
-}
-
-
-
-
-
-void cWorld::GrowTreeFromSapling(int a_X, int a_Y, int a_Z, char a_SaplingMeta)
-{
- cNoise Noise(m_Generator.GetSeed());
- sSetBlockVector Blocks;
- switch (a_SaplingMeta & 0x07)
- {
- case E_META_SAPLING_APPLE: GetAppleTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break;
- case E_META_SAPLING_BIRCH: GetBirchTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break;
- case E_META_SAPLING_CONIFER: GetConiferTreeImage(a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break;
- case E_META_SAPLING_JUNGLE: GetJungleTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break;
- }
-
- GrowTreeImage(Blocks);
-}
-
-
-
-
-
-void cWorld::GrowTreeByBiome(int a_X, int a_Y, int a_Z)
-{
- cNoise Noise(m_Generator.GetSeed());
- sSetBlockVector Blocks;
- GetTreeImageByBiome(a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), (EMCSBiome)GetBiomeAt(a_X, a_Z), Blocks);
- GrowTreeImage(Blocks);
-}
-
-
-
-
-
-void cWorld::GrowTreeImage(const sSetBlockVector & a_Blocks)
-{
- // Check that the tree has place to grow
-
- // Make a copy of the log blocks:
- sSetBlockVector b2;
- for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
- {
- if (itr->BlockType == E_BLOCK_LOG)
- {
- b2.push_back(*itr);
- }
- } // for itr - a_Blocks[]
-
- // Query blocktypes and metas at those log blocks:
- if (!GetBlocks(b2, false))
- {
- return;
- }
-
- // Check that at each log's coord there's an block allowed to be overwritten:
- for (sSetBlockVector::const_iterator itr = b2.begin(); itr != b2.end(); ++itr)
- {
- switch (itr->BlockType)
- {
- CASE_TREE_ALLOWED_BLOCKS:
- {
- break;
- }
- default:
- {
- return;
- }
- }
- } // for itr - b2[]
-
- // All ok, replace blocks with the tree image:
- m_ChunkMap->ReplaceTreeBlocks(a_Blocks);
-}
-
-
-
-
-
-bool cWorld::GrowPlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsByBonemeal)
-{
- BLOCKTYPE BlockType;
- NIBBLETYPE BlockMeta;
- GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
- switch (BlockType)
- {
- case E_BLOCK_CROPS:
- {
- if (a_IsByBonemeal && !m_IsGrassBonemealable)
- {
- return false;
- }
- if (BlockMeta < 7)
- {
- FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, 7);
- }
- return true;
- }
-
- case E_BLOCK_MELON_STEM:
- {
- if (BlockMeta < 7)
- {
- if (a_IsByBonemeal && !m_IsMelonStemBonemealable)
- {
- return false;
- }
- FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, 7);
- }
- else
- {
- if (a_IsByBonemeal && !m_IsMelonBonemealable)
- {
- return false;
- }
- GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, BlockType);
- }
- return true;
- }
-
- case E_BLOCK_PUMPKIN_STEM:
- {
- if (BlockMeta < 7)
- {
- if (a_IsByBonemeal && !m_IsPumpkinStemBonemealable)
- {
- return false;
- }
- FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, 7);
- }
- else
- {
- if (a_IsByBonemeal && !m_IsPumpkinBonemealable)
- {
- return false;
- }
- GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, BlockType);
- }
- return true;
- }
-
- case E_BLOCK_SAPLING:
- {
- if (a_IsByBonemeal && !m_IsSaplingBonemealable)
- {
- return false;
- }
- GrowTreeFromSapling(a_BlockX, a_BlockY, a_BlockZ, BlockMeta);
- return true;
- }
-
- case E_BLOCK_GRASS:
- {
- if (a_IsByBonemeal && !m_IsGrassBonemealable)
- {
- return false;
- }
- MTRand r1;
- for (int i = 0; i < 60; i++)
- {
- int OfsX = (r1.randInt(3) + r1.randInt(3) + r1.randInt(3) + r1.randInt(3)) / 2 - 3;
- int OfsY = r1.randInt(3) + r1.randInt(3) - 3;
- int OfsZ = (r1.randInt(3) + r1.randInt(3) + r1.randInt(3) + r1.randInt(3)) / 2 - 3;
- BLOCKTYPE Ground = GetBlock(a_BlockX + OfsX, a_BlockY + OfsY, a_BlockZ + OfsZ);
- if (Ground != E_BLOCK_GRASS)
- {
- continue;
- }
- BLOCKTYPE Above = GetBlock(a_BlockX + OfsX, a_BlockY + OfsY + 1, a_BlockZ + OfsZ);
- if (Above != E_BLOCK_AIR)
- {
- continue;
- }
- BLOCKTYPE SpawnType;
- NIBBLETYPE SpawnMeta = 0;
- switch (r1.randInt(10))
- {
- case 0: SpawnType = E_BLOCK_YELLOW_FLOWER; break;
- case 1: SpawnType = E_BLOCK_RED_ROSE; break;
- default:
- {
- SpawnType = E_BLOCK_TALL_GRASS;
- SpawnMeta = E_META_TALL_GRASS_GRASS;
- break;
- }
- } // switch (random spawn block)
- FastSetBlock(a_BlockX + OfsX, a_BlockY + OfsY + 1, a_BlockZ + OfsZ, SpawnType, SpawnMeta);
- } // for i - 50 times
- return true;
- }
-
- case E_BLOCK_SUGARCANE:
- {
- if (a_IsByBonemeal && !m_IsSugarcaneBonemealable)
- {
- return false;
- }
- m_ChunkMap->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, m_MaxSugarcaneHeight);
- return true;
- }
-
- case E_BLOCK_CACTUS:
- {
- if (a_IsByBonemeal && !m_IsCactusBonemealable)
- {
- return false;
- }
- m_ChunkMap->GrowCactus(a_BlockX, a_BlockY, a_BlockZ, m_MaxCactusHeight);
- return true;
- }
- } // switch (BlockType)
- return false;
-}
-
-
-
-
-
-void cWorld::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockType)
-{
- MTRand Rand;
- m_ChunkMap->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, Rand);
-}
-
-
-
-
-
-int cWorld::GetBiomeAt (int a_BlockX, int a_BlockZ)
-{
- return m_ChunkMap->GetBiomeAt(a_BlockX, a_BlockZ);
-}
-
-
-
-
-
-void cWorld::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta )
-{
- m_ChunkMap->SetBlock(a_X, a_Y, a_Z, a_BlockType, a_BlockMeta);
-
- GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z);
-}
-
-
-
-
-
-void cWorld::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta )
-{
- cCSLock Lock(m_CSFastSetBlock);
- m_FastSetBlockQueue.push_back(sSetBlock(a_X, a_Y, a_Z, a_BlockType, a_BlockMeta));
-}
-
-
-
-
-
-char cWorld::GetBlock(int a_X, int a_Y, int a_Z)
-{
- // First check if it isn't queued in the m_FastSetBlockQueue:
- {
- int X = a_X, Y = a_Y, Z = a_Z;
- int ChunkX, ChunkY, ChunkZ;
- AbsoluteToRelative(X, Y, Z, ChunkX, ChunkY, ChunkZ);
-
- cCSLock Lock(m_CSFastSetBlock);
- for (sSetBlockList::iterator itr = m_FastSetBlockQueue.begin(); itr != m_FastSetBlockQueue.end(); ++itr)
- {
- if ((itr->x == X) && (itr->y == Y) && (itr->z == Z) && (itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ))
- {
- return itr->BlockType;
- }
- } // for itr - m_FastSetBlockQueue[]
- }
-
- return m_ChunkMap->GetBlock(a_X, a_Y, a_Z);
-}
-
-
-
-
-
-char cWorld::GetBlockMeta( int a_X, int a_Y, int a_Z )
-{
- // First check if it isn't queued in the m_FastSetBlockQueue:
- {
- cCSLock Lock(m_CSFastSetBlock);
- for (sSetBlockList::iterator itr = m_FastSetBlockQueue.begin(); itr != m_FastSetBlockQueue.end(); ++itr)
- {
- if ((itr->x == a_X) && (itr->y == a_Y) && (itr->y == a_Y))
- {
- return itr->BlockMeta;
- }
- } // for itr - m_FastSetBlockQueue[]
- }
-
- return m_ChunkMap->GetBlockMeta(a_X, a_Y, a_Z);
-}
-
-
-
-
-
-void cWorld::SetBlockMeta( int a_X, int a_Y, int a_Z, char a_MetaData )
-{
- m_ChunkMap->SetBlockMeta(a_X, a_Y, a_Z, a_MetaData);
-}
-
-
-
-
-
-char cWorld::GetBlockSkyLight( int a_X, int a_Y, int a_Z )
-{
- return m_ChunkMap->GetBlockSkyLight(a_X, a_Y, a_Z);
-}
-
-
-
-
-
-void cWorld::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, char & a_BlockType, unsigned char & a_BlockMeta)
-{
- m_ChunkMap->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, (BLOCKTYPE &)a_BlockType, (NIBBLETYPE &)a_BlockMeta);
-}
-
-
-
-
-
-void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed)
-{
- MTRand r1;
- a_FlyAwaySpeed /= 1000; // Pre-divide, so that we can don't have to divide each time inside the loop
- for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr)
- {
- float SpeedX = (float)(a_FlyAwaySpeed * (r1.randInt(1000) - 500));
- float SpeedY = (float)(a_FlyAwaySpeed * r1.randInt(1000));
- float SpeedZ = (float)(a_FlyAwaySpeed * (r1.randInt(1000) - 500));
- cPickup * Pickup = new cPickup(
- (int)(a_BlockX * 32) + r1.randInt(16) + r1.randInt(16),
- (int)(a_BlockY * 32) + r1.randInt(16) + r1.randInt(16),
- (int)(a_BlockZ * 32) + r1.randInt(16) + r1.randInt(16),
- *itr, SpeedX, SpeedY, SpeedZ
- );
- Pickup->Initialize(this);
- }
-}
-
-
-
-
-
-void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ)
-{
- MTRand r1;
- for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr)
- {
- cPickup * Pickup = new cPickup(
- (int)(a_BlockX * 32) + r1.randInt(16) + r1.randInt(16),
- (int)(a_BlockY * 32) + r1.randInt(16) + r1.randInt(16),
- (int)(a_BlockZ * 32) + r1.randInt(16) + r1.randInt(16),
- *itr, (float)a_SpeedX, (float)a_SpeedY, (float)a_SpeedZ
- );
- Pickup->Initialize(this);
- }
-}
-
-
-
-
-
-void cWorld::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType)
-{
- m_ChunkMap->ReplaceBlocks(a_Blocks, a_FilterBlockType);
-}
-
-
-
-
-
-bool cWorld::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure)
-{
- return m_ChunkMap->GetBlocks(a_Blocks, a_ContinueOnFailure);
-}
-
-
-
-
-
-bool cWorld::DigBlock( int a_X, int a_Y, int a_Z)
-{
- return m_ChunkMap->DigBlock(a_X, a_Y, a_Z);
-}
-
-
-
-
-
-void cWorld::SendBlockTo( int a_X, int a_Y, int a_Z, cPlayer * a_Player )
-{
- m_ChunkMap->SendBlockTo(a_X, a_Y, a_Z, a_Player);
-}
-
-
-
-
-
-// TODO: This interface is dangerous!
-cBlockEntity * cWorld::GetBlockEntity( int a_X, int a_Y, int a_Z )
-{
- return NULL;
-}
-
-
-
-
-
-int cWorld::GetHeight( int a_X, int a_Z )
-{
- return m_ChunkMap->GetHeight(a_X, a_Z);
-}
-
-
-
-
-
-const double & cWorld::GetSpawnY(void)
-{
- return m_SpawnY;
-}
-
-
-
-
-void cWorld::Broadcast( const cPacket & a_Packet, cClientHandle * a_Exclude)
-{
- cCSLock Lock(m_CSPlayers);
- for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
- {
- cClientHandle * ch = (*itr)->GetClientHandle();
- if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed())
- {
- continue;
- }
- (*itr)->GetClientHandle()->Send( a_Packet );
- }
-}
-
-
-
-
-
-void cWorld::BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude)
-{
- m_ChunkMap->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Packet, a_Exclude);
-}
-
-
-
-
-
-void cWorld::BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude)
-{
- m_ChunkMap->BroadcastToChunkOfBlock(a_X, a_Y, a_Z, a_Packet, a_Exclude);
-}
-
-
-
-
-
-void cWorld::MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- m_ChunkMap->MarkChunkDirty (a_ChunkX, a_ChunkY, a_ChunkZ);
-}
-
-
-
-
-
-void cWorld::MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- m_ChunkMap->MarkChunkSaving(a_ChunkX, a_ChunkY, a_ChunkZ);
-}
-
-
-
-
-
-void cWorld::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- m_ChunkMap->MarkChunkSaved (a_ChunkX, a_ChunkY, a_ChunkZ);
-}
-
-
-
-
-
-void cWorld::SetChunkData(
- int a_ChunkX, int a_ChunkY, int a_ChunkZ,
- const BLOCKTYPE * a_BlockTypes,
- const NIBBLETYPE * a_BlockMeta,
- const NIBBLETYPE * a_BlockLight,
- const NIBBLETYPE * a_BlockSkyLight,
- const cChunkDef::HeightMap * a_HeightMap,
- const cChunkDef::BiomeMap * a_BiomeMap,
- cEntityList & a_Entities,
- cBlockEntityList & a_BlockEntities,
- bool a_MarkDirty
-)
-{
- // Validate biomes, if needed:
- cChunkDef::BiomeMap BiomeMap;
- const cChunkDef::BiomeMap * Biomes = a_BiomeMap;
- if (a_BiomeMap == NULL)
- {
- // The biomes are not assigned, get them from the generator:
- Biomes = &BiomeMap;
- m_Generator.GenerateBiomes(a_ChunkX, a_ChunkZ, BiomeMap);
- }
-
- m_ChunkMap->SetChunkData(
- a_ChunkX, a_ChunkY, a_ChunkZ,
- a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight,
- a_HeightMap, *Biomes,
- a_Entities, a_BlockEntities,
- a_MarkDirty
- );
-
- // If a client is requesting this chunk, send it to them:
- if (m_ChunkMap->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ))
- {
- m_ChunkSender.ChunkReady(a_ChunkX, a_ChunkY, a_ChunkZ);
- }
-
- // Notify the lighting thread that the chunk has become valid (in case it is a neighbor of a postponed chunk):
- m_Lighting.ChunkReady(a_ChunkX, a_ChunkZ);
-}
-
-
-
-
-
-void cWorld::ChunkLighted(
- int a_ChunkX, int a_ChunkZ,
- const cChunkDef::BlockNibbles & a_BlockLight,
- const cChunkDef::BlockNibbles & a_SkyLight
-)
-{
- m_ChunkMap->ChunkLighted(a_ChunkX, a_ChunkZ, a_BlockLight, a_SkyLight);
-}
-
-
-
-
-
-bool cWorld::GetChunkData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback)
-{
- return m_ChunkMap->GetChunkData(a_ChunkX, a_ChunkY, a_ChunkZ, a_Callback);
-}
-
-
-
-
-
-bool cWorld::GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes)
-{
- return m_ChunkMap->GetChunkBlockTypes(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockTypes);
-}
-
-
-
-
-
-bool cWorld::GetChunkBlockData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData)
-{
- return m_ChunkMap->GetChunkBlockData(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockData);
-}
-
-
-
-
-
-bool cWorld::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const
-{
- return m_ChunkMap->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ);
-}
-
-
-
-
-
-bool cWorld::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const
-{
- return m_ChunkMap->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ);
-}
-
-
-
-
-
-void cWorld::UnloadUnusedChunks(void )
-{
- m_LastUnload = m_Time;
- m_ChunkMap->UnloadUnusedChunks();
-}
-
-
-
-
-
-void cWorld::CollectPickupsByPlayer(cPlayer * a_Player)
-{
- m_ChunkMap->CollectPickupsByPlayer(a_Player);
-}
-
-
-
-
-
-void cWorld::SetMaxPlayers(int iMax)
-{
- m_MaxPlayers = MAX_PLAYERS;
- if (iMax > 0 && iMax < MAX_PLAYERS)
- {
- m_MaxPlayers = iMax;
- }
-}
-
-
-
-
-
-void cWorld::AddPlayer( cPlayer* a_Player )
-{
- cCSLock Lock(m_CSPlayers);
-
- ASSERT(std::find(m_Players.begin(), m_Players.end(), a_Player) == m_Players.end()); // Is it already in the list? HOW?
-
- m_Players.remove( a_Player ); // Make sure the player is registered only once
- m_Players.push_back( a_Player );
-}
-
-
-
-
-
-void cWorld::RemovePlayer( cPlayer* a_Player )
-{
- cCSLock Lock(m_CSPlayers);
- m_Players.remove( a_Player );
-}
-
-
-
-
-
-bool cWorld::ForEachPlayer(cPlayerListCallback & a_Callback)
-{
- // Calls the callback for each player in the list
- cCSLock Lock(m_CSPlayers);
- for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
- {
- if (a_Callback.Item(*itr))
- {
- return false;
- }
- } // for itr - m_Players[]
- return true;
-}
-
-
-
-
-// TODO: This interface is dangerous!
-cPlayer* cWorld::GetPlayer( const char* a_PlayerName )
-{
- cPlayer* BestMatch = 0;
- unsigned int MatchedLetters = 0;
- unsigned int NumMatches = 0;
- bool bPerfectMatch = false;
-
- unsigned int NameLength = strlen( a_PlayerName );
- cCSLock Lock(m_CSPlayers);
- for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); itr++ )
- {
- std::string Name = (*itr)->GetName();
- if( NameLength > Name.length() ) continue; // Definitely not a match
-
- for (unsigned int i = 0; i < NameLength; i++)
- {
- char c1 = (char)toupper( a_PlayerName[i] );
- char c2 = (char)toupper( Name[i] );
- if( c1 == c2 )
- {
- if( i+1 > MatchedLetters )
- {
- MatchedLetters = i+1;
- BestMatch = *itr;
- }
- if( i+1 == NameLength )
- {
- NumMatches++;
- if( NameLength == Name.length() )
- {
- bPerfectMatch = true;
- break;
- }
- }
- }
- else
- {
- if( BestMatch == *itr ) BestMatch = 0;
- break;
- }
- if( bPerfectMatch )
- break;
- }
- }
- if ( NumMatches == 1 )
- {
- return BestMatch;
- }
-
- // More than one matches, so it's undefined. Return NULL instead
- return NULL;
-}
-
-
-
-
-
-cPlayer * cWorld::FindClosestPlayer(const Vector3f & a_Pos, float a_SightLimit)
-{
- cTracer LineOfSight(this);
-
- float ClosestDistance = a_SightLimit;
- cPlayer* ClosestPlayer = NULL;
-
- cCSLock Lock(m_CSPlayers);
- for (cPlayerList::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
- {
- Vector3f Pos = (*itr)->GetPosition();
- float Distance = (Pos - a_Pos).Length();
-
- if (Distance <= a_SightLimit)
- {
- if (!LineOfSight.Trace(a_Pos,(Pos - a_Pos),(int)(Pos - a_Pos).Length()))
- {
- if (Distance < ClosestDistance)
- {
- ClosestDistance = Distance;
- ClosestPlayer = *itr;
- }
- }
- }
- }
- return ClosestPlayer;
-}
-
-
-
-
-
-void cWorld::SendPlayerList(cPlayer * a_DestPlayer)
-{
- // Sends the playerlist to a_DestPlayer
- cCSLock Lock(m_CSPlayers);
- for ( cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
- {
- cClientHandle * ch = (*itr)->GetClientHandle();
- if ((ch != NULL) && !ch->IsDestroyed())
- {
- cPacket_PlayerListItem PlayerListItem((*itr)->GetColor() + (*itr)->GetName(), true, (*itr)->GetClientHandle()->GetPing());
- a_DestPlayer->GetClientHandle()->Send( PlayerListItem );
- }
- }
-}
-
-
-
-
-
-bool cWorld::DoWithEntity( int a_UniqueID, cEntityCallback & a_Callback )
-{
- cCSLock Lock(m_CSEntities);
- for (cEntityList::iterator itr = m_AllEntities.begin(); itr != m_AllEntities.end(); ++itr )
- {
- if( (*itr)->GetUniqueID() == a_UniqueID )
- {
- return a_Callback.Item(*itr);
- }
- } // for itr - m_AllEntities[]
- return false;
-}
-
-
-
-
-
-void cWorld::RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- m_ChunkMap->RemoveEntityFromChunk(a_Entity, a_ChunkX, a_ChunkY, a_ChunkZ);
-}
-
-
-
-
-
-void cWorld::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- m_ChunkMap->MoveEntityToChunk(a_Entity, a_ChunkX, a_ChunkY, a_ChunkZ);
-}
-
-
-
-
-
-void cWorld::CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback)
-{
- m_ChunkMap->CompareChunkClients(a_ChunkX1, a_ChunkY1, a_ChunkZ1, a_ChunkX2, a_ChunkY2, a_ChunkZ2, a_Callback);
-}
-
-
-
-
-
-bool cWorld::AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
-{
- return m_ChunkMap->AddChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client);
-}
-
-
-
-
-
-void cWorld::RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
-{
- m_ChunkMap->RemoveChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client);
-}
-
-
-
-
-
-void cWorld::RemoveClientFromChunks(cClientHandle * a_Client)
-{
- m_ChunkMap->RemoveClientFromChunks(a_Client);
-}
-
-
-
-
-
-void cWorld::SendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
-{
- m_ChunkSender.QueueSendChunkTo(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client);
-}
-
-
-
-
-
-void cWorld::RemoveClientFromChunkSender(cClientHandle * a_Client)
-{
- m_ChunkSender.RemoveClient(a_Client);
-}
-
-
-
-
-
-void cWorld::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- m_ChunkMap->TouchChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
-}
-
-
-
-
-
-bool cWorld::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- return m_ChunkMap->LoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
-}
-
-
-
-
-
-void cWorld::LoadChunks(const cChunkCoordsList & a_Chunks)
-{
- m_ChunkMap->LoadChunks(a_Chunks);
-}
-
-
-
-
-
-void cWorld::ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-{
- m_ChunkMap->ChunkLoadFailed(a_ChunkX, a_ChunkY, a_ChunkZ);
-}
-
-
-
-
-
-void cWorld::UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4)
-{
- m_ChunkMap->UpdateSign(a_X, a_Y, a_Z, a_Line1, a_Line2, a_Line3, a_Line4);
-}
-
-
-
-
-
-void cWorld::ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay)
-{
- m_ChunkMap->ChunksStay(a_Chunks, a_Stay);
-}
-
-
-
-
-
-void cWorld::RegenerateChunk(int a_ChunkX, int a_ChunkZ)
-{
- m_ChunkMap->MarkChunkRegenerating(a_ChunkX, a_ChunkZ);
-
- // Trick: use Y=1 to force the chunk generation even though the chunk data is already present
- m_Generator.QueueGenerateChunk(a_ChunkX, 1, a_ChunkZ);
-}
-
-
-
-
-
-void cWorld::GenerateChunk(int a_ChunkX, int a_ChunkZ)
-{
- m_Generator.QueueGenerateChunk(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
-}
-
-
-
-
-
-void cWorld::QueueLightChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback)
-{
- m_Lighting.QueueChunk(a_ChunkX, a_ChunkZ, a_Callback);
-}
-
-
-
-
-
-bool cWorld::IsChunkLighted(int a_ChunkX, int a_ChunkZ)
-{
- return m_ChunkMap->IsChunkLighted(a_ChunkX, a_ChunkZ);
-}
-
-
-
-
-
-void cWorld::SaveAllChunks(void)
-{
- LOG("Saving all chunks...");
- m_LastSave = m_Time;
- m_ChunkMap->SaveAllChunks();
-}
-
-
-
-
-
-/************************************************************************/
-/* Get and set */
-/************************************************************************/
-// void cWorld::AddClient( cClientHandle* a_Client )
-// {
-// m_m_Clients.push_back( a_Client );
-// }
-// cWorld::ClientList & cWorld::GetClients()
-// {
-// return m_m_Clients;
-// }
-
-
-
-
-
-void cWorld::AddEntity( cEntity* a_Entity )
-{
- cCSLock Lock(m_CSEntities);
- m_AllEntities.push_back( a_Entity );
-}
-
-
-
-
-
-unsigned int cWorld::GetNumPlayers()
-{
- cCSLock Lock(m_CSPlayers);
- return m_Players.size();
-}
-
-
-
-
-
-int cWorld::GetNumChunks(void) const
-{
- return m_ChunkMap->GetNumChunks();
-}
-
-
-
-
-
-void cWorld::GetChunkStats(int & a_NumValid, int & a_NumDirty, int & a_NumInLightingQueue)
-{
- m_ChunkMap->GetChunkStats(a_NumValid, a_NumDirty);
- a_NumInLightingQueue = (int) m_Lighting.GetQueueLength();
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "BlockID.h" +#include "cWorld.h" +#include "cRedstone.h" +#include "ChunkDef.h" +#include "cClientHandle.h" +#include "cPickup.h" +#include "cBlockToPickup.h" +#include "cPlayer.h" +#include "cServer.h" +#include "cItem.h" +#include "cRoot.h" +#include "../iniFile/iniFile.h" +#include "cChunkMap.h" +#include "cSimulatorManager.h" +#include "cWaterSimulator.h" +#include "cLavaSimulator.h" +#include "cFireSimulator.h" +#include "cSandSimulator.h" +#include "cRedstoneSimulator.h" +#include "cChicken.h" +#include "cSpider.h" +#include "cCow.h" //cow +#include "cSquid.h" //Squid +#include "cWolf.h" //wolf +#include "cSlime.h" //slime +#include "cSkeleton.h" //Skeleton +#include "cSilverfish.h" //Silverfish +#include "cPig.h" //pig +#include "cSheep.h" //sheep +#include "cZombie.h" //zombie +#include "cEnderman.h" //enderman +#include "cCreeper.h" //creeper +#include "cCavespider.h" //cavespider +#include "cGhast.h" //Ghast +#include "cZombiepigman.h" //Zombiepigman +#include "cMakeDir.h" +#include "cChunkGenerator.h" +#include "MersenneTwister.h" +#include "cTracer.h" +#include "Trees.h" +#include "cPluginManager.h" + + +#include "packets/cPacket_TimeUpdate.h" +#include "packets/cPacket_NewInvalidState.h" +#include "packets/cPacket_Thunderbolt.h" + +#include "Vector3d.h" + +#include <time.h> + +#include "tolua++.h" + +#ifndef _WIN32 + #include <stdlib.h> +#endif + + + + + +/// Up to this many m_SpreadQueue elements are handled each world tick +const int MAX_LIGHTING_SPREAD_PER_TICK = 10; + + + + + +float cWorld::m_Time = 0.f; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWorldLoadProgress: + +/// A simple thread that displays the progress of world loading / saving in cWorld::InitializeSpawn() +class cWorldLoadProgress : + public cIsThread +{ +public: + cWorldLoadProgress(cWorld * a_World) : + cIsThread("cWorldLoadProgress"), + m_World(a_World) + { + Start(); + } + + void Stop(void) + { + m_ShouldTerminate = true; + Wait(); + } + +protected: + + cWorld * m_World; + + virtual void Execute(void) override + { + for (;;) + { + LOG("%d chunks to load, %d chunks to generate", + m_World->GetStorage().GetLoadQueueLength(), + m_World->GetGenerator().GetQueueLength() + ); + + // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish + for (int i = 0; i < 20; i++) + { + cSleep::MilliSleep(100); + if (m_ShouldTerminate) + { + return; + } + } + } // for (-ever) + } + +} ; + + + + + +/// A simple thread that displays the progress of world lighting in cWorld::InitializeSpawn() +class cWorldLightingProgress : + public cIsThread +{ +public: + cWorldLightingProgress(cLightingThread * a_Lighting) : + cIsThread("cWorldLightingProgress"), + m_Lighting(a_Lighting) + { + Start(); + } + + void Stop(void) + { + m_ShouldTerminate = true; + Wait(); + } + +protected: + + cLightingThread * m_Lighting; + + virtual void Execute(void) override + { + for (;;) + { + LOG("%d chunks remaining to light", m_Lighting->GetQueueLength() + ); + + // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish + for (int i = 0; i < 20; i++) + { + cSleep::MilliSleep(100); + if (m_ShouldTerminate) + { + return; + } + } + } // for (-ever) + } + +} ; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWorld: + +cWorld* cWorld::GetWorld() +{ + LOGWARN("WARNING: Using deprecated function cWorld::GetWorld() use cRoot::Get()->GetDefaultWorld() instead!"); + return cRoot::Get()->GetDefaultWorld(); +} + + + + + +cWorld::~cWorld() +{ + { + cCSLock Lock(m_CSEntities); + while( m_AllEntities.begin() != m_AllEntities.end() ) + { + cEntity* Entity = *m_AllEntities.begin(); + m_AllEntities.remove( Entity ); + if ( !Entity->IsDestroyed() ) + { + Entity->Destroy(); + } + delete Entity; + } + } + + delete m_SimulatorManager; + delete m_SandSimulator; + delete m_WaterSimulator; + delete m_LavaSimulator; + delete m_FireSimulator; + delete m_RedstoneSimulator; + + m_Generator.Stop(); + m_ChunkSender.Stop(); + + UnloadUnusedChunks(); + + m_Storage.WaitForFinish(); + + delete m_ChunkMap; +} + + + + + +cWorld::cWorld( const AString & a_WorldName ) + : m_SpawnMonsterTime( 0.f ) + , m_RSList ( 0 ) + , m_Weather ( eWeather_Sunny ) +{ + LOG("cWorld::cWorld(%s)", a_WorldName.c_str()); + m_WorldName = a_WorldName; + m_IniFileName = m_WorldName + "/world.ini"; + + cMakeDir::MakeDir(m_WorldName.c_str()); + + MTRand r1; + m_SpawnX = (double)((r1.randInt() % 1000) - 500); + m_SpawnY = cChunkDef::Height; + m_SpawnZ = (double)((r1.randInt() % 1000) - 500); + m_GameMode = eGameMode_Creative; + + AString StorageSchema("Default"); + + cIniFile IniFile(m_IniFileName); + IniFile.ReadFile(); + m_SpawnX = IniFile.GetValueSetF("SpawnPosition", "X", m_SpawnX); + m_SpawnY = IniFile.GetValueSetF("SpawnPosition", "Y", m_SpawnY); + m_SpawnZ = IniFile.GetValueSetF("SpawnPosition", "Z", m_SpawnZ); + StorageSchema = IniFile.GetValueSet ("Storage", "Schema", StorageSchema); + m_MaxCactusHeight = IniFile.GetValueSetI("Plants", "MaxCactusHeight", 3); + m_MaxSugarcaneHeight = IniFile.GetValueSetI("Plants", "MaxSugarcaneHeight", 3); + m_IsCropsBonemealable = IniFile.GetValueSetB("Plants", "IsCropsBonemealable", true); + m_IsGrassBonemealable = IniFile.GetValueSetB("Plants", "IsGrassBonemealable", true); + m_IsSaplingBonemealable = IniFile.GetValueSetB("Plants", "IsSaplingBonemealable", true); + m_IsMelonStemBonemealable = IniFile.GetValueSetB("Plants", "IsMelonStemBonemealable", true); + m_IsMelonBonemealable = IniFile.GetValueSetB("Plants", "IsMelonBonemealable", false); + m_IsPumpkinStemBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinStemBonemealable", true); + m_IsPumpkinBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinBonemealable", false); + m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false); + m_IsCactusBonemealable = IniFile.GetValueSetB("Plants", "IsCactusBonemealable", false); + + m_GameMode = (eGameMode)IniFile.GetValueSetI("GameMode", "GameMode", m_GameMode ); + + if (!IniFile.WriteFile()) + { + LOG("WARNING: Could not write to %s", m_IniFileName.c_str()); + } + + m_Lighting.Start(this); + m_Storage.Start(this, StorageSchema); + m_Generator.Start(this, IniFile); + + m_bAnimals = true; + m_SpawnMonsterRate = 10; + cIniFile IniFile2("settings.ini"); + if( IniFile2.ReadFile() ) + { + m_bAnimals = IniFile2.GetValueB("Monsters", "AnimalsOn", true ); + m_SpawnMonsterRate = (float)IniFile2.GetValueF("Monsters", "AnimalSpawnInterval", 10); + SetMaxPlayers(IniFile2.GetValueI("Server", "MaxPlayers", 9001)); + m_Description = IniFile2.GetValue("Server", "Description", "MCServer! - It's OVER 9000!").c_str(); + } + + m_ChunkMap = new cChunkMap(this ); + + m_ChunkSender.Start(this); + + m_Time = 0; + m_WorldTimeFraction = 0.f; + m_WorldTime = 0; + m_LastSave = 0; + m_LastUnload = 0; + + //Simulators: + m_WaterSimulator = new cWaterSimulator( this ); + m_LavaSimulator = new cLavaSimulator( this ); + m_SandSimulator = new cSandSimulator(this); + m_FireSimulator = new cFireSimulator(this); + m_RedstoneSimulator = new cRedstoneSimulator(this); + + m_SimulatorManager = new cSimulatorManager(); + m_SimulatorManager->RegisterSimulator(m_WaterSimulator, 6); + m_SimulatorManager->RegisterSimulator(m_LavaSimulator, 12); + m_SimulatorManager->RegisterSimulator(m_SandSimulator, 1); + m_SimulatorManager->RegisterSimulator(m_FireSimulator, 10); + m_SimulatorManager->RegisterSimulator(m_RedstoneSimulator, 1); +} + + + + + +void cWorld::SetWeather( eWeather a_Weather ) +{ + switch( a_Weather ) + { + case eWeather_Sunny: + { + m_Weather = a_Weather; + cPacket_NewInvalidState WeatherPacket; + WeatherPacket.m_Reason = 2; //stop rain + Broadcast ( WeatherPacket ); + } + break; + case eWeather_Rain: + { + m_Weather = a_Weather; + cPacket_NewInvalidState WeatherPacket; + WeatherPacket.m_Reason = 1; //begin rain + Broadcast ( WeatherPacket ); + } + break; + case eWeather_ThunderStorm: + { + m_Weather = a_Weather; + cPacket_NewInvalidState WeatherPacket; + WeatherPacket.m_Reason = 1; //begin rain + Broadcast ( WeatherPacket ); + CastThunderbolt ( 0, 0, 0 ); //start thunderstorm with a lightning strike at 0, 0, 0. >:D + } + break; + default: + LOGWARN("Trying to set unknown weather %d", a_Weather ); + break; + } +} + + + + + +void cWorld::CastThunderbolt ( int a_X, int a_Y, int a_Z ) +{ + cPacket_Thunderbolt ThunderboltPacket; + ThunderboltPacket.m_xLBPos = a_X; + ThunderboltPacket.m_yLBPos = a_Y; + ThunderboltPacket.m_zLBPos = a_Z; + BroadcastToChunkOfBlock(a_X, a_Y, a_Z, &ThunderboltPacket); +} + + + + + +bool cWorld::IsPlacingItemLegal(Int16 a_ItemType, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + BLOCKTYPE SurfaceBlock = GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); + switch (a_ItemType) + { + case E_BLOCK_YELLOW_FLOWER: // Can ONLY be placed on dirt/grass + case E_BLOCK_RED_ROSE: + case E_BLOCK_SAPLING: + { + switch (SurfaceBlock) + { + case E_BLOCK_DIRT: + case E_BLOCK_GRASS: + case E_BLOCK_FARMLAND: + { + return true; + } + } + return false; + } + + case E_BLOCK_BROWN_MUSHROOM: // Can be placed on pretty much anything, with exceptions + case E_BLOCK_RED_MUSHROOM: + { + switch (SurfaceBlock) + { + case E_BLOCK_GLASS: + case E_BLOCK_YELLOW_FLOWER: + case E_BLOCK_RED_ROSE: + case E_BLOCK_BROWN_MUSHROOM: + case E_BLOCK_RED_MUSHROOM: + case E_BLOCK_CACTUS: + { + return false; + } + } + return true; + } + + case E_BLOCK_CACTUS: + { + if ((SurfaceBlock != E_BLOCK_SAND) && (SurfaceBlock != E_BLOCK_CACTUS)) + { + // Cactus can only be placed on sand and itself + return false; + } + + // Check surroundings. Cacti may ONLY be surrounded by air + if ( + (GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) != E_BLOCK_AIR) || + (GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) != E_BLOCK_AIR) || + (GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) != E_BLOCK_AIR) || + (GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) != E_BLOCK_AIR) + ) + { + return false; + } + return true; + } + + case E_ITEM_SEEDS: + case E_ITEM_MELON_SEEDS: + case E_ITEM_PUMPKIN_SEEDS: + { + // Seeds can go only on the farmland block: + return (SurfaceBlock == E_BLOCK_FARMLAND); + } + } // switch (a_Packet->m_ItemType) + return true; +} + + + + + +void cWorld::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + return m_ChunkMap->SetNextBlockTick(a_BlockX, a_BlockY, a_BlockZ); +} + + + + + +void cWorld::InitializeSpawn(void) +{ + int ChunkX = 0, ChunkY = 0, ChunkZ = 0; + BlockToChunk( (int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ, ChunkX, ChunkY, ChunkZ ); + + // For the debugging builds, don't make the server build too much world upon start: + #ifdef _DEBUG + int ViewDist = 9; + #else + int ViewDist = 20; // Always prepare an area 20 chunks across, no matter what the actual cClientHandle::VIEWDISTANCE is + #endif // _DEBUG + + LOG("Preparing spawn area in world \"%s\"...", m_WorldName.c_str()); + for (int x = 0; x < ViewDist; x++) + { + for (int z = 0; z < ViewDist; z++) + { + m_ChunkMap->TouchChunk( x + ChunkX-(ViewDist - 1) / 2, ZERO_CHUNK_Y, z + ChunkZ-(ViewDist - 1) / 2 ); // Queue the chunk in the generator / loader + } + } + + { + // Display progress during this process: + cWorldLoadProgress Progress(this); + + // Wait for the loader to finish loading + m_Storage.WaitForQueuesEmpty(); + + // Wait for the generator to finish generating + m_Generator.WaitForQueueEmpty(); + + Progress.Stop(); + } + + // Light all chunks that have been newly generated: + LOG("Lighting spawn area in world \"%s\"...", m_WorldName.c_str()); + + for (int x = 0; x < ViewDist; x++) + { + int ChX = x + ChunkX-(ViewDist - 1) / 2; + for (int z = 0; z < ViewDist; z++) + { + int ChZ = z + ChunkZ-(ViewDist - 1) / 2; + if (!m_ChunkMap->IsChunkLighted(ChX, ChZ)) + { + m_Lighting.QueueChunk(ChX, ChZ); // Queue the chunk in the lighting thread + } + } // for z + } // for x + + { + cWorldLightingProgress Progress(&m_Lighting); + m_Lighting.WaitForQueueEmpty(); + Progress.Stop(); + } + + // TODO: Better spawn detection - move spawn out of the water if it isn't set in the INI already + m_SpawnY = (double)GetHeight( (int)m_SpawnX, (int)m_SpawnZ ) + 1.6f; // +1.6f eye height +} + + + + + +void cWorld::Tick(float a_Dt) +{ + m_Time += a_Dt / 1000.f; + + CurrentTick++; + + bool bSendTime = false; + m_WorldTimeFraction += a_Dt / 1000.f; + while ( m_WorldTimeFraction > 1.f ) + { + m_WorldTimeFraction -= 1.f; + m_WorldTime += 20; + bSendTime = true; + } + m_WorldTime %= 24000; // 24000 units in a day + if ( bSendTime ) + { + Broadcast( cPacket_TimeUpdate( (m_WorldTime) ) ); + } + + { + cCSLock Lock(m_CSEntities); + for (cEntityList::iterator itr = m_AllEntities.begin(); itr != m_AllEntities.end();) + { + if ((*itr)->IsDestroyed()) + { + LOG("Destroying entity #%i", (*itr)->GetUniqueID()); + cEntity * RemoveMe = *itr; + itr = m_AllEntities.erase( itr ); + m_RemoveEntityQueue.push_back( RemoveMe ); + continue; + } + (*itr)->Tick(a_Dt); + itr++; + } + } + + m_ChunkMap->Tick(a_Dt, m_TickRand); + + GetSimulatorManager()->Simulate(a_Dt); + + TickWeather(a_Dt); + + // Asynchronously set blocks: + sSetBlockList FastSetBlockQueueCopy; + { + cCSLock Lock(m_CSFastSetBlock); + std::swap(FastSetBlockQueueCopy, m_FastSetBlockQueue); + } + m_ChunkMap->FastSetBlocks(FastSetBlockQueueCopy); + if (!FastSetBlockQueueCopy.empty()) + { + // Some blocks failed, store them for next tick: + cCSLock Lock(m_CSFastSetBlock); + m_FastSetBlockQueue.splice(m_FastSetBlockQueue.end(), FastSetBlockQueueCopy); + } + + if( m_Time - m_LastSave > 60 * 5 ) // Save each 5 minutes + { + SaveAllChunks(); + } + + if( m_Time - m_LastUnload > 10 ) // Unload every 10 seconds + { + UnloadUnusedChunks(); + } + + // Delete entities queued for removal: + for (cEntityList::iterator itr = m_RemoveEntityQueue.begin(); itr != m_RemoveEntityQueue.end(); ++itr) + { + delete *itr; + } + m_RemoveEntityQueue.clear(); + + TickSpawnMobs(a_Dt); + + std::vector<int> m_RSList_copy(m_RSList); + + m_RSList.clear(); + + std::vector<int>::const_iterator cii; // FIXME - Please rename this variable, WTF is cii??? Use human readable variable names or common abbreviations (i, idx, itr, iter) + for(cii=m_RSList_copy.begin(); cii!=m_RSList_copy.end();) + { + int tempX = *cii;cii++; + int tempY = *cii;cii++; + int tempZ = *cii;cii++; + int state = *cii;cii++; + + if ( (state == 11111) && ( (int)GetBlock( tempX, tempY, tempZ ) == E_BLOCK_REDSTONE_TORCH_OFF ) ) + { + FastSetBlock( tempX, tempY, tempZ, E_BLOCK_REDSTONE_TORCH_ON, (int)GetBlockMeta( tempX, tempY, tempZ ) ); + cRedstone Redstone(this); + Redstone.ChangeRedstone( tempX, tempY, tempZ, true ); + } + else if ( (state == 00000) && ( (int)GetBlock( tempX, tempY, tempZ ) == E_BLOCK_REDSTONE_TORCH_ON ) ) + { + FastSetBlock( tempX, tempY, tempZ, E_BLOCK_REDSTONE_TORCH_OFF, (int)GetBlockMeta( tempX, tempY, tempZ ) ); + cRedstone Redstone(this); + Redstone.ChangeRedstone( tempX, tempY, tempZ, false ); + } + } + m_RSList_copy.erase(m_RSList_copy.begin(),m_RSList_copy.end()); +} + + + + + +void cWorld::ChangeWeather() +{ + unsigned randWeather = (m_TickRand.randInt() % 99); + + if (GetWeather() == eWeather_Sunny) + { + if (randWeather < 20) + { + LOG("Starting rainstorm!"); + SetWeather( eWeather_Rain ); + } + } + + else if (GetWeather() == eWeather_Rain) + { + if (randWeather < 5) + { + LOG("Thunderstorm!"); + SetWeather( eWeather_ThunderStorm ); + } + + else if (randWeather < 60) + { + LOG("Back to sunshine"); + SetWeather( eWeather_Sunny ); + } + } + + else if (GetWeather() == eWeather_ThunderStorm) + { + if (randWeather < 70) + { + SetWeather(eWeather_Sunny); + LOG("Thunder ended abruptly, returning to lovely sunshine"); + } + else if (randWeather < 85) + { + SetWeather(eWeather_Rain); + LOG("Thunder ended, but rain persists."); + } + else + { + return; + } + } +} + + + + + +void cWorld::TickWeather(float a_Dt) +{ + if(m_WeatherInterval == 0) + { + ChangeWeather(); + + cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::HOOK_WEATHER_CHANGE, 0 ); + + switch(GetWeather()) + { + case eWeather_Sunny: + m_WeatherInterval = 14400 + (m_TickRand.randInt() % 4800); // 12 - 16 minutes + break; + case eWeather_Rain: + m_WeatherInterval = 9600 + (m_TickRand.randInt() % 7200); // 8 - 14 minutes + break; + case eWeather_ThunderStorm: + m_WeatherInterval = 2400 + (m_TickRand.randInt() % 4800); // 2 - 6 minutes + break; + default: + LOG("Unknown weather occurred"); + break; + } + } + + else + { + m_WeatherInterval--; + } + + if ( GetWeather() == 2 ) // if thunderstorm + { + if (m_TickRand.randInt() % 199 == 0) // 0.5% chance per tick of thunderbolt + { + CastThunderbolt ( 0, 0, 0 ); // TODO: find random possitions near players to cast thunderbolts. + } + } +} + + + + + +void cWorld::TickSpawnMobs(float a_Dt) +{ + if (!m_bAnimals || (m_Time - m_SpawnMonsterTime <= m_SpawnMonsterRate)) + { + return; + } + + m_SpawnMonsterTime = m_Time; + Vector3d SpawnPos; + { + cCSLock Lock(m_CSPlayers); + if ( m_Players.size() <= 0) + { + return; + } + int RandomPlayerIdx = m_TickRand.randInt() & m_Players.size(); + cPlayerList::iterator itr = m_Players.begin(); + for( int i = 1; i < RandomPlayerIdx; i++ ) + { + itr++; + } + SpawnPos = (*itr)->GetPosition(); + } + + cMonster * Monster = NULL; + int dayRand = m_TickRand.randInt() % 6; + int nightRand = m_TickRand.randInt() % 10; + + SpawnPos += Vector3d( (double)(m_TickRand.randInt() % 64) - 32, (double)(m_TickRand.randInt() % 64) - 32, (double)(m_TickRand.randInt() % 64) - 32 ); + int Height = GetHeight( (int)SpawnPos.x, (int)SpawnPos.z ); + + if (m_WorldTime >= 12000 + 1000) + { + if (nightRand == 0) //random percent to spawn for night + Monster = new cSpider(); + else if (nightRand == 1) + Monster = new cZombie(); + else if (nightRand == 2) + Monster = new cEnderman(); + else if (nightRand == 3) + Monster = new cCreeper(); + else if (nightRand == 4) + Monster = new cCavespider(); + else if (nightRand == 5) + Monster = new cGhast(); + else if (nightRand == 6) + Monster = new cZombiepigman(); + else if (nightRand == 7) + Monster = new cSlime(); + else if (nightRand == 8) + Monster = new cSilverfish(); + else if (nightRand == 9) + Monster = new cSkeleton(); + //end random percent to spawn for night + } + else + { + if (dayRand == 0) //random percent to spawn for day + Monster = new cChicken(); + else if (dayRand == 1) + Monster = new cCow(); + else if (dayRand == 2) + Monster = new cPig(); + else if (dayRand == 3) + Monster = new cSheep(); + else if (dayRand == 4) + Monster = new cSquid(); + else if (dayRand == 5) + Monster = new cWolf(); + //end random percent to spawn for day + } + + if( Monster ) + { + Monster->Initialize( this ); + Monster->TeleportTo( SpawnPos.x, (double)(Height) + 2, SpawnPos.z ); + Monster->SpawnOn(0); + } +} + + + + + +void cWorld::GrowTree( int a_X, int a_Y, int a_Z ) +{ + if (GetBlock(a_X, a_Y, a_Z) == E_BLOCK_SAPLING) + { + // There is a sapling here, grow a tree according to its type: + GrowTreeFromSapling(a_X, a_Y, a_Z, GetBlockMeta(a_X, a_Y, a_Z)); + } + else + { + // There is nothing here, grow a tree based on the current biome here: + GrowTreeByBiome(a_X, a_Y, a_Z); + } +} + + + + + +void cWorld::GrowTreeFromSapling(int a_X, int a_Y, int a_Z, char a_SaplingMeta) +{ + cNoise Noise(m_Generator.GetSeed()); + sSetBlockVector Blocks; + switch (a_SaplingMeta & 0x07) + { + case E_META_SAPLING_APPLE: GetAppleTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break; + case E_META_SAPLING_BIRCH: GetBirchTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break; + case E_META_SAPLING_CONIFER: GetConiferTreeImage(a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break; + case E_META_SAPLING_JUNGLE: GetJungleTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), Blocks); break; + } + + GrowTreeImage(Blocks); +} + + + + + +void cWorld::GrowTreeByBiome(int a_X, int a_Y, int a_Z) +{ + cNoise Noise(m_Generator.GetSeed()); + sSetBlockVector Blocks; + GetTreeImageByBiome(a_X, a_Y, a_Z, Noise, (int)(m_WorldTime & 0xffffffff), (EMCSBiome)GetBiomeAt(a_X, a_Z), Blocks); + GrowTreeImage(Blocks); +} + + + + + +void cWorld::GrowTreeImage(const sSetBlockVector & a_Blocks) +{ + // Check that the tree has place to grow + + // Make a copy of the log blocks: + sSetBlockVector b2; + for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) + { + if (itr->BlockType == E_BLOCK_LOG) + { + b2.push_back(*itr); + } + } // for itr - a_Blocks[] + + // Query blocktypes and metas at those log blocks: + if (!GetBlocks(b2, false)) + { + return; + } + + // Check that at each log's coord there's an block allowed to be overwritten: + for (sSetBlockVector::const_iterator itr = b2.begin(); itr != b2.end(); ++itr) + { + switch (itr->BlockType) + { + CASE_TREE_ALLOWED_BLOCKS: + { + break; + } + default: + { + return; + } + } + } // for itr - b2[] + + // All ok, replace blocks with the tree image: + m_ChunkMap->ReplaceTreeBlocks(a_Blocks); +} + + + + + +bool cWorld::GrowPlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsByBonemeal) +{ + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta); + switch (BlockType) + { + case E_BLOCK_CROPS: + { + if (a_IsByBonemeal && !m_IsGrassBonemealable) + { + return false; + } + if (BlockMeta < 7) + { + FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, 7); + } + return true; + } + + case E_BLOCK_MELON_STEM: + { + if (BlockMeta < 7) + { + if (a_IsByBonemeal && !m_IsMelonStemBonemealable) + { + return false; + } + FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, 7); + } + else + { + if (a_IsByBonemeal && !m_IsMelonBonemealable) + { + return false; + } + GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, BlockType); + } + return true; + } + + case E_BLOCK_PUMPKIN_STEM: + { + if (BlockMeta < 7) + { + if (a_IsByBonemeal && !m_IsPumpkinStemBonemealable) + { + return false; + } + FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, 7); + } + else + { + if (a_IsByBonemeal && !m_IsPumpkinBonemealable) + { + return false; + } + GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, BlockType); + } + return true; + } + + case E_BLOCK_SAPLING: + { + if (a_IsByBonemeal && !m_IsSaplingBonemealable) + { + return false; + } + GrowTreeFromSapling(a_BlockX, a_BlockY, a_BlockZ, BlockMeta); + return true; + } + + case E_BLOCK_GRASS: + { + if (a_IsByBonemeal && !m_IsGrassBonemealable) + { + return false; + } + MTRand r1; + for (int i = 0; i < 60; i++) + { + int OfsX = (r1.randInt(3) + r1.randInt(3) + r1.randInt(3) + r1.randInt(3)) / 2 - 3; + int OfsY = r1.randInt(3) + r1.randInt(3) - 3; + int OfsZ = (r1.randInt(3) + r1.randInt(3) + r1.randInt(3) + r1.randInt(3)) / 2 - 3; + BLOCKTYPE Ground = GetBlock(a_BlockX + OfsX, a_BlockY + OfsY, a_BlockZ + OfsZ); + if (Ground != E_BLOCK_GRASS) + { + continue; + } + BLOCKTYPE Above = GetBlock(a_BlockX + OfsX, a_BlockY + OfsY + 1, a_BlockZ + OfsZ); + if (Above != E_BLOCK_AIR) + { + continue; + } + BLOCKTYPE SpawnType; + NIBBLETYPE SpawnMeta = 0; + switch (r1.randInt(10)) + { + case 0: SpawnType = E_BLOCK_YELLOW_FLOWER; break; + case 1: SpawnType = E_BLOCK_RED_ROSE; break; + default: + { + SpawnType = E_BLOCK_TALL_GRASS; + SpawnMeta = E_META_TALL_GRASS_GRASS; + break; + } + } // switch (random spawn block) + FastSetBlock(a_BlockX + OfsX, a_BlockY + OfsY + 1, a_BlockZ + OfsZ, SpawnType, SpawnMeta); + } // for i - 50 times + return true; + } + + case E_BLOCK_SUGARCANE: + { + if (a_IsByBonemeal && !m_IsSugarcaneBonemealable) + { + return false; + } + m_ChunkMap->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, m_MaxSugarcaneHeight); + return true; + } + + case E_BLOCK_CACTUS: + { + if (a_IsByBonemeal && !m_IsCactusBonemealable) + { + return false; + } + m_ChunkMap->GrowCactus(a_BlockX, a_BlockY, a_BlockZ, m_MaxCactusHeight); + return true; + } + } // switch (BlockType) + return false; +} + + + + + +void cWorld::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockType) +{ + MTRand Rand; + m_ChunkMap->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, Rand); +} + + + + + +int cWorld::GetBiomeAt (int a_BlockX, int a_BlockZ) +{ + return m_ChunkMap->GetBiomeAt(a_BlockX, a_BlockZ); +} + + + + + +void cWorld::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ) +{ + m_ChunkMap->SetBlock(a_X, a_Y, a_Z, a_BlockType, a_BlockMeta); + + GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z); +} + + + + + +void cWorld::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ) +{ + cCSLock Lock(m_CSFastSetBlock); + m_FastSetBlockQueue.push_back(sSetBlock(a_X, a_Y, a_Z, a_BlockType, a_BlockMeta)); +} + + + + + +char cWorld::GetBlock(int a_X, int a_Y, int a_Z) +{ + // First check if it isn't queued in the m_FastSetBlockQueue: + { + int X = a_X, Y = a_Y, Z = a_Z; + int ChunkX, ChunkY, ChunkZ; + AbsoluteToRelative(X, Y, Z, ChunkX, ChunkY, ChunkZ); + + cCSLock Lock(m_CSFastSetBlock); + for (sSetBlockList::iterator itr = m_FastSetBlockQueue.begin(); itr != m_FastSetBlockQueue.end(); ++itr) + { + if ((itr->x == X) && (itr->y == Y) && (itr->z == Z) && (itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ)) + { + return itr->BlockType; + } + } // for itr - m_FastSetBlockQueue[] + } + + return m_ChunkMap->GetBlock(a_X, a_Y, a_Z); +} + + + + + +char cWorld::GetBlockMeta( int a_X, int a_Y, int a_Z ) +{ + // First check if it isn't queued in the m_FastSetBlockQueue: + { + cCSLock Lock(m_CSFastSetBlock); + for (sSetBlockList::iterator itr = m_FastSetBlockQueue.begin(); itr != m_FastSetBlockQueue.end(); ++itr) + { + if ((itr->x == a_X) && (itr->y == a_Y) && (itr->y == a_Y)) + { + return itr->BlockMeta; + } + } // for itr - m_FastSetBlockQueue[] + } + + return m_ChunkMap->GetBlockMeta(a_X, a_Y, a_Z); +} + + + + + +void cWorld::SetBlockMeta( int a_X, int a_Y, int a_Z, char a_MetaData ) +{ + m_ChunkMap->SetBlockMeta(a_X, a_Y, a_Z, a_MetaData); +} + + + + + +char cWorld::GetBlockSkyLight( int a_X, int a_Y, int a_Z ) +{ + return m_ChunkMap->GetBlockSkyLight(a_X, a_Y, a_Z); +} + + + + + +void cWorld::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, char & a_BlockType, unsigned char & a_BlockMeta) +{ + m_ChunkMap->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, (BLOCKTYPE &)a_BlockType, (NIBBLETYPE &)a_BlockMeta); +} + + + + + +void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed) +{ + MTRand r1; + a_FlyAwaySpeed /= 1000; // Pre-divide, so that we can don't have to divide each time inside the loop + for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr) + { + float SpeedX = (float)(a_FlyAwaySpeed * (r1.randInt(1000) - 500)); + float SpeedY = (float)(a_FlyAwaySpeed * r1.randInt(1000)); + float SpeedZ = (float)(a_FlyAwaySpeed * (r1.randInt(1000) - 500)); + cPickup * Pickup = new cPickup( + (int)(a_BlockX * 32) + r1.randInt(16) + r1.randInt(16), + (int)(a_BlockY * 32) + r1.randInt(16) + r1.randInt(16), + (int)(a_BlockZ * 32) + r1.randInt(16) + r1.randInt(16), + *itr, SpeedX, SpeedY, SpeedZ + ); + Pickup->Initialize(this); + } +} + + + + + +void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ) +{ + MTRand r1; + for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr) + { + cPickup * Pickup = new cPickup( + (int)(a_BlockX * 32) + r1.randInt(16) + r1.randInt(16), + (int)(a_BlockY * 32) + r1.randInt(16) + r1.randInt(16), + (int)(a_BlockZ * 32) + r1.randInt(16) + r1.randInt(16), + *itr, (float)a_SpeedX, (float)a_SpeedY, (float)a_SpeedZ + ); + Pickup->Initialize(this); + } +} + + + + + +void cWorld::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType) +{ + m_ChunkMap->ReplaceBlocks(a_Blocks, a_FilterBlockType); +} + + + + + +bool cWorld::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) +{ + return m_ChunkMap->GetBlocks(a_Blocks, a_ContinueOnFailure); +} + + + + + +bool cWorld::DigBlock( int a_X, int a_Y, int a_Z) +{ + return m_ChunkMap->DigBlock(a_X, a_Y, a_Z); +} + + + + + +void cWorld::SendBlockTo( int a_X, int a_Y, int a_Z, cPlayer * a_Player ) +{ + m_ChunkMap->SendBlockTo(a_X, a_Y, a_Z, a_Player); +} + + + + + +// TODO: This interface is dangerous! +cBlockEntity * cWorld::GetBlockEntity( int a_X, int a_Y, int a_Z ) +{ + return NULL; +} + + + + + +int cWorld::GetHeight( int a_X, int a_Z ) +{ + return m_ChunkMap->GetHeight(a_X, a_Z); +} + + + + + +const double & cWorld::GetSpawnY(void) +{ + return m_SpawnY; +} + + + + +void cWorld::Broadcast( const cPacket & a_Packet, cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSPlayers); + for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + cClientHandle * ch = (*itr)->GetClientHandle(); + if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + { + continue; + } + (*itr)->GetClientHandle()->Send( a_Packet ); + } +} + + + + + +void cWorld::BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude) +{ + m_ChunkMap->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Packet, a_Exclude); +} + + + + + +void cWorld::BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude) +{ + m_ChunkMap->BroadcastToChunkOfBlock(a_X, a_Y, a_Z, a_Packet, a_Exclude); +} + + + + + +void cWorld::MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + m_ChunkMap->MarkChunkDirty (a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + m_ChunkMap->MarkChunkSaving(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + m_ChunkMap->MarkChunkSaved (a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::SetChunkData( + int a_ChunkX, int a_ChunkY, int a_ChunkZ, + const BLOCKTYPE * a_BlockTypes, + const NIBBLETYPE * a_BlockMeta, + const NIBBLETYPE * a_BlockLight, + const NIBBLETYPE * a_BlockSkyLight, + const cChunkDef::HeightMap * a_HeightMap, + const cChunkDef::BiomeMap * a_BiomeMap, + cEntityList & a_Entities, + cBlockEntityList & a_BlockEntities, + bool a_MarkDirty +) +{ + // Validate biomes, if needed: + cChunkDef::BiomeMap BiomeMap; + const cChunkDef::BiomeMap * Biomes = a_BiomeMap; + if (a_BiomeMap == NULL) + { + // The biomes are not assigned, get them from the generator: + Biomes = &BiomeMap; + m_Generator.GenerateBiomes(a_ChunkX, a_ChunkZ, BiomeMap); + } + + m_ChunkMap->SetChunkData( + a_ChunkX, a_ChunkY, a_ChunkZ, + a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, + a_HeightMap, *Biomes, + a_Entities, a_BlockEntities, + a_MarkDirty + ); + + // If a client is requesting this chunk, send it to them: + if (m_ChunkMap->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ)) + { + m_ChunkSender.ChunkReady(a_ChunkX, a_ChunkY, a_ChunkZ); + } + + // Notify the lighting thread that the chunk has become valid (in case it is a neighbor of a postponed chunk): + m_Lighting.ChunkReady(a_ChunkX, a_ChunkZ); +} + + + + + +void cWorld::ChunkLighted( + int a_ChunkX, int a_ChunkZ, + const cChunkDef::BlockNibbles & a_BlockLight, + const cChunkDef::BlockNibbles & a_SkyLight +) +{ + m_ChunkMap->ChunkLighted(a_ChunkX, a_ChunkZ, a_BlockLight, a_SkyLight); +} + + + + + +bool cWorld::GetChunkData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback) +{ + return m_ChunkMap->GetChunkData(a_ChunkX, a_ChunkY, a_ChunkZ, a_Callback); +} + + + + + +bool cWorld::GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes) +{ + return m_ChunkMap->GetChunkBlockTypes(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockTypes); +} + + + + + +bool cWorld::GetChunkBlockData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData) +{ + return m_ChunkMap->GetChunkBlockData(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockData); +} + + + + + +bool cWorld::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const +{ + return m_ChunkMap->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +bool cWorld::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const +{ + return m_ChunkMap->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::UnloadUnusedChunks(void ) +{ + m_LastUnload = m_Time; + m_ChunkMap->UnloadUnusedChunks(); +} + + + + + +void cWorld::CollectPickupsByPlayer(cPlayer * a_Player) +{ + m_ChunkMap->CollectPickupsByPlayer(a_Player); +} + + + + + +void cWorld::SetMaxPlayers(int iMax) +{ + m_MaxPlayers = MAX_PLAYERS; + if (iMax > 0 && iMax < MAX_PLAYERS) + { + m_MaxPlayers = iMax; + } +} + + + + + +void cWorld::AddPlayer( cPlayer* a_Player ) +{ + cCSLock Lock(m_CSPlayers); + + ASSERT(std::find(m_Players.begin(), m_Players.end(), a_Player) == m_Players.end()); // Is it already in the list? HOW? + + m_Players.remove( a_Player ); // Make sure the player is registered only once + m_Players.push_back( a_Player ); +} + + + + + +void cWorld::RemovePlayer( cPlayer* a_Player ) +{ + cCSLock Lock(m_CSPlayers); + m_Players.remove( a_Player ); +} + + + + + +bool cWorld::ForEachPlayer(cPlayerListCallback & a_Callback) +{ + // Calls the callback for each player in the list + cCSLock Lock(m_CSPlayers); + for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + if (a_Callback.Item(*itr)) + { + return false; + } + } // for itr - m_Players[] + return true; +} + + + + +// TODO: This interface is dangerous! +cPlayer* cWorld::GetPlayer( const char* a_PlayerName ) +{ + cPlayer* BestMatch = 0; + unsigned int MatchedLetters = 0; + unsigned int NumMatches = 0; + bool bPerfectMatch = false; + + unsigned int NameLength = strlen( a_PlayerName ); + cCSLock Lock(m_CSPlayers); + for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); itr++ ) + { + std::string Name = (*itr)->GetName(); + if( NameLength > Name.length() ) continue; // Definitely not a match + + for (unsigned int i = 0; i < NameLength; i++) + { + char c1 = (char)toupper( a_PlayerName[i] ); + char c2 = (char)toupper( Name[i] ); + if( c1 == c2 ) + { + if( i+1 > MatchedLetters ) + { + MatchedLetters = i+1; + BestMatch = *itr; + } + if( i+1 == NameLength ) + { + NumMatches++; + if( NameLength == Name.length() ) + { + bPerfectMatch = true; + break; + } + } + } + else + { + if( BestMatch == *itr ) BestMatch = 0; + break; + } + if( bPerfectMatch ) + break; + } + } + if ( NumMatches == 1 ) + { + return BestMatch; + } + + // More than one matches, so it's undefined. Return NULL instead + return NULL; +} + + + + + +cPlayer * cWorld::FindClosestPlayer(const Vector3f & a_Pos, float a_SightLimit) +{ + cTracer LineOfSight(this); + + float ClosestDistance = a_SightLimit; + cPlayer* ClosestPlayer = NULL; + + cCSLock Lock(m_CSPlayers); + for (cPlayerList::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + Vector3f Pos = (*itr)->GetPosition(); + float Distance = (Pos - a_Pos).Length(); + + if (Distance <= a_SightLimit) + { + if (!LineOfSight.Trace(a_Pos,(Pos - a_Pos),(int)(Pos - a_Pos).Length())) + { + if (Distance < ClosestDistance) + { + ClosestDistance = Distance; + ClosestPlayer = *itr; + } + } + } + } + return ClosestPlayer; +} + + + + + +void cWorld::SendPlayerList(cPlayer * a_DestPlayer) +{ + // Sends the playerlist to a_DestPlayer + cCSLock Lock(m_CSPlayers); + for ( cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + cClientHandle * ch = (*itr)->GetClientHandle(); + if ((ch != NULL) && !ch->IsDestroyed()) + { + cPacket_PlayerListItem PlayerListItem((*itr)->GetColor() + (*itr)->GetName(), true, (*itr)->GetClientHandle()->GetPing()); + a_DestPlayer->GetClientHandle()->Send( PlayerListItem ); + } + } +} + + + + + +bool cWorld::DoWithEntity( int a_UniqueID, cEntityCallback & a_Callback ) +{ + cCSLock Lock(m_CSEntities); + for (cEntityList::iterator itr = m_AllEntities.begin(); itr != m_AllEntities.end(); ++itr ) + { + if( (*itr)->GetUniqueID() == a_UniqueID ) + { + return a_Callback.Item(*itr); + } + } // for itr - m_AllEntities[] + return false; +} + + + + + +void cWorld::RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + m_ChunkMap->RemoveEntityFromChunk(a_Entity, a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + m_ChunkMap->MoveEntityToChunk(a_Entity, a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback) +{ + m_ChunkMap->CompareChunkClients(a_ChunkX1, a_ChunkY1, a_ChunkZ1, a_ChunkX2, a_ChunkY2, a_ChunkZ2, a_Callback); +} + + + + + +bool cWorld::AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +{ + return m_ChunkMap->AddChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client); +} + + + + + +void cWorld::RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +{ + m_ChunkMap->RemoveChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client); +} + + + + + +void cWorld::RemoveClientFromChunks(cClientHandle * a_Client) +{ + m_ChunkMap->RemoveClientFromChunks(a_Client); +} + + + + + +void cWorld::SendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +{ + m_ChunkSender.QueueSendChunkTo(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client); +} + + + + + +void cWorld::RemoveClientFromChunkSender(cClientHandle * a_Client) +{ + m_ChunkSender.RemoveClient(a_Client); +} + + + + + +void cWorld::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + m_ChunkMap->TouchChunk(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +bool cWorld::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + return m_ChunkMap->LoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::LoadChunks(const cChunkCoordsList & a_Chunks) +{ + m_ChunkMap->LoadChunks(a_Chunks); +} + + + + + +void cWorld::ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + m_ChunkMap->ChunkLoadFailed(a_ChunkX, a_ChunkY, a_ChunkZ); +} + + + + + +void cWorld::UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) +{ + m_ChunkMap->UpdateSign(a_X, a_Y, a_Z, a_Line1, a_Line2, a_Line3, a_Line4); +} + + + + + +void cWorld::ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay) +{ + m_ChunkMap->ChunksStay(a_Chunks, a_Stay); +} + + + + + +void cWorld::RegenerateChunk(int a_ChunkX, int a_ChunkZ) +{ + m_ChunkMap->MarkChunkRegenerating(a_ChunkX, a_ChunkZ); + + // Trick: use Y=1 to force the chunk generation even though the chunk data is already present + m_Generator.QueueGenerateChunk(a_ChunkX, 1, a_ChunkZ); +} + + + + + +void cWorld::GenerateChunk(int a_ChunkX, int a_ChunkZ) +{ + m_Generator.QueueGenerateChunk(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); +} + + + + + +void cWorld::QueueLightChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback) +{ + m_Lighting.QueueChunk(a_ChunkX, a_ChunkZ, a_Callback); +} + + + + + +bool cWorld::IsChunkLighted(int a_ChunkX, int a_ChunkZ) +{ + return m_ChunkMap->IsChunkLighted(a_ChunkX, a_ChunkZ); +} + + + + + +void cWorld::SaveAllChunks(void) +{ + LOG("Saving all chunks..."); + m_LastSave = m_Time; + m_ChunkMap->SaveAllChunks(); +} + + + + + +/************************************************************************/ +/* Get and set */ +/************************************************************************/ +// void cWorld::AddClient( cClientHandle* a_Client ) +// { +// m_m_Clients.push_back( a_Client ); +// } +// cWorld::ClientList & cWorld::GetClients() +// { +// return m_m_Clients; +// } + + + + + +void cWorld::AddEntity( cEntity* a_Entity ) +{ + cCSLock Lock(m_CSEntities); + m_AllEntities.push_back( a_Entity ); +} + + + + + +unsigned int cWorld::GetNumPlayers() +{ + cCSLock Lock(m_CSPlayers); + return m_Players.size(); +} + + + + + +int cWorld::GetNumChunks(void) const +{ + return m_ChunkMap->GetNumChunks(); +} + + + + + +void cWorld::GetChunkStats(int & a_NumValid, int & a_NumDirty, int & a_NumInLightingQueue) +{ + m_ChunkMap->GetChunkStats(a_NumValid, a_NumDirty); + a_NumInLightingQueue = (int) m_Lighting.GetQueueLength(); +} + + + + diff --git a/source/cWorld.h b/source/cWorld.h index 7c4e8b654..e557a56ed 100644 --- a/source/cWorld.h +++ b/source/cWorld.h @@ -1,408 +1,408 @@ -
-#pragma once
-
-#ifndef _WIN32
- #include "BlockID.h"
-#else
- enum ENUM_ITEM_ID;
-#endif
-
-#define MAX_PLAYERS 65535
-
-#include "cSimulatorManager.h"
-#include "MersenneTwister.h"
-#include "cChunkMap.h"
-#include "WorldStorage.h"
-#include "cChunkGenerator.h"
-#include "Vector3i.h"
-#include "Vector3f.h"
-#include "ChunkSender.h"
-#include "Defines.h"
-#include "LightingThread.h"
-#include "cItem.h"
-
-
-
-
-
-class cPacket;
-class cRedstone;
-class cFireSimulator;
-class cWaterSimulator;
-class cLavaSimulator;
-class cSandSimulator;
-class cRedstoneSimulator;
-class cItem;
-class cPlayer;
-class cClientHandle;
-class cEntity;
-class cBlockEntity;
-class cWorldGenerator; // The generator that actually generates the chunks for a single world
-class cChunkGenerator; // The thread responsible for generating chunks
-typedef std::list< cPlayer * > cPlayerList;
-typedef cItemCallback<cPlayer> cPlayerListCallback;
-typedef cItemCallback<cEntity> cEntityCallback;
-
-
-
-
-
-class cWorld //tolua_export
-{ //tolua_export
-public:
-
- OBSOLETE static cWorld* GetWorld();
-
- // Return time in seconds
- inline static float GetTime() //tolua_export
- {
- return m_Time;
- }
- long long GetWorldTime(void) const { return m_WorldTime; } //tolua_export
-
- eGameMode GetGameMode(void) const { return m_GameMode; } //tolua_export
-
- void SetWorldTime(long long a_WorldTime) { m_WorldTime = a_WorldTime; } //tolua_export
-
- int GetHeight( int a_X, int a_Z ); //tolua_export
-
- void Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude = 0 );
- void BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude = NULL);
- void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude = NULL);
-
- void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- /** Sets the chunk data as either loaded from the storage or generated.
- a_BlockLight and a_BlockSkyLight are optional, if not present, chunk will be marked as unlighted.
- a_BiomeMap is optional, if not present, biomes will be calculated by the generator
- a_HeightMap is optional, if not present, will be calculated.
- If a_MarkDirty is set, the chunk is set as dirty (used after generating)
- */
- void SetChunkData(
- int a_ChunkX, int a_ChunkY, int a_ChunkZ,
- const BLOCKTYPE * a_BlockTypes,
- const NIBBLETYPE * a_BlockMeta,
- const NIBBLETYPE * a_BlockLight,
- const NIBBLETYPE * a_BlockSkyLight,
- const cChunkDef::HeightMap * a_HeightMap,
- const cChunkDef::BiomeMap * a_BiomeMap,
- cEntityList & a_Entities,
- cBlockEntityList & a_BlockEntities,
- bool a_MarkDirty
- );
-
- void ChunkLighted(
- int a_ChunkX, int a_ChunkZ,
- const cChunkDef::BlockNibbles & a_BlockLight,
- const cChunkDef::BlockNibbles & a_SkyLight
- );
-
- bool GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback);
-
- /// Gets the chunk's blocks, only the block types
- bool GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes);
-
- /// Gets the chunk's blockdata, the entire 4 arrays (Types, Meta, Light, SkyLight)
- bool GetChunkBlockData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData);
-
- bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
- bool HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
-
- void UnloadUnusedChunks(void); // tolua_export
-
- void CollectPickupsByPlayer(cPlayer * a_Player);
-
- // MOTD
- const AString & GetDescription(void) const {return m_Description; } // FIXME: This should not be in cWorld
-
- // Max Players
- unsigned int GetMaxPlayers(void) const {return m_MaxPlayers; } //tolua_export
- void SetMaxPlayers(int iMax); //tolua_export
-
- void AddPlayer( cPlayer* a_Player );
- void RemovePlayer( cPlayer* a_Player );
-
- bool ForEachPlayer(cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
-
- unsigned int GetNumPlayers(); //tolua_export
-
- // TODO: This interface is dangerous - rewrite to DoWithPlayer(playername, action)
- cPlayer * GetPlayer( const char * a_PlayerName ); //tolua_export
-
- // TODO: This interface is dangerous - rewrite to DoWithClosestPlayer(pos, sight, action)
- cPlayer * FindClosestPlayer(const Vector3f & a_Pos, float a_SightLimit);
-
- void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player
-
- void AddEntity( cEntity* a_Entity );
-
- /// Add an entity to the chunk specified; broadcasts the a_SpawnPacket to all clients of that chunk
- void AddEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ, cPacket * a_SpawnPacket);
-
- /// Removes the entity from the chunk specified
- void RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- /// Moves the entity from its current chunk to the new chunk specified
- void MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- /// Compares clients of two chunks, calls the callback accordingly
- void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback);
-
- /// Adds client to a chunk, if not already present; returns true if added, false if present
- bool AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
-
- /// Removes client from the chunk specified
- void RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
-
- /// Removes the client from all chunks it is present in
- void RemoveClientFromChunks(cClientHandle * a_Client);
-
- /// Sends the chunk to the client specified, if the chunk is valid. If not valid, the request is postponed (ChunkSender will send that chunk when it becomes valid+lighted)
- void SendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
-
- /// Removes client from ChunkSender's queue of chunks to be sent
- void RemoveClientFromChunkSender(cClientHandle * a_Client);
-
- /// Touches the chunk, causing it to be loaded or generated
- void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- /// Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before)
- bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- /// Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid()
- void LoadChunks(const cChunkCoordsList & a_Chunks);
-
- /// Marks the chunk as failed-to-load:
- void ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
-
- void UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); //tolua_export
-
- /// Marks (a_Stay == true) or unmarks (a_Stay == false) chunks as non-unloadable. To be used only by cChunkStay!
- void ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay = true);
-
- /// Regenerate the given chunk:
- void RegenerateChunk(int a_ChunkX, int a_ChunkZ); //tolua_export
-
- /// Generates the given chunk, if not already generated
- void GenerateChunk(int a_ChunkX, int a_ChunkZ); //tolua_export
-
- /// Queues a chunk for lighting; a_Callback is called after the chunk is lighted
- void QueueLightChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback = NULL);
-
- bool IsChunkLighted(int a_ChunkX, int a_ChunkZ);
-
- // TODO: Export to Lua
- bool DoWithEntity( int a_UniqueID, cEntityCallback & a_Callback );
-
- void SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ); //tolua_export
- void FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ); //tolua_export
- char GetBlock( int a_X, int a_Y, int a_Z ); //tolua_export
- char GetBlock( const Vector3i & a_Pos ) { return GetBlock( a_Pos.x, a_Pos.y, a_Pos.z ); } //tolua_export
- char GetBlockMeta( int a_X, int a_Y, int a_Z ); //tolua_export
- char GetBlockMeta( const Vector3i & a_Pos ) { return GetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z ); } //tolua_export
- void SetBlockMeta( int a_X, int a_Y, int a_Z, char a_MetaData ); //tolua_export
- void SetBlockMeta( const Vector3i & a_Pos, char a_MetaData ) { SetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z, a_MetaData ); } //tolua_export
- char GetBlockSkyLight( int a_X, int a_Y, int a_Z ); //tolua_export
- // TODO: char GetBlockActualLight(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export
- void GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, char & a_BlockType, unsigned char & a_BlockMeta); // tolua_export
-
- /// Spawns item pickups for each item in the list. May compress pickups if too many entities:
- void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed = 1.0);
-
- /// Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified:
- void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ);
-
- /// Replaces world blocks with a_Blocks, if they are of type a_FilterBlockType
- void ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType);
-
- /// Retrieves block types of the specified blocks. If a chunk is not loaded, doesn't modify the block. Returns true if all blocks were read.
- bool GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure);
-
- bool DigBlock (int a_X, int a_Y, int a_Z); //tolua_export
- void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player ); //tolua_export
-
- const double & GetSpawnX() { return m_SpawnX; } //tolua_export
- const double & GetSpawnY(); //tolua_export
- const double & GetSpawnZ() { return m_SpawnZ; } //tolua_export
-
- inline cSimulatorManager *GetSimulatorManager() { return m_SimulatorManager; }
- inline cWaterSimulator *GetWaterSimulator() { return m_WaterSimulator; }
- inline cLavaSimulator *GetLavaSimulator() { return m_LavaSimulator; }
-
- // TODO: This interface is dangerous! Export as a set of specific action functions for Lua: GetChestItem, GetFurnaceItem, SetFurnaceItem, SetSignLines etc.
- // _X 2012_02_21: This function always returns NULL
- OBSOLETE cBlockEntity * GetBlockEntity( int a_X, int a_Y, int a_Z ); //tolua_export
-
- /// a_Player is using block entity at [x, y, z], handle that:
- void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) {m_ChunkMap->UseBlockEntity(a_Player, a_X, a_Y, a_Z); }
-
- void GrowTree (int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export
- void GrowTreeFromSapling(int a_BlockX, int a_BlockY, int a_BlockZ, char a_SaplingMeta); // tolua_export
- void GrowTreeByBiome (int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export
-
- void GrowTreeImage(const sSetBlockVector & a_Blocks);
-
- /// Grows the plant at the specified block to its ripe stage (bonemeal used); returns false if the block is not growable. If a_IsBonemeal is true, block is not grown if not allowed in world.ini
- bool GrowPlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsByBonemeal = false); // tolua_export
-
- /// Grows a melon or a pumpkin next to the block specified (assumed to be the stem)
- void GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockType); // tolua_export
-
- int GetBiomeAt (int a_BlockX, int a_BlockZ); // tolua_export
-
- const AString & GetName(void) const { return m_WorldName; } //tolua_export
- const AString & GetIniFileName(void) const {return m_IniFileName; }
-
- inline static void AbsoluteToRelative( int & a_X, int & a_Y, int & a_Z, int & a_ChunkX, int & a_ChunkY, int & a_ChunkZ )
- {
- // TODO: Use floor() instead of weird if statements
- // Also fix Y
- a_ChunkX = a_X/cChunkDef::Width;
- if(a_X < 0 && a_X % cChunkDef::Width != 0) a_ChunkX--;
- a_ChunkY = 0;
- a_ChunkZ = a_Z/cChunkDef::Width;
- if(a_Z < 0 && a_Z % cChunkDef::Width != 0) a_ChunkZ--;
-
- a_X = a_X - a_ChunkX*cChunkDef::Width;
- a_Y = a_Y - a_ChunkY*cChunkDef::Height;
- a_Z = a_Z - a_ChunkZ*cChunkDef::Width;
- }
-
- inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkY, int & a_ChunkZ )
- {
- // TODO: Use floor() instead of weird if statements
- // Also fix Y
- (void)a_Y; // not unused anymore
- a_ChunkX = a_X/cChunkDef::Width;
- if(a_X < 0 && a_X % cChunkDef::Width != 0) a_ChunkX--;
- a_ChunkY = 0;
- a_ChunkZ = a_Z/cChunkDef::Width;
- if(a_Z < 0 && a_Z % cChunkDef::Width != 0) a_ChunkZ--;
- }
-
- void SaveAllChunks(void); //tolua_export
-
- /// Returns the number of chunks loaded
- int GetNumChunks() const; //tolua_export
-
- /// Returns the number of chunks loaded and dirty, and in the lighting queue
- void GetChunkStats(int & a_NumValid, int & a_NumDirty, int & a_NumInLightingQueue);
-
- // Various queues length queries (cannot be const, they lock their CS):
- inline int GetGeneratorQueueLength (void) { return m_Generator.GetQueueLength(); } // tolua_export
- inline int GetLightingQueueLength (void) { return m_Lighting.GetQueueLength(); } // tolua_export
- inline int GetStorageLoadQueueLength(void) { return m_Storage.GetLoadQueueLength(); } // tolua_export
- inline int GetStorageSaveQueueLength(void) { return m_Storage.GetSaveQueueLength(); } // tolua_export
-
- void Tick(float a_Dt);
-
- void InitializeSpawn();
-
- void CastThunderbolt (int a_X, int a_Y, int a_Z); //tolua_export
- void SetWeather ( eWeather a_Weather ); //tolua_export
- void ChangeWeather(); //tolua_export
- eWeather GetWeather() { return m_Weather; }; //tolua_export
-
- cChunkGenerator & GetGenerator(void) { return m_Generator; }
- cWorldStorage & GetStorage (void) { return m_Storage; }
- cChunkMap * GetChunkMap (void) { return m_ChunkMap; }
-
- bool IsPlacingItemLegal(Int16 a_ItemType, int a_BlockX, int a_BlockY, int a_BlockZ);
-
- /// Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call
- void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export
-
- int GetMaxSugarcaneHeight(void) const { return m_MaxSugarcaneHeight; } // tolua_export
- int GetMaxCactusHeight (void) const { return m_MaxCactusHeight; } // tolua_export
-
-private:
-
- friend class cRoot;
-
- // This random generator is to be used only in the Tick() method, and thus only in the World-Tick-thread (MTRand is not exactly thread-safe)
- MTRand m_TickRand;
-
- double m_SpawnX;
- double m_SpawnY;
- double m_SpawnZ;
-
- float m_LastUnload;
- float m_LastSave;
- static float m_Time; // Time in seconds
- long long m_WorldTime; // Time in seconds*20, this is sent to clients (is wrapped)
- unsigned long long CurrentTick;
- eGameMode m_GameMode;
- float m_WorldTimeFraction; // When this > 1.f m_WorldTime is incremented by 20
-
- // The cRedstone class simulates redstone and needs access to m_RSList
- friend class cRedstone;
- std::vector<int> m_RSList;
-
- cSimulatorManager * m_SimulatorManager;
- cSandSimulator * m_SandSimulator;
- cWaterSimulator * m_WaterSimulator;
- cLavaSimulator * m_LavaSimulator;
- cFireSimulator * m_FireSimulator;
- cRedstoneSimulator * m_RedstoneSimulator;
-
- cCriticalSection m_CSClients;
- cCriticalSection m_CSEntities;
- cCriticalSection m_CSPlayers;
-
- cWorldStorage m_Storage;
-
- AString m_Description;
-
- unsigned int m_MaxPlayers;
-
- cChunkMap * m_ChunkMap;
-
- bool m_bAnimals;
- float m_SpawnMonsterTime;
- float m_SpawnMonsterRate;
-
- eWeather m_Weather;
- int m_WeatherInterval;
-
- int m_MaxCactusHeight;
- int m_MaxSugarcaneHeight;
- bool m_IsCropsBonemealable;
- bool m_IsGrassBonemealable;
- bool m_IsSaplingBonemealable;
- bool m_IsMelonStemBonemealable;
- bool m_IsMelonBonemealable;
- bool m_IsPumpkinStemBonemealable;
- bool m_IsPumpkinBonemealable;
- bool m_IsSugarcaneBonemealable;
- bool m_IsCactusBonemealable;
-
- cEntityList m_RemoveEntityQueue;
- cEntityList m_AllEntities;
- cClientHandleList m_Clients;
- cPlayerList m_Players;
-
- cCriticalSection m_CSFastSetBlock;
- sSetBlockList m_FastSetBlockQueue;
-
- cChunkGenerator m_Generator;
-
- cChunkSender m_ChunkSender;
- cLightingThread m_Lighting;
-
- AString m_WorldName;
- AString m_IniFileName;
-
- cWorld(const AString & a_WorldName);
- ~cWorld();
-
- void TickWeather(float a_Dt); // Handles weather each tick
- void TickSpawnMobs(float a_Dt); // Handles mob spawning each tick
-
- void RemoveEntity( cEntity * a_Entity );
-}; //tolua_export
-
-
-
-
+ +#pragma once + +#ifndef _WIN32 + #include "BlockID.h" +#else + enum ENUM_ITEM_ID; +#endif + +#define MAX_PLAYERS 65535 + +#include "cSimulatorManager.h" +#include "MersenneTwister.h" +#include "cChunkMap.h" +#include "WorldStorage.h" +#include "cChunkGenerator.h" +#include "Vector3i.h" +#include "Vector3f.h" +#include "ChunkSender.h" +#include "Defines.h" +#include "LightingThread.h" +#include "cItem.h" + + + + + +class cPacket; +class cRedstone; +class cFireSimulator; +class cWaterSimulator; +class cLavaSimulator; +class cSandSimulator; +class cRedstoneSimulator; +class cItem; +class cPlayer; +class cClientHandle; +class cEntity; +class cBlockEntity; +class cWorldGenerator; // The generator that actually generates the chunks for a single world +class cChunkGenerator; // The thread responsible for generating chunks +typedef std::list< cPlayer * > cPlayerList; +typedef cItemCallback<cPlayer> cPlayerListCallback; +typedef cItemCallback<cEntity> cEntityCallback; + + + + + +class cWorld //tolua_export +{ //tolua_export +public: + + OBSOLETE static cWorld* GetWorld(); + + // Return time in seconds + inline static float GetTime() //tolua_export + { + return m_Time; + } + long long GetWorldTime(void) const { return m_WorldTime; } //tolua_export + + eGameMode GetGameMode(void) const { return m_GameMode; } //tolua_export + + void SetWorldTime(long long a_WorldTime) { m_WorldTime = a_WorldTime; } //tolua_export + + int GetHeight( int a_X, int a_Z ); //tolua_export + + void Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude = 0 ); + void BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude = NULL); + void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude = NULL); + + void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /** Sets the chunk data as either loaded from the storage or generated. + a_BlockLight and a_BlockSkyLight are optional, if not present, chunk will be marked as unlighted. + a_BiomeMap is optional, if not present, biomes will be calculated by the generator + a_HeightMap is optional, if not present, will be calculated. + If a_MarkDirty is set, the chunk is set as dirty (used after generating) + */ + void SetChunkData( + int a_ChunkX, int a_ChunkY, int a_ChunkZ, + const BLOCKTYPE * a_BlockTypes, + const NIBBLETYPE * a_BlockMeta, + const NIBBLETYPE * a_BlockLight, + const NIBBLETYPE * a_BlockSkyLight, + const cChunkDef::HeightMap * a_HeightMap, + const cChunkDef::BiomeMap * a_BiomeMap, + cEntityList & a_Entities, + cBlockEntityList & a_BlockEntities, + bool a_MarkDirty + ); + + void ChunkLighted( + int a_ChunkX, int a_ChunkZ, + const cChunkDef::BlockNibbles & a_BlockLight, + const cChunkDef::BlockNibbles & a_SkyLight + ); + + bool GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback & a_Callback); + + /// Gets the chunk's blocks, only the block types + bool GetChunkBlockTypes(int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockTypes); + + /// Gets the chunk's blockdata, the entire 4 arrays (Types, Meta, Light, SkyLight) + bool GetChunkBlockData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, BLOCKTYPE * a_BlockData); + + bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ) const; + bool HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const; + + void UnloadUnusedChunks(void); // tolua_export + + void CollectPickupsByPlayer(cPlayer * a_Player); + + // MOTD + const AString & GetDescription(void) const {return m_Description; } // FIXME: This should not be in cWorld + + // Max Players + unsigned int GetMaxPlayers(void) const {return m_MaxPlayers; } //tolua_export + void SetMaxPlayers(int iMax); //tolua_export + + void AddPlayer( cPlayer* a_Player ); + void RemovePlayer( cPlayer* a_Player ); + + bool ForEachPlayer(cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << + + unsigned int GetNumPlayers(); //tolua_export + + // TODO: This interface is dangerous - rewrite to DoWithPlayer(playername, action) + cPlayer * GetPlayer( const char * a_PlayerName ); //tolua_export + + // TODO: This interface is dangerous - rewrite to DoWithClosestPlayer(pos, sight, action) + cPlayer * FindClosestPlayer(const Vector3f & a_Pos, float a_SightLimit); + + void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player + + void AddEntity( cEntity* a_Entity ); + + /// Add an entity to the chunk specified; broadcasts the a_SpawnPacket to all clients of that chunk + void AddEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ, cPacket * a_SpawnPacket); + + /// Removes the entity from the chunk specified + void RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Moves the entity from its current chunk to the new chunk specified + void MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Compares clients of two chunks, calls the callback accordingly + void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback); + + /// Adds client to a chunk, if not already present; returns true if added, false if present + bool AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); + + /// Removes client from the chunk specified + void RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); + + /// Removes the client from all chunks it is present in + void RemoveClientFromChunks(cClientHandle * a_Client); + + /// Sends the chunk to the client specified, if the chunk is valid. If not valid, the request is postponed (ChunkSender will send that chunk when it becomes valid+lighted) + void SendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); + + /// Removes client from ChunkSender's queue of chunks to be sent + void RemoveClientFromChunkSender(cClientHandle * a_Client); + + /// Touches the chunk, causing it to be loaded or generated + void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) + bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + /// Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() + void LoadChunks(const cChunkCoordsList & a_Chunks); + + /// Marks the chunk as failed-to-load: + void ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + + void UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); //tolua_export + + /// Marks (a_Stay == true) or unmarks (a_Stay == false) chunks as non-unloadable. To be used only by cChunkStay! + void ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay = true); + + /// Regenerate the given chunk: + void RegenerateChunk(int a_ChunkX, int a_ChunkZ); //tolua_export + + /// Generates the given chunk, if not already generated + void GenerateChunk(int a_ChunkX, int a_ChunkZ); //tolua_export + + /// Queues a chunk for lighting; a_Callback is called after the chunk is lighted + void QueueLightChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback = NULL); + + bool IsChunkLighted(int a_ChunkX, int a_ChunkZ); + + // TODO: Export to Lua + bool DoWithEntity( int a_UniqueID, cEntityCallback & a_Callback ); + + void SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ); //tolua_export + void FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ); //tolua_export + char GetBlock( int a_X, int a_Y, int a_Z ); //tolua_export + char GetBlock( const Vector3i & a_Pos ) { return GetBlock( a_Pos.x, a_Pos.y, a_Pos.z ); } //tolua_export + char GetBlockMeta( int a_X, int a_Y, int a_Z ); //tolua_export + char GetBlockMeta( const Vector3i & a_Pos ) { return GetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z ); } //tolua_export + void SetBlockMeta( int a_X, int a_Y, int a_Z, char a_MetaData ); //tolua_export + void SetBlockMeta( const Vector3i & a_Pos, char a_MetaData ) { SetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z, a_MetaData ); } //tolua_export + char GetBlockSkyLight( int a_X, int a_Y, int a_Z ); //tolua_export + // TODO: char GetBlockActualLight(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export + void GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, char & a_BlockType, unsigned char & a_BlockMeta); // tolua_export + + /// Spawns item pickups for each item in the list. May compress pickups if too many entities: + void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed = 1.0); + + /// Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified: + void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ); + + /// Replaces world blocks with a_Blocks, if they are of type a_FilterBlockType + void ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType); + + /// Retrieves block types of the specified blocks. If a chunk is not loaded, doesn't modify the block. Returns true if all blocks were read. + bool GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure); + + bool DigBlock (int a_X, int a_Y, int a_Z); //tolua_export + void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player ); //tolua_export + + const double & GetSpawnX() { return m_SpawnX; } //tolua_export + const double & GetSpawnY(); //tolua_export + const double & GetSpawnZ() { return m_SpawnZ; } //tolua_export + + inline cSimulatorManager *GetSimulatorManager() { return m_SimulatorManager; } + inline cWaterSimulator *GetWaterSimulator() { return m_WaterSimulator; } + inline cLavaSimulator *GetLavaSimulator() { return m_LavaSimulator; } + + // TODO: This interface is dangerous! Export as a set of specific action functions for Lua: GetChestItem, GetFurnaceItem, SetFurnaceItem, SetSignLines etc. + // _X 2012_02_21: This function always returns NULL + OBSOLETE cBlockEntity * GetBlockEntity( int a_X, int a_Y, int a_Z ); //tolua_export + + /// a_Player is using block entity at [x, y, z], handle that: + void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) {m_ChunkMap->UseBlockEntity(a_Player, a_X, a_Y, a_Z); } + + void GrowTree (int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export + void GrowTreeFromSapling(int a_BlockX, int a_BlockY, int a_BlockZ, char a_SaplingMeta); // tolua_export + void GrowTreeByBiome (int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export + + void GrowTreeImage(const sSetBlockVector & a_Blocks); + + /// Grows the plant at the specified block to its ripe stage (bonemeal used); returns false if the block is not growable. If a_IsBonemeal is true, block is not grown if not allowed in world.ini + bool GrowPlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsByBonemeal = false); // tolua_export + + /// Grows a melon or a pumpkin next to the block specified (assumed to be the stem) + void GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockType); // tolua_export + + int GetBiomeAt (int a_BlockX, int a_BlockZ); // tolua_export + + const AString & GetName(void) const { return m_WorldName; } //tolua_export + const AString & GetIniFileName(void) const {return m_IniFileName; } + + inline static void AbsoluteToRelative( int & a_X, int & a_Y, int & a_Z, int & a_ChunkX, int & a_ChunkY, int & a_ChunkZ ) + { + // TODO: Use floor() instead of weird if statements + // Also fix Y + a_ChunkX = a_X/cChunkDef::Width; + if(a_X < 0 && a_X % cChunkDef::Width != 0) a_ChunkX--; + a_ChunkY = 0; + a_ChunkZ = a_Z/cChunkDef::Width; + if(a_Z < 0 && a_Z % cChunkDef::Width != 0) a_ChunkZ--; + + a_X = a_X - a_ChunkX*cChunkDef::Width; + a_Y = a_Y - a_ChunkY*cChunkDef::Height; + a_Z = a_Z - a_ChunkZ*cChunkDef::Width; + } + + inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkY, int & a_ChunkZ ) + { + // TODO: Use floor() instead of weird if statements + // Also fix Y + (void)a_Y; // not unused anymore + a_ChunkX = a_X/cChunkDef::Width; + if(a_X < 0 && a_X % cChunkDef::Width != 0) a_ChunkX--; + a_ChunkY = 0; + a_ChunkZ = a_Z/cChunkDef::Width; + if(a_Z < 0 && a_Z % cChunkDef::Width != 0) a_ChunkZ--; + } + + void SaveAllChunks(void); //tolua_export + + /// Returns the number of chunks loaded + int GetNumChunks() const; //tolua_export + + /// Returns the number of chunks loaded and dirty, and in the lighting queue + void GetChunkStats(int & a_NumValid, int & a_NumDirty, int & a_NumInLightingQueue); + + // Various queues length queries (cannot be const, they lock their CS): + inline int GetGeneratorQueueLength (void) { return m_Generator.GetQueueLength(); } // tolua_export + inline int GetLightingQueueLength (void) { return m_Lighting.GetQueueLength(); } // tolua_export + inline int GetStorageLoadQueueLength(void) { return m_Storage.GetLoadQueueLength(); } // tolua_export + inline int GetStorageSaveQueueLength(void) { return m_Storage.GetSaveQueueLength(); } // tolua_export + + void Tick(float a_Dt); + + void InitializeSpawn(); + + void CastThunderbolt (int a_X, int a_Y, int a_Z); //tolua_export + void SetWeather ( eWeather a_Weather ); //tolua_export + void ChangeWeather(); //tolua_export + eWeather GetWeather() { return m_Weather; }; //tolua_export + + cChunkGenerator & GetGenerator(void) { return m_Generator; } + cWorldStorage & GetStorage (void) { return m_Storage; } + cChunkMap * GetChunkMap (void) { return m_ChunkMap; } + + bool IsPlacingItemLegal(Int16 a_ItemType, int a_BlockX, int a_BlockY, int a_BlockZ); + + /// Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call + void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export + + int GetMaxSugarcaneHeight(void) const { return m_MaxSugarcaneHeight; } // tolua_export + int GetMaxCactusHeight (void) const { return m_MaxCactusHeight; } // tolua_export + +private: + + friend class cRoot; + + // This random generator is to be used only in the Tick() method, and thus only in the World-Tick-thread (MTRand is not exactly thread-safe) + MTRand m_TickRand; + + double m_SpawnX; + double m_SpawnY; + double m_SpawnZ; + + float m_LastUnload; + float m_LastSave; + static float m_Time; // Time in seconds + long long m_WorldTime; // Time in seconds*20, this is sent to clients (is wrapped) + unsigned long long CurrentTick; + eGameMode m_GameMode; + float m_WorldTimeFraction; // When this > 1.f m_WorldTime is incremented by 20 + + // The cRedstone class simulates redstone and needs access to m_RSList + friend class cRedstone; + std::vector<int> m_RSList; + + cSimulatorManager * m_SimulatorManager; + cSandSimulator * m_SandSimulator; + cWaterSimulator * m_WaterSimulator; + cLavaSimulator * m_LavaSimulator; + cFireSimulator * m_FireSimulator; + cRedstoneSimulator * m_RedstoneSimulator; + + cCriticalSection m_CSClients; + cCriticalSection m_CSEntities; + cCriticalSection m_CSPlayers; + + cWorldStorage m_Storage; + + AString m_Description; + + unsigned int m_MaxPlayers; + + cChunkMap * m_ChunkMap; + + bool m_bAnimals; + float m_SpawnMonsterTime; + float m_SpawnMonsterRate; + + eWeather m_Weather; + int m_WeatherInterval; + + int m_MaxCactusHeight; + int m_MaxSugarcaneHeight; + bool m_IsCropsBonemealable; + bool m_IsGrassBonemealable; + bool m_IsSaplingBonemealable; + bool m_IsMelonStemBonemealable; + bool m_IsMelonBonemealable; + bool m_IsPumpkinStemBonemealable; + bool m_IsPumpkinBonemealable; + bool m_IsSugarcaneBonemealable; + bool m_IsCactusBonemealable; + + cEntityList m_RemoveEntityQueue; + cEntityList m_AllEntities; + cClientHandleList m_Clients; + cPlayerList m_Players; + + cCriticalSection m_CSFastSetBlock; + sSetBlockList m_FastSetBlockQueue; + + cChunkGenerator m_Generator; + + cChunkSender m_ChunkSender; + cLightingThread m_Lighting; + + AString m_WorldName; + AString m_IniFileName; + + cWorld(const AString & a_WorldName); + ~cWorld(); + + void TickWeather(float a_Dt); // Handles weather each tick + void TickSpawnMobs(float a_Dt); // Handles mob spawning each tick + + void RemoveEntity( cEntity * a_Entity ); +}; //tolua_export + + + + diff --git a/source/cZombie.cpp b/source/cZombie.cpp index b8f9553d2..94c1d669b 100644 --- a/source/cZombie.cpp +++ b/source/cZombie.cpp @@ -1,66 +1,66 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cZombie.h"
-
-
-
-
-
-cZombie::cZombie()
-{
- m_MobType = 54;
- GetMonsterConfig("Zombie");
-}
-
-
-
-
-
-cZombie::~cZombie()
-{
-}
-
-
-
-
-
-bool cZombie::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cZombie" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
-
-
-
-
-
-void cZombie::Tick(float a_Dt)
-{
- cMonster::Tick(a_Dt);
-
- //TODO Same as in cSkeleton :D
- if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING) { //if daylight
- SetMetaData(BURNING); // BURN, BABY, BURN! >:D
- }
-}
-
-
-
-
-
-void cZombie::KilledBy( cEntity* a_Killer )
-{
- cItems Drops;
- AddRandomDropItem(Drops, 0, 2, E_ITEM_ROTTEN_FLESH);
-
- // TODO: Rare drops
-
- m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
-
- cMonster::KilledBy( a_Killer );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cZombie.h" + + + + + +cZombie::cZombie() +{ + m_MobType = 54; + GetMonsterConfig("Zombie"); +} + + + + + +cZombie::~cZombie() +{ +} + + + + + +bool cZombie::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cZombie" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cZombie::Tick(float a_Dt) +{ + cMonster::Tick(a_Dt); + + //TODO Same as in cSkeleton :D + if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING) { //if daylight + SetMetaData(BURNING); // BURN, BABY, BURN! >:D + } +} + + + + + +void cZombie::KilledBy( cEntity* a_Killer ) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_ROTTEN_FLESH); + + // TODO: Rare drops + + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cZombie.h b/source/cZombie.h index b35ff8933..4d6e39fb0 100644 --- a/source/cZombie.h +++ b/source/cZombie.h @@ -1,15 +1,15 @@ -#pragma once
-
-#include "cAggressiveMonster.h"
-
-class cZombie : public cAggressiveMonster
-{
-public:
- cZombie();
- ~cZombie();
-
- virtual bool IsA( const char* a_EntityType );
-
- virtual void Tick(float a_Dt);
- virtual void KilledBy( cEntity* a_Killer );
-};
+#pragma once + +#include "cAggressiveMonster.h" + +class cZombie : public cAggressiveMonster +{ +public: + cZombie(); + ~cZombie(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void Tick(float a_Dt); + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/cZombiepigman.cpp b/source/cZombiepigman.cpp index 024c0bd62..5aefbae72 100644 --- a/source/cZombiepigman.cpp +++ b/source/cZombiepigman.cpp @@ -1,67 +1,67 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cZombiepigman.h"
-
-
-
-
-
-cZombiepigman::cZombiepigman()
-{
- m_MobType = 57;
- GetMonsterConfig("Zombiepigman");
-}
-
-
-
-
-
-cZombiepigman::~cZombiepigman()
-{
-}
-
-
-
-
-
-bool cZombiepigman::IsA( const char* a_EntityType )
-{
- if( strcmp( a_EntityType, "cZombiepigman" ) == 0 ) return true;
- return cMonster::IsA( a_EntityType );
-}
-
-
-
-
-
-void cZombiepigman::Tick(float a_Dt)
-{
- cMonster::Tick(a_Dt);
-
- //TODO Same as noticed in cSkeleton AND Do they really burn by sun?? :D In the neather is no sun :D
- if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING ) { //if daylight
- SetMetaData(BURNING); // BURN, BABY, BURN! >:D
- }
-}
-
-
-
-
-
-void cZombiepigman::KilledBy(cEntity * a_Killer)
-{
- cItems Drops;
- AddRandomDropItem(Drops, 0, 1, E_ITEM_ROTTEN_FLESH);
- AddRandomDropItem(Drops, 0, 1, E_ITEM_GOLD_NUGGET);
-
- // TODO: Rare drops
-
- m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
-
- cMonster::KilledBy( a_Killer );
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cZombiepigman.h" + + + + + +cZombiepigman::cZombiepigman() +{ + m_MobType = 57; + GetMonsterConfig("Zombiepigman"); +} + + + + + +cZombiepigman::~cZombiepigman() +{ +} + + + + + +bool cZombiepigman::IsA( const char* a_EntityType ) +{ + if( strcmp( a_EntityType, "cZombiepigman" ) == 0 ) return true; + return cMonster::IsA( a_EntityType ); +} + + + + + +void cZombiepigman::Tick(float a_Dt) +{ + cMonster::Tick(a_Dt); + + //TODO Same as noticed in cSkeleton AND Do they really burn by sun?? :D In the neather is no sun :D + if (GetWorld()->GetWorldTime() < (12000 + 1000) && GetMetaData() != BURNING ) { //if daylight + SetMetaData(BURNING); // BURN, BABY, BURN! >:D + } +} + + + + + +void cZombiepigman::KilledBy(cEntity * a_Killer) +{ + cItems Drops; + AddRandomDropItem(Drops, 0, 1, E_ITEM_ROTTEN_FLESH); + AddRandomDropItem(Drops, 0, 1, E_ITEM_GOLD_NUGGET); + + // TODO: Rare drops + + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + + cMonster::KilledBy( a_Killer ); +} + + + + diff --git a/source/cZombiepigman.h b/source/cZombiepigman.h index 1a102572b..76fb34e4b 100644 --- a/source/cZombiepigman.h +++ b/source/cZombiepigman.h @@ -1,15 +1,15 @@ -#pragma once
-
-#include "cPassiveAggressiveMonster.h"
-
-class cZombiepigman : public cPassiveAggressiveMonster
-{
-public:
- cZombiepigman();
- ~cZombiepigman();
-
- virtual bool IsA( const char* a_EntityType );
-
- virtual void Tick(float a_Dt);
- virtual void KilledBy( cEntity* a_Killer );
-};
+#pragma once + +#include "cPassiveAggressiveMonster.h" + +class cZombiepigman : public cPassiveAggressiveMonster +{ +public: + cZombiepigman(); + ~cZombiepigman(); + + virtual bool IsA( const char* a_EntityType ); + + virtual void Tick(float a_Dt); + virtual void KilledBy( cEntity* a_Killer ); +}; diff --git a/source/main.cpp b/source/main.cpp index 1d245ae0b..d379fdd17 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,204 +1,204 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cRoot.h"
-
-#include <exception> //std::exception
-#include <csignal> //std::signal
-#include <stdlib.h> //exit()
-
-#ifdef _WIN32
- #include <dbghelp.h>
-#endif // _WIN32
-
-#include "SquirrelBindings.h"
-#if USE_SQUIRREL
- #pragma warning(push)
- #pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus
- #include <sqplus/sqplus.h>
- #pragma warning(pop)
-#endif
-
-
-
-
-/// If defined, a thorough leak finder will be used (debug MSVC only); leaks will be output to the Output window
-#define ENABLE_LEAK_FINDER
-
-
-
-
-
-#if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER)
- #define XML_LEAK_FINDER
- #pragma warning(push)
- #pragma warning(disable:4100)
- #include "LeakFinder.h"
- #pragma warning(pop)
-#endif
-
-
-
-
-
-
-void ShowCrashReport(int)
-{
- std::signal(SIGSEGV, SIG_DFL);
-
- printf("\n\nMCServer has crashed!\n");
-
- exit(-1);
-}
-
-
-
-
-
-#if defined(_WIN32) && !defined(_WIN64)
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Windows 32-bit stuff: when the server crashes, create a "dump file" containing the callstack of each thread and some variables; let the user send us that crash file for analysis
-
-typedef BOOL (WINAPI *pMiniDumpWriteDump)(
- HANDLE hProcess,
- DWORD ProcessId,
- HANDLE hFile,
- MINIDUMP_TYPE DumpType,
- PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
- PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
- PMINIDUMP_CALLBACK_INFORMATION CallbackParam
-);
-
-pMiniDumpWriteDump g_WriteMiniDump; // The function in dbghlp DLL that creates dump files
-
-char g_DumpFileName[MAX_PATH]; // Filename of the dump file; hes to be created before the dump handler kicks in
-char g_ExceptionStack[128 * 1024]; // Substitute stack, just in case the handler kicks in because of "insufficient stack space"
-MINIDUMP_TYPE g_DumpFlags = MiniDumpNormal; // By default dump only the stack and some helpers
-
-
-
-
-
-/** This function gets called just before the "program executed an illegal instruction and will be terminated" or similar.
-Its purpose is to create the crashdump using the dbghlp DLLs
-*/
-LONG WINAPI LastChanceExceptionFilter(__in struct _EXCEPTION_POINTERS * a_ExceptionInfo)
-{
- char * newStack = &g_ExceptionStack[sizeof(g_ExceptionStack)];
- char * oldStack;
-
- // Use the substitute stack:
- // This code is the reason why we don't support 64-bit (yet)
- _asm
- {
- mov oldStack, esp
- mov esp, newStack
- }
-
- MINIDUMP_EXCEPTION_INFORMATION ExcInformation;
- ExcInformation.ThreadId = GetCurrentThreadId();
- ExcInformation.ExceptionPointers = a_ExceptionInfo;
- ExcInformation.ClientPointers = 0;
-
- // Write the dump file:
- HANDLE dumpFile = CreateFile(g_DumpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- g_WriteMiniDump(GetCurrentProcess(), GetCurrentProcessId(), dumpFile, g_DumpFlags, (a_ExceptionInfo) ? &ExcInformation : NULL, NULL, NULL);
- CloseHandle(dumpFile);
-
- // Revert to old stack:
- _asm
- {
- mov esp, oldStack
- }
-
- return 0;
-}
-
-#endif // _WIN32 && !_WIN64
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// main:
-
-int main( int argc, char **argv )
-{
- (void)argc;
- (void)argv;
-
- #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER)
- InitLeakFinder();
- #endif
-
- // Magic code to produce dump-files on Windows if the server crashes:
- #if defined(_WIN32) && !defined(_WIN64)
- HINSTANCE hDbgHelp = LoadLibrary("DBGHELP.DLL");
- g_WriteMiniDump = (pMiniDumpWriteDump)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
- if (g_WriteMiniDump != NULL)
- {
- _snprintf_s(g_DumpFileName, ARRAYCOUNT(g_DumpFileName), _TRUNCATE, "crash_mcs_%x.dmp", GetCurrentProcessId());
- SetUnhandledExceptionFilter(LastChanceExceptionFilter);
-
- // Parse arguments for minidump flags:
- for (int i = 0; i < argc; i++)
- {
- if (stricmp(argv[i], "/cdg") == 0)
- {
- // Add globals to the dump
- g_DumpFlags = (MINIDUMP_TYPE)(g_DumpFlags | MiniDumpWithDataSegs);
- }
- else if (stricmp(argv[i], "/cdf") == 0)
- {
- // Add full memory to the dump (HUUUGE file)
- g_DumpFlags = (MINIDUMP_TYPE)(g_DumpFlags | MiniDumpWithFullMemory);
- }
- } // for i - argv[]
- }
- #endif // _WIN32 && !_WIN64
- // End of dump-file magic
-
- #if defined(_DEBUG) && defined(_MSC_VER)
- _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
-
- // _X: The simple built-in CRT leak finder - simply break when allocating the Nth block ({N} is listed in the leak output)
- // Only useful when the leak is in the same sequence all the time
- // _CrtSetBreakAlloc(85950);
-
- #endif // _DEBUG && _MSC_VER
-
- #ifndef _DEBUG
- std::signal(SIGSEGV, ShowCrashReport);
- #endif
-
- // DEBUG: test the dumpfile creation:
- // *((int *)0) = 0;
-
- try
- {
- cRoot Root;
- Root.Start();
- }
- catch( std::exception& e )
- {
- LOGERROR("Standard exception: %s", e.what() );
- }
- catch( ... )
- {
- LOGERROR("Unknown exception!");
- }
-
- #if USE_SQUIRREL
- SquirrelVM::Shutdown();
- #endif
-
- #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER)
- DeinitLeakFinder();
- #endif
-
- return 0;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cRoot.h" + +#include <exception> //std::exception +#include <csignal> //std::signal +#include <stdlib.h> //exit() + +#ifdef _WIN32 + #include <dbghelp.h> +#endif // _WIN32 + +#include "SquirrelBindings.h" +#if USE_SQUIRREL + #pragma warning(push) + #pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus + #include <sqplus/sqplus.h> + #pragma warning(pop) +#endif + + + + +/// If defined, a thorough leak finder will be used (debug MSVC only); leaks will be output to the Output window +#define ENABLE_LEAK_FINDER + + + + + +#if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) + #define XML_LEAK_FINDER + #pragma warning(push) + #pragma warning(disable:4100) + #include "LeakFinder.h" + #pragma warning(pop) +#endif + + + + + + +void ShowCrashReport(int) +{ + std::signal(SIGSEGV, SIG_DFL); + + printf("\n\nMCServer has crashed!\n"); + + exit(-1); +} + + + + + +#if defined(_WIN32) && !defined(_WIN64) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Windows 32-bit stuff: when the server crashes, create a "dump file" containing the callstack of each thread and some variables; let the user send us that crash file for analysis + +typedef BOOL (WINAPI *pMiniDumpWriteDump)( + HANDLE hProcess, + DWORD ProcessId, + HANDLE hFile, + MINIDUMP_TYPE DumpType, + PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + PMINIDUMP_CALLBACK_INFORMATION CallbackParam +); + +pMiniDumpWriteDump g_WriteMiniDump; // The function in dbghlp DLL that creates dump files + +char g_DumpFileName[MAX_PATH]; // Filename of the dump file; hes to be created before the dump handler kicks in +char g_ExceptionStack[128 * 1024]; // Substitute stack, just in case the handler kicks in because of "insufficient stack space" +MINIDUMP_TYPE g_DumpFlags = MiniDumpNormal; // By default dump only the stack and some helpers + + + + + +/** This function gets called just before the "program executed an illegal instruction and will be terminated" or similar. +Its purpose is to create the crashdump using the dbghlp DLLs +*/ +LONG WINAPI LastChanceExceptionFilter(__in struct _EXCEPTION_POINTERS * a_ExceptionInfo) +{ + char * newStack = &g_ExceptionStack[sizeof(g_ExceptionStack)]; + char * oldStack; + + // Use the substitute stack: + // This code is the reason why we don't support 64-bit (yet) + _asm + { + mov oldStack, esp + mov esp, newStack + } + + MINIDUMP_EXCEPTION_INFORMATION ExcInformation; + ExcInformation.ThreadId = GetCurrentThreadId(); + ExcInformation.ExceptionPointers = a_ExceptionInfo; + ExcInformation.ClientPointers = 0; + + // Write the dump file: + HANDLE dumpFile = CreateFile(g_DumpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + g_WriteMiniDump(GetCurrentProcess(), GetCurrentProcessId(), dumpFile, g_DumpFlags, (a_ExceptionInfo) ? &ExcInformation : NULL, NULL, NULL); + CloseHandle(dumpFile); + + // Revert to old stack: + _asm + { + mov esp, oldStack + } + + return 0; +} + +#endif // _WIN32 && !_WIN64 + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// main: + +int main( int argc, char **argv ) +{ + (void)argc; + (void)argv; + + #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) + InitLeakFinder(); + #endif + + // Magic code to produce dump-files on Windows if the server crashes: + #if defined(_WIN32) && !defined(_WIN64) + HINSTANCE hDbgHelp = LoadLibrary("DBGHELP.DLL"); + g_WriteMiniDump = (pMiniDumpWriteDump)GetProcAddress(hDbgHelp, "MiniDumpWriteDump"); + if (g_WriteMiniDump != NULL) + { + _snprintf_s(g_DumpFileName, ARRAYCOUNT(g_DumpFileName), _TRUNCATE, "crash_mcs_%x.dmp", GetCurrentProcessId()); + SetUnhandledExceptionFilter(LastChanceExceptionFilter); + + // Parse arguments for minidump flags: + for (int i = 0; i < argc; i++) + { + if (stricmp(argv[i], "/cdg") == 0) + { + // Add globals to the dump + g_DumpFlags = (MINIDUMP_TYPE)(g_DumpFlags | MiniDumpWithDataSegs); + } + else if (stricmp(argv[i], "/cdf") == 0) + { + // Add full memory to the dump (HUUUGE file) + g_DumpFlags = (MINIDUMP_TYPE)(g_DumpFlags | MiniDumpWithFullMemory); + } + } // for i - argv[] + } + #endif // _WIN32 && !_WIN64 + // End of dump-file magic + + #if defined(_DEBUG) && defined(_MSC_VER) + _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); + + // _X: The simple built-in CRT leak finder - simply break when allocating the Nth block ({N} is listed in the leak output) + // Only useful when the leak is in the same sequence all the time + // _CrtSetBreakAlloc(85950); + + #endif // _DEBUG && _MSC_VER + + #ifndef _DEBUG + std::signal(SIGSEGV, ShowCrashReport); + #endif + + // DEBUG: test the dumpfile creation: + // *((int *)0) = 0; + + try + { + cRoot Root; + Root.Start(); + } + catch( std::exception& e ) + { + LOGERROR("Standard exception: %s", e.what() ); + } + catch( ... ) + { + LOGERROR("Unknown exception!"); + } + + #if USE_SQUIRREL + SquirrelVM::Shutdown(); + #endif + + #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) + DeinitLeakFinder(); + #endif + + return 0; +} + + + + diff --git a/source/md5/md5.cpp b/source/md5/md5.cpp index 2b9e10c9f..39337da5d 100644 --- a/source/md5/md5.cpp +++ b/source/md5/md5.cpp @@ -1,364 +1,364 @@ -/* 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.
-
-*/
-
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-/* interface header */
-#include "md5.h"
-
-
-
-
-
-// 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();
-}
+/* 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. + +*/ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +/* interface header */ +#include "md5.h" + + + + + +// 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(); +} diff --git a/source/md5/md5.h b/source/md5/md5.h index 140ad1f14..ad5ad5384 100644 --- a/source/md5/md5.h +++ b/source/md5/md5.h @@ -1,93 +1,93 @@ -/* 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);
-
+/* 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
\ No newline at end of file diff --git a/source/packets/cPacket.cpp b/source/packets/cPacket.cpp index ec7181762..6fad331ed 100644 --- a/source/packets/cPacket.cpp +++ b/source/packets/cPacket.cpp @@ -1,307 +1,307 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket.h"
-#include "../Endianness.h"
-
-
-
-
-
-/*
-// These checks cannot be done in preprocessor, since sizeof() is evaluated while compiling, so in preprocessing it's unknown.
-// Check some basic type assumptions:
-#if (sizeof(int) != 4)
- #error "Bad size for int, protocol won't work"
-#endif
-
-#if (sizeof(float) != 4)
- #error "Bad size for float, protocol won't work"
-#endif
-
-#if (sizeof(double) != 8)
- #error "Bad size for double, protocol won't work"
-#endif
-*/
-
-
-
-
-
-int cPacket::ReadString16(const char * a_Data, int a_Size, AString & a_OutString )
-{
- int TotalBytes = 0;
- short StrLen;
- HANDLE_PACKET_READ(ReadShort, StrLen, TotalBytes);
-
- if (2 * StrLen > a_Size - TotalBytes)
- {
- // The string is not yet complete in the buffer
- return PACKET_INCOMPLETE;
- }
-
- // Simple UTF-16 to UTF-8 conversion - discard higher bits, ignore multishort sequences:
- a_OutString.clear();
- a_OutString.reserve(StrLen);
- short * UTF16 = (short *)(a_Data + TotalBytes);
- for ( int i = 0; i < StrLen; ++i )
- {
- a_OutString.push_back( (char)ntohs(UTF16[i]) );
- }
-
- return TotalBytes + StrLen * sizeof(short);
-}
-
-
-
-
-
-int cPacket::ReadShort(const char * a_Data, int a_Size, short & a_OutShort )
-{
- if (a_Size < 2)
- {
- return PACKET_INCOMPLETE;
- }
- a_OutShort = ntohs(*((short *)a_Data));
- return 2;
-}
-
-
-
-
-
-int cPacket::ReadInteger(const char * a_Data, int a_Size, int & a_OutInteger )
-{
- if (a_Size < 4)
- {
- return PACKET_INCOMPLETE;
- }
- a_OutInteger = ntohl(*((int *)a_Data));
- return 4;
-}
-
-
-
-
-
-int cPacket::ReadInteger(const char * a_Data, int a_Size, unsigned int & a_OutInteger )
-{
- if (a_Size < 4)
- {
- return PACKET_INCOMPLETE;
- }
- a_OutInteger = ntohl(*((unsigned int *)a_Data));
- return 4;
-}
-
-
-
-
-
-int cPacket::ReadFloat(const char * a_Data, int a_Size, float & a_OutFloat )
-{
- if (a_Size < sizeof(float))
- {
- return PACKET_INCOMPLETE;
- }
- a_OutFloat = NetworkToHostFloat4(a_Data);
- return sizeof(float);
-}
-
-
-
-
-
-int cPacket::ReadDouble(const char * a_Data, int a_Size, double & a_OutDouble )
-{
- if (a_Size < sizeof(double))
- {
- return PACKET_INCOMPLETE;
- }
- a_OutDouble = NetworkToHostDouble8(a_Data);
- return sizeof(double);
-}
-
-
-
-
-
-int cPacket::ReadByte(const char * a_Data, int a_Size, char & a_OutByte )
-{
- if (a_Size < 1)
- {
- return PACKET_INCOMPLETE;
- }
- a_OutByte = *a_Data;
- return 1;
-}
-
-
-
-
-
-int cPacket::ReadByte(const char * a_Data, int a_Size, unsigned char & a_OutByte )
-{
- if (a_Size < 1)
- {
- return PACKET_INCOMPLETE;
- }
- a_OutByte = *((unsigned char *)a_Data);
- return 1;
-}
-
-
-
-
-
-int cPacket::ReadLong(const char * a_Data, int a_Size, long long & a_OutLong )
-{
- if (a_Size < sizeof(a_OutLong))
- {
- return PACKET_INCOMPLETE;
- }
- a_OutLong = NetworkToHostLong8(a_Data);
- return sizeof(a_OutLong);
-}
-
-
-
-
-
-int cPacket::ReadBool(const char * a_Data, int a_Size, bool & a_OutBool )
-{
- if (a_Size < sizeof(bool))
- {
- return PACKET_INCOMPLETE;
- }
- a_OutBool = (*a_Data != 0);
- return sizeof(bool);
-}
-
-
-
-
-
-void cPacket::AppendString(AString & a_Dst, const AString & a_String)
-{
- AppendShort(a_Dst, (unsigned short)a_String.size());
- a_Dst.append(a_String);
-}
-
-
-
-
-
-void cPacket::AppendString16(AString & a_Dst, const AString & a_String)
-{
- AppendShort(a_Dst, (unsigned short)a_String.size());
- AString UTF16;
- UTF16.resize(a_String.size() * sizeof(short));
- for( unsigned int i = 0; i < a_String.size(); ++i )
- {
- UTF16[i * sizeof( short )] = 0x00;
- UTF16[i * sizeof( short ) + 1] = a_String[i];
- }
- a_Dst.append(UTF16.data(), a_String.size() * sizeof(short));
-}
-
-
-
-
-
-void cPacket::AppendShort(AString & a_Dst, short a_Short)
-{
- short ConvertedShort = htons( a_Short );
- a_Dst.append((const char *)&ConvertedShort, sizeof(short));
-}
-
-
-
-
-
-void cPacket::AppendShort(AString & a_Dst, unsigned short a_Short)
-{
- short ConvertedShort = htons( a_Short );
- a_Dst.append((const char *)&ConvertedShort, sizeof(short));
-}
-
-
-
-
-
-void cPacket::AppendInteger(AString & a_Dst, int a_Integer)
-{
- int ConvertedInt = htonl( a_Integer );
- a_Dst.append((const char *)&ConvertedInt, sizeof(int));
-}
-
-
-
-
-
-void cPacket::AppendInteger(AString & a_Dst, unsigned int a_Integer)
-{
- unsigned int ConvertedInt = htonl( a_Integer );
- a_Dst.append((const char *)&ConvertedInt, sizeof(int));
-}
-
-
-
-
-
-void cPacket::AppendFloat(AString & a_Dst, float a_Float)
-{
- unsigned int ConvertedFloat = HostToNetwork4(&a_Float);
- a_Dst.append((const char *)&ConvertedFloat, sizeof(int));
-}
-
-
-
-
-
-void cPacket::AppendDouble(AString & a_Dst, const double & a_Double)
-{
- unsigned long long ConvertedDouble = HostToNetwork8(&a_Double);
- a_Dst.append((const char *)&ConvertedDouble, 8);
-}
-
-
-
-
-
-void cPacket::AppendByte(AString & a_Dst, char a_Byte)
-{
- a_Dst.append(&a_Byte, 1);
-}
-
-
-
-
-
-void cPacket::AppendLong(AString & a_Dst, const long long & a_Long)
-{
- unsigned long long ConvertedLong = HostToNetwork8(&a_Long);
- a_Dst.append((const char *)&ConvertedLong, sizeof(a_Long));
-}
-
-
-
-
-
-void cPacket::AppendBool(AString & a_Dst, bool a_Bool)
-{
- a_Dst.append((const char *)&a_Bool, 1);
-}
-
-
-
-
-
-void cPacket::AppendData(AString & a_Dst, const char * a_Data, unsigned int a_Size)
-{
- a_Dst.append(a_Data, a_Size);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket.h" +#include "../Endianness.h" + + + + + +/* +// These checks cannot be done in preprocessor, since sizeof() is evaluated while compiling, so in preprocessing it's unknown. +// Check some basic type assumptions: +#if (sizeof(int) != 4) + #error "Bad size for int, protocol won't work" +#endif + +#if (sizeof(float) != 4) + #error "Bad size for float, protocol won't work" +#endif + +#if (sizeof(double) != 8) + #error "Bad size for double, protocol won't work" +#endif +*/ + + + + + +int cPacket::ReadString16(const char * a_Data, int a_Size, AString & a_OutString ) +{ + int TotalBytes = 0; + short StrLen; + HANDLE_PACKET_READ(ReadShort, StrLen, TotalBytes); + + if (2 * StrLen > a_Size - TotalBytes) + { + // The string is not yet complete in the buffer + return PACKET_INCOMPLETE; + } + + // Simple UTF-16 to UTF-8 conversion - discard higher bits, ignore multishort sequences: + a_OutString.clear(); + a_OutString.reserve(StrLen); + short * UTF16 = (short *)(a_Data + TotalBytes); + for ( int i = 0; i < StrLen; ++i ) + { + a_OutString.push_back( (char)ntohs(UTF16[i]) ); + } + + return TotalBytes + StrLen * sizeof(short); +} + + + + + +int cPacket::ReadShort(const char * a_Data, int a_Size, short & a_OutShort ) +{ + if (a_Size < 2) + { + return PACKET_INCOMPLETE; + } + a_OutShort = ntohs(*((short *)a_Data)); + return 2; +} + + + + + +int cPacket::ReadInteger(const char * a_Data, int a_Size, int & a_OutInteger ) +{ + if (a_Size < 4) + { + return PACKET_INCOMPLETE; + } + a_OutInteger = ntohl(*((int *)a_Data)); + return 4; +} + + + + + +int cPacket::ReadInteger(const char * a_Data, int a_Size, unsigned int & a_OutInteger ) +{ + if (a_Size < 4) + { + return PACKET_INCOMPLETE; + } + a_OutInteger = ntohl(*((unsigned int *)a_Data)); + return 4; +} + + + + + +int cPacket::ReadFloat(const char * a_Data, int a_Size, float & a_OutFloat ) +{ + if (a_Size < sizeof(float)) + { + return PACKET_INCOMPLETE; + } + a_OutFloat = NetworkToHostFloat4(a_Data); + return sizeof(float); +} + + + + + +int cPacket::ReadDouble(const char * a_Data, int a_Size, double & a_OutDouble ) +{ + if (a_Size < sizeof(double)) + { + return PACKET_INCOMPLETE; + } + a_OutDouble = NetworkToHostDouble8(a_Data); + return sizeof(double); +} + + + + + +int cPacket::ReadByte(const char * a_Data, int a_Size, char & a_OutByte ) +{ + if (a_Size < 1) + { + return PACKET_INCOMPLETE; + } + a_OutByte = *a_Data; + return 1; +} + + + + + +int cPacket::ReadByte(const char * a_Data, int a_Size, unsigned char & a_OutByte ) +{ + if (a_Size < 1) + { + return PACKET_INCOMPLETE; + } + a_OutByte = *((unsigned char *)a_Data); + return 1; +} + + + + + +int cPacket::ReadLong(const char * a_Data, int a_Size, long long & a_OutLong ) +{ + if (a_Size < sizeof(a_OutLong)) + { + return PACKET_INCOMPLETE; + } + a_OutLong = NetworkToHostLong8(a_Data); + return sizeof(a_OutLong); +} + + + + + +int cPacket::ReadBool(const char * a_Data, int a_Size, bool & a_OutBool ) +{ + if (a_Size < sizeof(bool)) + { + return PACKET_INCOMPLETE; + } + a_OutBool = (*a_Data != 0); + return sizeof(bool); +} + + + + + +void cPacket::AppendString(AString & a_Dst, const AString & a_String) +{ + AppendShort(a_Dst, (unsigned short)a_String.size()); + a_Dst.append(a_String); +} + + + + + +void cPacket::AppendString16(AString & a_Dst, const AString & a_String) +{ + AppendShort(a_Dst, (unsigned short)a_String.size()); + AString UTF16; + UTF16.resize(a_String.size() * sizeof(short)); + for( unsigned int i = 0; i < a_String.size(); ++i ) + { + UTF16[i * sizeof( short )] = 0x00; + UTF16[i * sizeof( short ) + 1] = a_String[i]; + } + a_Dst.append(UTF16.data(), a_String.size() * sizeof(short)); +} + + + + + +void cPacket::AppendShort(AString & a_Dst, short a_Short) +{ + short ConvertedShort = htons( a_Short ); + a_Dst.append((const char *)&ConvertedShort, sizeof(short)); +} + + + + + +void cPacket::AppendShort(AString & a_Dst, unsigned short a_Short) +{ + short ConvertedShort = htons( a_Short ); + a_Dst.append((const char *)&ConvertedShort, sizeof(short)); +} + + + + + +void cPacket::AppendInteger(AString & a_Dst, int a_Integer) +{ + int ConvertedInt = htonl( a_Integer ); + a_Dst.append((const char *)&ConvertedInt, sizeof(int)); +} + + + + + +void cPacket::AppendInteger(AString & a_Dst, unsigned int a_Integer) +{ + unsigned int ConvertedInt = htonl( a_Integer ); + a_Dst.append((const char *)&ConvertedInt, sizeof(int)); +} + + + + + +void cPacket::AppendFloat(AString & a_Dst, float a_Float) +{ + unsigned int ConvertedFloat = HostToNetwork4(&a_Float); + a_Dst.append((const char *)&ConvertedFloat, sizeof(int)); +} + + + + + +void cPacket::AppendDouble(AString & a_Dst, const double & a_Double) +{ + unsigned long long ConvertedDouble = HostToNetwork8(&a_Double); + a_Dst.append((const char *)&ConvertedDouble, 8); +} + + + + + +void cPacket::AppendByte(AString & a_Dst, char a_Byte) +{ + a_Dst.append(&a_Byte, 1); +} + + + + + +void cPacket::AppendLong(AString & a_Dst, const long long & a_Long) +{ + unsigned long long ConvertedLong = HostToNetwork8(&a_Long); + a_Dst.append((const char *)&ConvertedLong, sizeof(a_Long)); +} + + + + + +void cPacket::AppendBool(AString & a_Dst, bool a_Bool) +{ + a_Dst.append((const char *)&a_Bool, 1); +} + + + + + +void cPacket::AppendData(AString & a_Dst, const char * a_Data, unsigned int a_Size) +{ + a_Dst.append(a_Data, a_Size); +} + + + + diff --git a/source/packets/cPacket.h b/source/packets/cPacket.h index 7eb224c9e..f5a014ed5 100644 --- a/source/packets/cPacket.h +++ b/source/packets/cPacket.h @@ -1,94 +1,94 @@ -
-#pragma once
-
-#include "../cSocket.h"
-#include "../PacketID.h"
-
-
-
-
-
-#define PACKET_INCOMPLETE -2
-#define PACKET_ERROR -1
-
-
-
-
-
-// Use this macro to simplify handling several ReadXXX in a row. It assumes that you want [a_Data, a_Size] parsed (which is true for all Parse() functions)
-#define HANDLE_PACKET_READ(Proc, Var, TotalBytes) \
- { \
- int res = Proc(a_Data + TotalBytes, a_Size - TotalBytes, Var); \
- if (res < 0) \
- { \
- return res; \
- } \
- TotalBytes += res; \
- }
-
-
-
-
-
-class cPacket
-{
-public:
- cPacket()
- : m_PacketID( 0 )
- {}
- virtual ~cPacket() {}
-
- /// Called to parse the packet. Packet type has already been read and the correct packet type created. Return the number of characters processed, PACKET_INCOMPLETE for incomplete data, PACKET_ERROR for error
- virtual int Parse(const char * a_Data, int a_Size)
- {
- LOGERROR("Undefined Parse function for packet type 0x%x\n", m_PacketID );
- ASSERT(!"Undefined Parse function");
- return -1;
- }
-
- /// Called to serialize the packet into a string. Append all packet data to a_Data, including the packet type!
- virtual void Serialize(AString & a_Data) const
- {
- LOGERROR("Undefined Serialize function for packet type 0x%x\n", m_PacketID );
- ASSERT(!"Undefined Serialize function");
- }
-
- virtual cPacket * Clone() const = 0;
-
- unsigned char m_PacketID;
-
-protected:
-
- // These return the number of characters processed, PACKET_INCOMPLETE for incomplete data, PACKET_ERROR for error:
- static int ReadString16(const char * a_Data, int a_Size, AString & a_OutString );
- static int ReadShort (const char * a_Data, int a_Size, short & a_Short );
- static int ReadInteger (const char * a_Data, int a_Size, int & a_OutInteger );
- static int ReadInteger (const char * a_Data, int a_Size, unsigned int & a_OutInteger );
- static int ReadFloat (const char * a_Data, int a_Size, float & a_OutFloat );
- static int ReadDouble (const char * a_Data, int a_Size, double & a_OutDouble );
- static int ReadByte (const char * a_Data, int a_Size, char & a_OutByte );
- static int ReadByte (const char * a_Data, int a_Size, unsigned char & a_OutByte );
- static int ReadLong (const char * a_Data, int a_Size, long long & a_OutLong );
- static int ReadBool (const char * a_Data, int a_Size, bool & a_OutBool );
-
- // These append the data into the a_Dst string:
- static void AppendString ( AString & a_Dst, const AString & a_String);
- static void AppendString16( AString & a_Dst, const AString & a_String);
- static void AppendShort ( AString & a_Dst, short a_Short);
- static void AppendShort ( AString & a_Dst, unsigned short a_Short);
- static void AppendInteger ( AString & a_Dst, int a_Integer);
- static void AppendInteger ( AString & a_Dst, unsigned int a_Integer);
- static void AppendFloat ( AString & a_Dst, float a_Float);
- static void AppendDouble ( AString & a_Dst, const double & a_Double);
- static void AppendByte ( AString & a_Dst, char a_Byte);
- static void AppendLong ( AString & a_Dst, const long long & a_Long);
- static void AppendBool ( AString & a_Dst, bool a_Bool);
- static void AppendData ( AString & a_Dst, const char * a_Data, unsigned int a_Size);
-};
-
-typedef std::list <cPacket*> PacketList;
-typedef std::deque<cPacket *> PacketQueue;
-
-
-
-
+ +#pragma once + +#include "../cSocket.h" +#include "../PacketID.h" + + + + + +#define PACKET_INCOMPLETE -2 +#define PACKET_ERROR -1 + + + + + +// Use this macro to simplify handling several ReadXXX in a row. It assumes that you want [a_Data, a_Size] parsed (which is true for all Parse() functions) +#define HANDLE_PACKET_READ(Proc, Var, TotalBytes) \ + { \ + int res = Proc(a_Data + TotalBytes, a_Size - TotalBytes, Var); \ + if (res < 0) \ + { \ + return res; \ + } \ + TotalBytes += res; \ + } + + + + + +class cPacket +{ +public: + cPacket() + : m_PacketID( 0 ) + {} + virtual ~cPacket() {} + + /// Called to parse the packet. Packet type has already been read and the correct packet type created. Return the number of characters processed, PACKET_INCOMPLETE for incomplete data, PACKET_ERROR for error + virtual int Parse(const char * a_Data, int a_Size) + { + LOGERROR("Undefined Parse function for packet type 0x%x\n", m_PacketID ); + ASSERT(!"Undefined Parse function"); + return -1; + } + + /// Called to serialize the packet into a string. Append all packet data to a_Data, including the packet type! + virtual void Serialize(AString & a_Data) const + { + LOGERROR("Undefined Serialize function for packet type 0x%x\n", m_PacketID ); + ASSERT(!"Undefined Serialize function"); + } + + virtual cPacket * Clone() const = 0; + + unsigned char m_PacketID; + +protected: + + // These return the number of characters processed, PACKET_INCOMPLETE for incomplete data, PACKET_ERROR for error: + static int ReadString16(const char * a_Data, int a_Size, AString & a_OutString ); + static int ReadShort (const char * a_Data, int a_Size, short & a_Short ); + static int ReadInteger (const char * a_Data, int a_Size, int & a_OutInteger ); + static int ReadInteger (const char * a_Data, int a_Size, unsigned int & a_OutInteger ); + static int ReadFloat (const char * a_Data, int a_Size, float & a_OutFloat ); + static int ReadDouble (const char * a_Data, int a_Size, double & a_OutDouble ); + static int ReadByte (const char * a_Data, int a_Size, char & a_OutByte ); + static int ReadByte (const char * a_Data, int a_Size, unsigned char & a_OutByte ); + static int ReadLong (const char * a_Data, int a_Size, long long & a_OutLong ); + static int ReadBool (const char * a_Data, int a_Size, bool & a_OutBool ); + + // These append the data into the a_Dst string: + static void AppendString ( AString & a_Dst, const AString & a_String); + static void AppendString16( AString & a_Dst, const AString & a_String); + static void AppendShort ( AString & a_Dst, short a_Short); + static void AppendShort ( AString & a_Dst, unsigned short a_Short); + static void AppendInteger ( AString & a_Dst, int a_Integer); + static void AppendInteger ( AString & a_Dst, unsigned int a_Integer); + static void AppendFloat ( AString & a_Dst, float a_Float); + static void AppendDouble ( AString & a_Dst, const double & a_Double); + static void AppendByte ( AString & a_Dst, char a_Byte); + static void AppendLong ( AString & a_Dst, const long long & a_Long); + static void AppendBool ( AString & a_Dst, bool a_Bool); + static void AppendData ( AString & a_Dst, const char * a_Data, unsigned int a_Size); +}; + +typedef std::list <cPacket*> PacketList; +typedef std::deque<cPacket *> PacketQueue; + + + + diff --git a/source/packets/cPacket_13.cpp b/source/packets/cPacket_13.cpp index aebef4410..4edeb8c95 100644 --- a/source/packets/cPacket_13.cpp +++ b/source/packets/cPacket_13.cpp @@ -1,20 +1,20 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_13.h"
-
-
-
-
-
-int cPacket_13::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadInteger, m_EntityID, TotalBytes);
- HANDLE_PACKET_READ(ReadByte , m_ActionID, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_13.h" + + + + + +int cPacket_13::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_EntityID, TotalBytes); + HANDLE_PACKET_READ(ReadByte , m_ActionID, TotalBytes); + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_13.h b/source/packets/cPacket_13.h index 361e35fe7..d0a257302 100644 --- a/source/packets/cPacket_13.h +++ b/source/packets/cPacket_13.h @@ -1,34 +1,34 @@ -#pragma once
-
-#include "cPacket.h"
-
-
-class cPacket_13 : public cPacket
-{
-public:
- enum ENUM_ACTION
- {
- ACTION_CROUCH = 1,
- ACTION_UNCROUCH = 2,
- ACTION_LEAVEBED = 3,
- ACTION_STARTSPRINTING = 4,
- ACTION_STOPSPRINTING = 5,
- };
-
- cPacket_13()
- : m_EntityID( 0 )
- , m_ActionID( 0 )
- { m_PacketID = E_PACKET_13; }
- virtual cPacket* Clone() const { return new cPacket_13( *this ); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
-
- int m_EntityID;
- char m_ActionID;
-
- static const unsigned int c_Size = 1;
-};
-
-
-
-
+#pragma once + +#include "cPacket.h" + + +class cPacket_13 : public cPacket +{ +public: + enum ENUM_ACTION + { + ACTION_CROUCH = 1, + ACTION_UNCROUCH = 2, + ACTION_LEAVEBED = 3, + ACTION_STARTSPRINTING = 4, + ACTION_STOPSPRINTING = 5, + }; + + cPacket_13() + : m_EntityID( 0 ) + , m_ActionID( 0 ) + { m_PacketID = E_PACKET_13; } + virtual cPacket* Clone() const { return new cPacket_13( *this ); } + + virtual int Parse(const char * a_Data, int a_Size) override; + + int m_EntityID; + char m_ActionID; + + static const unsigned int c_Size = 1; +}; + + + + diff --git a/source/packets/cPacket_AddToInventory.cpp b/source/packets/cPacket_AddToInventory.cpp index c8606afe0..b9231112c 100644 --- a/source/packets/cPacket_AddToInventory.cpp +++ b/source/packets/cPacket_AddToInventory.cpp @@ -1,20 +1,20 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_AddToInventory.h"
-#include "cPacket_WholeInventory.h"
-#include "cPacket_ItemData.h"
-
-
-
-
-
-void cPacket_AddToInventory::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- cPacket_ItemData::AppendItem(a_Data, m_ItemType, m_Count, m_Life);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_AddToInventory.h" +#include "cPacket_WholeInventory.h" +#include "cPacket_ItemData.h" + + + + + +void cPacket_AddToInventory::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + cPacket_ItemData::AppendItem(a_Data, m_ItemType, m_Count, m_Life); +} + + + + diff --git a/source/packets/cPacket_AddToInventory.h b/source/packets/cPacket_AddToInventory.h index 4317607a5..f7e1a084b 100644 --- a/source/packets/cPacket_AddToInventory.h +++ b/source/packets/cPacket_AddToInventory.h @@ -1,26 +1,26 @@ -#pragma once
-
-#include "cPacket.h"
-
-#include "../BlockID.h"
-
-class cPacket_AddToInventory : public cPacket
-{
-public:
- cPacket_AddToInventory()
- : m_ItemType( E_ITEM_EMPTY )
- , m_Count( 0 )
- , m_Life( 0 )
- { m_PacketID = E_ADD_TO_INV; }
- virtual cPacket* Clone() const { return new cPacket_AddToInventory(*this); }
-
- // _X: This was unimplemented, do we need it?:
- // bool Parse( cSocket & a_Socket );
-
- virtual void Serialize(AString & a_Data) const override;
-
- ENUM_ITEM_ID m_ItemType;
- char m_Count;
- short m_Life;
- static const unsigned int c_Size = 1;
-};
+#pragma once + +#include "cPacket.h" + +#include "../BlockID.h" + +class cPacket_AddToInventory : public cPacket +{ +public: + cPacket_AddToInventory() + : m_ItemType( E_ITEM_EMPTY ) + , m_Count( 0 ) + , m_Life( 0 ) + { m_PacketID = E_ADD_TO_INV; } + virtual cPacket* Clone() const { return new cPacket_AddToInventory(*this); } + + // _X: This was unimplemented, do we need it?: + // bool Parse( cSocket & a_Socket ); + + virtual void Serialize(AString & a_Data) const override; + + ENUM_ITEM_ID m_ItemType; + char m_Count; + short m_Life; + static const unsigned int c_Size = 1; +}; diff --git a/source/packets/cPacket_ArmAnim.cpp b/source/packets/cPacket_ArmAnim.cpp index c1766e8ce..dcd416449 100644 --- a/source/packets/cPacket_ArmAnim.cpp +++ b/source/packets/cPacket_ArmAnim.cpp @@ -1,31 +1,31 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_ArmAnim.h"
-
-
-
-
-
-int cPacket_ArmAnim::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadInteger, m_EntityID, TotalBytes);
- HANDLE_PACKET_READ(ReadByte , m_Animation, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_ArmAnim::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_EntityID);
- AppendByte (a_Data, m_Animation);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_ArmAnim.h" + + + + + +int cPacket_ArmAnim::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_EntityID, TotalBytes); + HANDLE_PACKET_READ(ReadByte , m_Animation, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_ArmAnim::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_EntityID); + AppendByte (a_Data, m_Animation); +} + + + + diff --git a/source/packets/cPacket_ArmAnim.h b/source/packets/cPacket_ArmAnim.h index 07753ebcb..79670de1c 100644 --- a/source/packets/cPacket_ArmAnim.h +++ b/source/packets/cPacket_ArmAnim.h @@ -1,21 +1,21 @@ -#pragma once
-
-#include "cPacket.h"
-
-
-class cPacket_ArmAnim : public cPacket
-{
-public:
- cPacket_ArmAnim()
- : m_EntityID( 0 )
- , m_Animation( 0 )
- { m_PacketID = E_ANIMATION; }
- virtual cPacket* Clone() const { return new cPacket_ArmAnim(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- int m_EntityID;
- char m_Animation;
- static const unsigned int c_Size = 1 + 4 + 1;
+#pragma once + +#include "cPacket.h" + + +class cPacket_ArmAnim : public cPacket +{ +public: + cPacket_ArmAnim() + : m_EntityID( 0 ) + , m_Animation( 0 ) + { m_PacketID = E_ANIMATION; } + virtual cPacket* Clone() const { return new cPacket_ArmAnim(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + int m_EntityID; + char m_Animation; + static const unsigned int c_Size = 1 + 4 + 1; };
\ No newline at end of file diff --git a/source/packets/cPacket_BlockChange.cpp b/source/packets/cPacket_BlockChange.cpp index 57c938814..e0ef5c001 100644 --- a/source/packets/cPacket_BlockChange.cpp +++ b/source/packets/cPacket_BlockChange.cpp @@ -1,22 +1,22 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_BlockChange.h"
-
-
-
-
-
-void cPacket_BlockChange::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_PosX);
- AppendByte (a_Data, m_PosY);
- AppendInteger(a_Data, m_PosZ);
- AppendByte (a_Data, m_BlockType);
- AppendByte (a_Data, m_BlockMeta);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_BlockChange.h" + + + + + +void cPacket_BlockChange::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_PosX); + AppendByte (a_Data, m_PosY); + AppendInteger(a_Data, m_PosZ); + AppendByte (a_Data, m_BlockType); + AppendByte (a_Data, m_BlockMeta); +} + + + + diff --git a/source/packets/cPacket_BlockChange.h b/source/packets/cPacket_BlockChange.h index a0b3c8843..039043cf0 100644 --- a/source/packets/cPacket_BlockChange.h +++ b/source/packets/cPacket_BlockChange.h @@ -1,27 +1,27 @@ -#pragma once
-
-#include "cPacket.h"
-
-
-class cPacket_BlockChange : public cPacket
-{
-public:
- cPacket_BlockChange()
- : m_PosX( 0 )
- , m_PosY( 0 )
- , m_PosZ( 0 )
- , m_BlockType( 0 )
- , m_BlockMeta( 0 )
- { m_PacketID = E_BLOCK_CHANGE; }
- virtual cPacket* Clone() const { return new cPacket_BlockChange(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- int m_PosX;
- unsigned char m_PosY;
- int m_PosZ;
- char m_BlockType;
- char m_BlockMeta;
-
- static const unsigned int c_Size = 1 + 4 + 1 + 4 + 1 + 1;
+#pragma once + +#include "cPacket.h" + + +class cPacket_BlockChange : public cPacket +{ +public: + cPacket_BlockChange() + : m_PosX( 0 ) + , m_PosY( 0 ) + , m_PosZ( 0 ) + , m_BlockType( 0 ) + , m_BlockMeta( 0 ) + { m_PacketID = E_BLOCK_CHANGE; } + virtual cPacket* Clone() const { return new cPacket_BlockChange(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_PosX; + unsigned char m_PosY; + int m_PosZ; + char m_BlockType; + char m_BlockMeta; + + static const unsigned int c_Size = 1 + 4 + 1 + 4 + 1 + 1; };
\ No newline at end of file diff --git a/source/packets/cPacket_BlockDig.cpp b/source/packets/cPacket_BlockDig.cpp index 466e77340..be2088cd0 100644 --- a/source/packets/cPacket_BlockDig.cpp +++ b/source/packets/cPacket_BlockDig.cpp @@ -1,36 +1,36 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_BlockDig.h"
-
-
-
-
-
-void cPacket_BlockDig::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_PosX);
- AppendByte (a_Data, m_PosY);
- AppendInteger(a_Data, m_PosZ);
- AppendByte (a_Data, m_Direction);
-}
-
-
-
-
-
-int cPacket_BlockDig::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadByte, m_Status, TotalBytes);
- HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes);
- HANDLE_PACKET_READ(ReadByte, m_PosY, TotalBytes);
- HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes);
- HANDLE_PACKET_READ(ReadByte, m_Direction, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_BlockDig.h" + + + + + +void cPacket_BlockDig::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_PosX); + AppendByte (a_Data, m_PosY); + AppendInteger(a_Data, m_PosZ); + AppendByte (a_Data, m_Direction); +} + + + + + +int cPacket_BlockDig::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadByte, m_Status, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_PosY, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Direction, TotalBytes); + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_BlockDig.h b/source/packets/cPacket_BlockDig.h index 56ddfa9ca..1fde63db6 100644 --- a/source/packets/cPacket_BlockDig.h +++ b/source/packets/cPacket_BlockDig.h @@ -1,32 +1,32 @@ -#pragma once
-
-#include "cPacket.h"
-
-
-class cPacket_BlockDig : public cPacket //tolua_export
-{ //tolua_export
-public:
- cPacket_BlockDig() //tolua_export
- : m_Status( 0 )
- , m_PosX( 0 )
- , m_PosY( 0 )
- , m_PosZ( 0 )
- , m_Direction( 0 )
- { m_PacketID = E_BLOCK_DIG; } //tolua_export
- virtual cPacket* Clone() const { return new cPacket_BlockDig(*this); } //tolua_export
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- char m_Status; // tolua_export
- int m_PosX; // tolua_export
- char m_PosY; // tolua_export
- int m_PosZ; // tolua_export
- char m_Direction; // tolua_export
-
- static const unsigned int c_Size = 12;
-}; //tolua_export
-
-
-
-
+#pragma once + +#include "cPacket.h" + + +class cPacket_BlockDig : public cPacket //tolua_export +{ //tolua_export +public: + cPacket_BlockDig() //tolua_export + : m_Status( 0 ) + , m_PosX( 0 ) + , m_PosY( 0 ) + , m_PosZ( 0 ) + , m_Direction( 0 ) + { m_PacketID = E_BLOCK_DIG; } //tolua_export + virtual cPacket* Clone() const { return new cPacket_BlockDig(*this); } //tolua_export + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + char m_Status; // tolua_export + int m_PosX; // tolua_export + char m_PosY; // tolua_export + int m_PosZ; // tolua_export + char m_Direction; // tolua_export + + static const unsigned int c_Size = 12; +}; //tolua_export + + + + diff --git a/source/packets/cPacket_BlockPlace.cpp b/source/packets/cPacket_BlockPlace.cpp index 6582c7890..2033bd91e 100644 --- a/source/packets/cPacket_BlockPlace.cpp +++ b/source/packets/cPacket_BlockPlace.cpp @@ -1,36 +1,36 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_BlockPlace.h"
-#include "cPacket_ItemData.h"
-
-
-
-
-
-int cPacket_BlockPlace::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes);
- HANDLE_PACKET_READ(ReadByte, m_PosY, TotalBytes);
- HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes);
- HANDLE_PACKET_READ(ReadByte, m_Direction, TotalBytes);
-
- cPacket_ItemData Item;
- int res = Item.Parse(a_Data + TotalBytes, a_Size - TotalBytes);
- if (res < 0)
- {
- return res;
- }
- TotalBytes += res;
-
- m_ItemType = Item.m_ItemID;
- m_Count = Item.m_ItemCount;
- m_Uses = Item.m_ItemUses;
-
- return TotalBytes;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_BlockPlace.h" +#include "cPacket_ItemData.h" + + + + + +int cPacket_BlockPlace::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_PosY, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Direction, TotalBytes); + + cPacket_ItemData Item; + int res = Item.Parse(a_Data + TotalBytes, a_Size - TotalBytes); + if (res < 0) + { + return res; + } + TotalBytes += res; + + m_ItemType = Item.m_ItemID; + m_Count = Item.m_ItemCount; + m_Uses = Item.m_ItemUses; + + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_BlockPlace.h b/source/packets/cPacket_BlockPlace.h index 9fa2fbbce..b8db56fd0 100644 --- a/source/packets/cPacket_BlockPlace.h +++ b/source/packets/cPacket_BlockPlace.h @@ -1,40 +1,40 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_BlockPlace : public cPacket //tolua_export
-{ //tolua_export
-public:
- cPacket_BlockPlace()
- : m_PosX( 0 )
- , m_PosY( 0 )
- , m_PosZ( 0 )
- , m_Direction( 0 )
- , m_ItemType( 0 )
- , m_Count( 0 )
- , m_Uses( 0 )
- { m_PacketID = E_BLOCK_PLACE; }
- virtual cPacket* Clone() const { return new cPacket_BlockPlace(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
-
- int m_PosX; //tolua_export
- unsigned char m_PosY; //tolua_export
- int m_PosZ; //tolua_export
- char m_Direction; //tolua_export
-
- short m_ItemType; //tolua_export
- char m_Count; //tolua_export
- short m_Uses; //tolua_export
-
- static const unsigned int c_Size = 1 + 4 + 1 + 4 + 1 + 2;// ( + 2 )
-}; //tolua_export
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_BlockPlace : public cPacket //tolua_export +{ //tolua_export +public: + cPacket_BlockPlace() + : m_PosX( 0 ) + , m_PosY( 0 ) + , m_PosZ( 0 ) + , m_Direction( 0 ) + , m_ItemType( 0 ) + , m_Count( 0 ) + , m_Uses( 0 ) + { m_PacketID = E_BLOCK_PLACE; } + virtual cPacket* Clone() const { return new cPacket_BlockPlace(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + + int m_PosX; //tolua_export + unsigned char m_PosY; //tolua_export + int m_PosZ; //tolua_export + char m_Direction; //tolua_export + + short m_ItemType; //tolua_export + char m_Count; //tolua_export + short m_Uses; //tolua_export + + static const unsigned int c_Size = 1 + 4 + 1 + 4 + 1 + 2;// ( + 2 ) +}; //tolua_export + + + + diff --git a/source/packets/cPacket_Chat.cpp b/source/packets/cPacket_Chat.cpp index 04a65d18e..43b1af3fa 100644 --- a/source/packets/cPacket_Chat.cpp +++ b/source/packets/cPacket_Chat.cpp @@ -1,29 +1,29 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_Chat.h"
-
-
-
-
-
-int cPacket_Chat::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadString16, m_Message, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_Chat::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendString16(a_Data, m_Message);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_Chat.h" + + + + + +int cPacket_Chat::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadString16, m_Message, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_Chat::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendString16(a_Data, m_Message); +} + + + + diff --git a/source/packets/cPacket_Chat.h b/source/packets/cPacket_Chat.h index 4141439d9..fac4a4097 100644 --- a/source/packets/cPacket_Chat.h +++ b/source/packets/cPacket_Chat.h @@ -1,22 +1,22 @@ -#pragma once
-
-#include "cPacket.h"
-
-
-class cPacket_Chat : public cPacket
-{
-public:
- cPacket_Chat() { m_PacketID = E_CHAT; }
- cPacket_Chat( const std::string & a_Message ) : m_Message( a_Message) { m_PacketID = E_CHAT; }
- virtual cPacket* Clone() const { return new cPacket_Chat(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- AString m_Message;
- static const unsigned int c_Size = 3; // Minimum size
-};
-
-
-
-
+#pragma once + +#include "cPacket.h" + + +class cPacket_Chat : public cPacket +{ +public: + cPacket_Chat() { m_PacketID = E_CHAT; } + cPacket_Chat( const std::string & a_Message ) : m_Message( a_Message) { m_PacketID = E_CHAT; } + virtual cPacket* Clone() const { return new cPacket_Chat(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + AString m_Message; + static const unsigned int c_Size = 3; // Minimum size +}; + + + + diff --git a/source/packets/cPacket_CollectItem.cpp b/source/packets/cPacket_CollectItem.cpp index 466eda6b7..39f4cdde2 100644 --- a/source/packets/cPacket_CollectItem.cpp +++ b/source/packets/cPacket_CollectItem.cpp @@ -1,19 +1,19 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_CollectItem.h"
-
-
-
-
-
-void cPacket_CollectItem::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_CollectedID);
- AppendInteger(a_Data, m_CollectorID);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_CollectItem.h" + + + + + +void cPacket_CollectItem::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_CollectedID); + AppendInteger(a_Data, m_CollectorID); +} + + + + diff --git a/source/packets/cPacket_CollectItem.h b/source/packets/cPacket_CollectItem.h index b424ab4b7..29ab78ff8 100644 --- a/source/packets/cPacket_CollectItem.h +++ b/source/packets/cPacket_CollectItem.h @@ -1,27 +1,27 @@ -#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_CollectItem : public cPacket
-{
-public:
- cPacket_CollectItem()
- : m_CollectedID( 0 )
- , m_CollectorID( 0 )
- { m_PacketID = E_COLLECT_ITEM; }
- virtual cPacket* Clone() const { return new cPacket_CollectItem(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- int m_CollectedID;
- int m_CollectorID;
- static const unsigned int c_Size = 1 + 4 + 4;
-};
-
-
-
-
+#pragma once + +#include "cPacket.h" + + + + + +class cPacket_CollectItem : public cPacket +{ +public: + cPacket_CollectItem() + : m_CollectedID( 0 ) + , m_CollectorID( 0 ) + { m_PacketID = E_COLLECT_ITEM; } + virtual cPacket* Clone() const { return new cPacket_CollectItem(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_CollectedID; + int m_CollectorID; + static const unsigned int c_Size = 1 + 4 + 4; +}; + + + + diff --git a/source/packets/cPacket_CreativeInventoryAction.cpp b/source/packets/cPacket_CreativeInventoryAction.cpp index de6cc1488..46f125701 100644 --- a/source/packets/cPacket_CreativeInventoryAction.cpp +++ b/source/packets/cPacket_CreativeInventoryAction.cpp @@ -1,67 +1,67 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_CreativeInventoryAction.h"
-#include "cPacket_ItemData.h"
-
-
-
-
-
-cPacket_CreativeInventoryAction::cPacket_CreativeInventoryAction( const cPacket_CreativeInventoryAction & a_Copy )
-{
- m_PacketID = E_CREATIVE_INVENTORY_ACTION;
- m_Slot = a_Copy.m_Slot;
- m_ItemID = a_Copy.m_ItemID;
- m_Quantity = a_Copy.m_Quantity;
- m_Damage = a_Copy.m_Damage;
-}
-
-
-
-
-
-int cPacket_CreativeInventoryAction::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadShort, m_Slot, TotalBytes);
-
- cPacket_ItemData Item;
- int res = Item.Parse(a_Data + TotalBytes, a_Size - TotalBytes);
- if (res < 0)
- {
- return res;
- }
- TotalBytes += res;
-
- m_ItemID = Item.m_ItemID;
- m_Quantity = Item.m_ItemCount;
- m_Damage = Item.m_ItemUses;
-
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_CreativeInventoryAction::Serialize(AString & a_Data) const
-{
- short ItemID = m_ItemID;
- ASSERT(ItemID >= -1); // Check validity of packets in debug runtime
- if (ItemID <= 0)
- {
- ItemID = -1;
- // Fix, to make sure no invalid values are sent.
- // WARNING: HERE ITS -1, BUT IN NAMED ENTITY SPAWN PACKET ITS 0 !!
- }
-
- AppendByte (a_Data, m_PacketID);
- AppendShort (a_Data, m_Slot);
-
- cPacket_ItemData::AppendItem(a_Data, ItemID, m_Quantity, m_Damage);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_CreativeInventoryAction.h" +#include "cPacket_ItemData.h" + + + + + +cPacket_CreativeInventoryAction::cPacket_CreativeInventoryAction( const cPacket_CreativeInventoryAction & a_Copy ) +{ + m_PacketID = E_CREATIVE_INVENTORY_ACTION; + m_Slot = a_Copy.m_Slot; + m_ItemID = a_Copy.m_ItemID; + m_Quantity = a_Copy.m_Quantity; + m_Damage = a_Copy.m_Damage; +} + + + + + +int cPacket_CreativeInventoryAction::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadShort, m_Slot, TotalBytes); + + cPacket_ItemData Item; + int res = Item.Parse(a_Data + TotalBytes, a_Size - TotalBytes); + if (res < 0) + { + return res; + } + TotalBytes += res; + + m_ItemID = Item.m_ItemID; + m_Quantity = Item.m_ItemCount; + m_Damage = Item.m_ItemUses; + + return TotalBytes; +} + + + + + +void cPacket_CreativeInventoryAction::Serialize(AString & a_Data) const +{ + short ItemID = m_ItemID; + ASSERT(ItemID >= -1); // Check validity of packets in debug runtime + if (ItemID <= 0) + { + ItemID = -1; + // Fix, to make sure no invalid values are sent. + // WARNING: HERE ITS -1, BUT IN NAMED ENTITY SPAWN PACKET ITS 0 !! + } + + AppendByte (a_Data, m_PacketID); + AppendShort (a_Data, m_Slot); + + cPacket_ItemData::AppendItem(a_Data, ItemID, m_Quantity, m_Damage); +} + + + + diff --git a/source/packets/cPacket_DestroyEntity.cpp b/source/packets/cPacket_DestroyEntity.cpp index cd41b380b..d7e1d085b 100644 --- a/source/packets/cPacket_DestroyEntity.cpp +++ b/source/packets/cPacket_DestroyEntity.cpp @@ -1,30 +1,30 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_DestroyEntity.h"
-#include "../cEntity.h"
-
-
-
-
-
-cPacket_DestroyEntity::cPacket_DestroyEntity(cEntity* a_Entity)
-{
- m_PacketID = E_DESTROY_ENT;
-
- m_UniqueID = a_Entity->GetUniqueID();
-}
-
-
-
-
-
-void cPacket_DestroyEntity::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_UniqueID);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_DestroyEntity.h" +#include "../cEntity.h" + + + + + +cPacket_DestroyEntity::cPacket_DestroyEntity(cEntity* a_Entity) +{ + m_PacketID = E_DESTROY_ENT; + + m_UniqueID = a_Entity->GetUniqueID(); +} + + + + + +void cPacket_DestroyEntity::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); +} + + + + diff --git a/source/packets/cPacket_DestroyEntity.h b/source/packets/cPacket_DestroyEntity.h index 5f2314e55..b4146e971 100644 --- a/source/packets/cPacket_DestroyEntity.h +++ b/source/packets/cPacket_DestroyEntity.h @@ -1,33 +1,33 @@ -#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cEntity;
-
-
-
-
-
-class cPacket_DestroyEntity : public cPacket
-{
-public:
- cPacket_DestroyEntity()
- : m_UniqueID( 0 )
- { m_PacketID = E_DESTROY_ENT; }
- cPacket_DestroyEntity(cEntity* a_Entity);
- virtual cPacket* Clone() const { return new cPacket_DestroyEntity(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- int m_UniqueID;
-
- static const unsigned int c_Size = 1 + 4;
-};
-
-
-
-
+#pragma once + +#include "cPacket.h" + + + + + +class cEntity; + + + + + +class cPacket_DestroyEntity : public cPacket +{ +public: + cPacket_DestroyEntity() + : m_UniqueID( 0 ) + { m_PacketID = E_DESTROY_ENT; } + cPacket_DestroyEntity(cEntity* a_Entity); + virtual cPacket* Clone() const { return new cPacket_DestroyEntity(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + + static const unsigned int c_Size = 1 + 4; +}; + + + + diff --git a/source/packets/cPacket_Disconnect.cpp b/source/packets/cPacket_Disconnect.cpp index 82342c303..0ddad3744 100644 --- a/source/packets/cPacket_Disconnect.cpp +++ b/source/packets/cPacket_Disconnect.cpp @@ -1,29 +1,29 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_Disconnect.h"
-
-
-
-
-
-int cPacket_Disconnect::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadString16, m_Reason, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_Disconnect::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendString16(a_Data, m_Reason);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_Disconnect.h" + + + + + +int cPacket_Disconnect::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadString16, m_Reason, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_Disconnect::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendString16(a_Data, m_Reason); +} + + + + diff --git a/source/packets/cPacket_Disconnect.h b/source/packets/cPacket_Disconnect.h index ccb3811b5..e91a09980 100644 --- a/source/packets/cPacket_Disconnect.h +++ b/source/packets/cPacket_Disconnect.h @@ -1,26 +1,26 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_Disconnect : public cPacket
-{
-public:
- cPacket_Disconnect() { m_PacketID = E_DISCONNECT; }
- cPacket_Disconnect(const AString & a_Reason) { m_PacketID = E_DISCONNECT; m_Reason = a_Reason; }
- virtual cPacket* Clone() const { return new cPacket_Disconnect(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- AString m_Reason;
- static const unsigned int c_Size = 3; // Minimum size
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_Disconnect : public cPacket +{ +public: + cPacket_Disconnect() { m_PacketID = E_DISCONNECT; } + cPacket_Disconnect(const AString & a_Reason) { m_PacketID = E_DISCONNECT; m_Reason = a_Reason; } + virtual cPacket* Clone() const { return new cPacket_Disconnect(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + AString m_Reason; + static const unsigned int c_Size = 3; // Minimum size +}; + + + + diff --git a/source/packets/cPacket_EntityEquipment.cpp b/source/packets/cPacket_EntityEquipment.cpp index a89cb9724..08bf30a6e 100644 --- a/source/packets/cPacket_EntityEquipment.cpp +++ b/source/packets/cPacket_EntityEquipment.cpp @@ -1,48 +1,48 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_EntityEquipment.h"
-
-
-
-
-
-cPacket_EntityEquipment::cPacket_EntityEquipment( const cPacket_EntityEquipment & a_Copy )
-{
- m_PacketID = E_ENTITY_EQUIPMENT;
- m_UniqueID = a_Copy.m_UniqueID;
- m_Slot = a_Copy.m_Slot;
- m_ItemID = a_Copy.m_ItemID;
- m_Short = 0;
-}
-
-
-
-
-
-int cPacket_EntityEquipment::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadInteger, m_UniqueID, TotalBytes);
- HANDLE_PACKET_READ(ReadShort, m_Slot, TotalBytes);
- HANDLE_PACKET_READ(ReadShort, m_ItemID, TotalBytes);
- HANDLE_PACKET_READ(ReadShort, m_Short, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_EntityEquipment::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_UniqueID);
- AppendShort (a_Data, m_Slot);
- AppendShort (a_Data, m_ItemID);
- AppendShort (a_Data, m_Short);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_EntityEquipment.h" + + + + + +cPacket_EntityEquipment::cPacket_EntityEquipment( const cPacket_EntityEquipment & a_Copy ) +{ + m_PacketID = E_ENTITY_EQUIPMENT; + m_UniqueID = a_Copy.m_UniqueID; + m_Slot = a_Copy.m_Slot; + m_ItemID = a_Copy.m_ItemID; + m_Short = 0; +} + + + + + +int cPacket_EntityEquipment::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_UniqueID, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_Slot, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_ItemID, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_Short, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_EntityEquipment::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendShort (a_Data, m_Slot); + AppendShort (a_Data, m_ItemID); + AppendShort (a_Data, m_Short); +} + + + + diff --git a/source/packets/cPacket_EntityEquipment.h b/source/packets/cPacket_EntityEquipment.h index 4beda6063..ec09bbf5c 100644 --- a/source/packets/cPacket_EntityEquipment.h +++ b/source/packets/cPacket_EntityEquipment.h @@ -1,34 +1,34 @@ -#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_EntityEquipment : public cPacket
-{
-public:
- cPacket_EntityEquipment()
- : m_UniqueID( 0 )
- , m_Slot( 0 )
- , m_ItemID( 0 )
- , m_Short( 0 )
- { m_PacketID = E_ENTITY_EQUIPMENT; m_Short = 0; }
- cPacket_EntityEquipment( const cPacket_EntityEquipment & a_Copy );
- virtual cPacket* Clone() const { return new cPacket_EntityEquipment(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- int m_UniqueID;
- short m_Slot; // 0 = hold 1-4 = armor
- short m_ItemID;
- short m_Short;
-
- static const unsigned int c_Size = 1 + 4 + 2 + 2 + 2;
-};
-
-
-
-
+#pragma once + +#include "cPacket.h" + + + + + +class cPacket_EntityEquipment : public cPacket +{ +public: + cPacket_EntityEquipment() + : m_UniqueID( 0 ) + , m_Slot( 0 ) + , m_ItemID( 0 ) + , m_Short( 0 ) + { m_PacketID = E_ENTITY_EQUIPMENT; m_Short = 0; } + cPacket_EntityEquipment( const cPacket_EntityEquipment & a_Copy ); + virtual cPacket* Clone() const { return new cPacket_EntityEquipment(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + short m_Slot; // 0 = hold 1-4 = armor + short m_ItemID; + short m_Short; + + static const unsigned int c_Size = 1 + 4 + 2 + 2 + 2; +}; + + + + diff --git a/source/packets/cPacket_EntityLook.cpp b/source/packets/cPacket_EntityLook.cpp index d25f788c0..04fc46d4d 100644 --- a/source/packets/cPacket_EntityLook.cpp +++ b/source/packets/cPacket_EntityLook.cpp @@ -1,64 +1,64 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_EntityLook.h"
-
-#include "../cEntity.h"
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cPacket_EntityLook:
-
-cPacket_EntityLook::cPacket_EntityLook(const cEntity & a_Entity)
-{
- m_PacketID = E_ENT_LOOK;
-
- m_UniqueID = a_Entity.GetUniqueID();
- m_Rotation = (char)((a_Entity.GetRotation() / 360.f) * 256);
- m_Pitch = (char)((a_Entity.GetPitch() / 360.f) * 256);
-}
-
-
-
-
-
-void cPacket_EntityLook::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_UniqueID);
- AppendByte (a_Data, m_Rotation);
- AppendByte (a_Data, m_Pitch);
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cPacket_EntityHeadLook:
-
-cPacket_EntityHeadLook::cPacket_EntityHeadLook(const cEntity & a_Entity)
-{
- m_PacketID = E_ENT_HEAD_LOOK;
-
- m_UniqueID = a_Entity.GetUniqueID();
- m_HeadYaw = (char)((a_Entity.GetRotation() / 360.f) * 256);
-}
-
-
-
-
-
-void cPacket_EntityHeadLook::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_UniqueID);
- AppendByte (a_Data, m_HeadYaw);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_EntityLook.h" + +#include "../cEntity.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_EntityLook: + +cPacket_EntityLook::cPacket_EntityLook(const cEntity & a_Entity) +{ + m_PacketID = E_ENT_LOOK; + + m_UniqueID = a_Entity.GetUniqueID(); + m_Rotation = (char)((a_Entity.GetRotation() / 360.f) * 256); + m_Pitch = (char)((a_Entity.GetPitch() / 360.f) * 256); +} + + + + + +void cPacket_EntityLook::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendByte (a_Data, m_Rotation); + AppendByte (a_Data, m_Pitch); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_EntityHeadLook: + +cPacket_EntityHeadLook::cPacket_EntityHeadLook(const cEntity & a_Entity) +{ + m_PacketID = E_ENT_HEAD_LOOK; + + m_UniqueID = a_Entity.GetUniqueID(); + m_HeadYaw = (char)((a_Entity.GetRotation() / 360.f) * 256); +} + + + + + +void cPacket_EntityHeadLook::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendByte (a_Data, m_HeadYaw); +} + + + + diff --git a/source/packets/cPacket_EntityLook.h b/source/packets/cPacket_EntityLook.h index e4aac18e3..7f2864d46 100644 --- a/source/packets/cPacket_EntityLook.h +++ b/source/packets/cPacket_EntityLook.h @@ -1,59 +1,59 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cEntity;
-
-
-
-
-
-class cPacket_EntityLook :
- public cPacket
-{
-public:
- cPacket_EntityLook(void)
- : m_UniqueID( 0 )
- , m_Rotation( 0 )
- , m_Pitch( 0 )
- { m_PacketID = E_ENT_LOOK; }
- cPacket_EntityLook(const cEntity & a_Entity);
- virtual cPacket* Clone(void) const { return new cPacket_EntityLook(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- int m_UniqueID;
- char m_Rotation;
- char m_Pitch;
-};
-
-
-
-
-
-class cPacket_EntityHeadLook :
- public cPacket
-{
-public:
- cPacket_EntityHeadLook(void)
- : m_UniqueID( 0 )
- , m_HeadYaw( 0 )
- { m_PacketID = E_ENT_LOOK; }
- cPacket_EntityHeadLook(const cEntity & a_Entity);
-
- virtual cPacket * Clone(void) const { return new cPacket_EntityHeadLook(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- int m_UniqueID;
- char m_HeadYaw;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cEntity; + + + + + +class cPacket_EntityLook : + public cPacket +{ +public: + cPacket_EntityLook(void) + : m_UniqueID( 0 ) + , m_Rotation( 0 ) + , m_Pitch( 0 ) + { m_PacketID = E_ENT_LOOK; } + cPacket_EntityLook(const cEntity & a_Entity); + virtual cPacket* Clone(void) const { return new cPacket_EntityLook(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + char m_Rotation; + char m_Pitch; +}; + + + + + +class cPacket_EntityHeadLook : + public cPacket +{ +public: + cPacket_EntityHeadLook(void) + : m_UniqueID( 0 ) + , m_HeadYaw( 0 ) + { m_PacketID = E_ENT_LOOK; } + cPacket_EntityHeadLook(const cEntity & a_Entity); + + virtual cPacket * Clone(void) const { return new cPacket_EntityHeadLook(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + char m_HeadYaw; +}; + + + + diff --git a/source/packets/cPacket_EntityStatus.cpp b/source/packets/cPacket_EntityStatus.cpp index 0fc6195b3..1ea468a51 100644 --- a/source/packets/cPacket_EntityStatus.cpp +++ b/source/packets/cPacket_EntityStatus.cpp @@ -1,19 +1,19 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_EntityStatus.h"
-
-
-
-
-
-void cPacket_EntityStatus::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_UniqueID);
- AppendByte (a_Data, m_Status);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_EntityStatus.h" + + + + + +void cPacket_EntityStatus::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendByte (a_Data, m_Status); +} + + + + diff --git a/source/packets/cPacket_EntityStatus.h b/source/packets/cPacket_EntityStatus.h index a50a25390..ecacd03c5 100644 --- a/source/packets/cPacket_EntityStatus.h +++ b/source/packets/cPacket_EntityStatus.h @@ -1,31 +1,31 @@ -#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_EntityStatus : public cPacket
-{
-public:
- cPacket_EntityStatus()
- : m_UniqueID( 0 )
- , m_Status( 0 )
- { m_PacketID = E_ENT_STATUS; }
- virtual cPacket* Clone() const { return new cPacket_EntityStatus( *this ); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- static const char STATUS_TAKEDAMAGE = 2;
- static const char STATUS_DIE = 3;
-
- int m_UniqueID;
- char m_Status;
-
- static const unsigned int c_Size = 1 + 4 + 1;
-};
-
-
-
-
+#pragma once + +#include "cPacket.h" + + + + + +class cPacket_EntityStatus : public cPacket +{ +public: + cPacket_EntityStatus() + : m_UniqueID( 0 ) + , m_Status( 0 ) + { m_PacketID = E_ENT_STATUS; } + virtual cPacket* Clone() const { return new cPacket_EntityStatus( *this ); } + + virtual void Serialize(AString & a_Data) const override; + + static const char STATUS_TAKEDAMAGE = 2; + static const char STATUS_DIE = 3; + + int m_UniqueID; + char m_Status; + + static const unsigned int c_Size = 1 + 4 + 1; +}; + + + + diff --git a/source/packets/cPacket_Flying.cpp b/source/packets/cPacket_Flying.cpp index c7916957a..64fbf11ea 100644 --- a/source/packets/cPacket_Flying.cpp +++ b/source/packets/cPacket_Flying.cpp @@ -1,19 +1,19 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_Flying.h"
-
-
-
-
-
-int cPacket_Flying::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes= 0;
- HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_Flying.h" + + + + + +int cPacket_Flying::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes= 0; + HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_Flying.h b/source/packets/cPacket_Flying.h index 19b0ee213..2d19820de 100644 --- a/source/packets/cPacket_Flying.h +++ b/source/packets/cPacket_Flying.h @@ -1,27 +1,27 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_Flying : public cPacket
-{
-public:
- // The BS packet
- cPacket_Flying()
- : m_bFlying( false )
- { m_PacketID = E_FLYING; }
- virtual cPacket* Clone() const { return new cPacket_Flying(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
-
- bool m_bFlying;
- static const unsigned int c_Size = 2;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_Flying : public cPacket +{ +public: + // The BS packet + cPacket_Flying() + : m_bFlying( false ) + { m_PacketID = E_FLYING; } + virtual cPacket* Clone() const { return new cPacket_Flying(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + + bool m_bFlying; + static const unsigned int c_Size = 2; +}; + + + + diff --git a/source/packets/cPacket_Handshake.cpp b/source/packets/cPacket_Handshake.cpp index 2c4f058e7..737eca330 100644 --- a/source/packets/cPacket_Handshake.cpp +++ b/source/packets/cPacket_Handshake.cpp @@ -1,29 +1,29 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_Handshake.h"
-
-
-
-
-
-int cPacket_Handshake::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadString16, m_Username, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_Handshake::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendString16(a_Data, m_Username);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_Handshake.h" + + + + + +int cPacket_Handshake::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadString16, m_Username, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_Handshake::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendString16(a_Data, m_Username); +} + + + + diff --git a/source/packets/cPacket_Handshake.h b/source/packets/cPacket_Handshake.h index e66827851..020be9eaf 100644 --- a/source/packets/cPacket_Handshake.h +++ b/source/packets/cPacket_Handshake.h @@ -1,25 +1,25 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_Handshake : public cPacket
-{
-public:
- cPacket_Handshake() { m_PacketID = E_HANDSHAKE; }
- virtual cPacket* Clone() const { return new cPacket_Handshake(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- std::string m_Username;
- static const unsigned int c_Size = 3; // Minimal size
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_Handshake : public cPacket +{ +public: + cPacket_Handshake() { m_PacketID = E_HANDSHAKE; } + virtual cPacket* Clone() const { return new cPacket_Handshake(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + std::string m_Username; + static const unsigned int c_Size = 3; // Minimal size +}; + + + + diff --git a/source/packets/cPacket_InventoryProgressBar.cpp b/source/packets/cPacket_InventoryProgressBar.cpp index 9df92b390..61541c8e9 100644 --- a/source/packets/cPacket_InventoryProgressBar.cpp +++ b/source/packets/cPacket_InventoryProgressBar.cpp @@ -1,20 +1,20 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_InventoryProgressBar.h"
-
-
-
-
-
-void cPacket_InventoryProgressBar::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendByte (a_Data, m_WindowID);
- AppendShort(a_Data, m_ProgressBar);
- AppendShort(a_Data, m_Value);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_InventoryProgressBar.h" + + + + + +void cPacket_InventoryProgressBar::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendByte (a_Data, m_WindowID); + AppendShort(a_Data, m_ProgressBar); + AppendShort(a_Data, m_Value); +} + + + + diff --git a/source/packets/cPacket_InventoryProgressBar.h b/source/packets/cPacket_InventoryProgressBar.h index 70bafcf9e..0aa2fd3a8 100644 --- a/source/packets/cPacket_InventoryProgressBar.h +++ b/source/packets/cPacket_InventoryProgressBar.h @@ -1,31 +1,31 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_InventoryProgressBar : public cPacket
-{
-public:
- cPacket_InventoryProgressBar()
- : m_WindowID( 0 )
- , m_ProgressBar( 0 )
- , m_Value( 0 )
- { m_PacketID = E_INVENTORY_PROGRESS; }
- virtual cPacket* Clone() const { return new cPacket_InventoryProgressBar(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- char m_WindowID;
- short m_ProgressBar;
- short m_Value;
-
- static const unsigned int c_Size = 1 + 1 + 2 + 2;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_InventoryProgressBar : public cPacket +{ +public: + cPacket_InventoryProgressBar() + : m_WindowID( 0 ) + , m_ProgressBar( 0 ) + , m_Value( 0 ) + { m_PacketID = E_INVENTORY_PROGRESS; } + virtual cPacket* Clone() const { return new cPacket_InventoryProgressBar(*this); } + + virtual void Serialize(AString & a_Data) const override; + + char m_WindowID; + short m_ProgressBar; + short m_Value; + + static const unsigned int c_Size = 1 + 1 + 2 + 2; +}; + + + + diff --git a/source/packets/cPacket_InventorySlot.cpp b/source/packets/cPacket_InventorySlot.cpp index 46f3bf3d4..5bf247541 100644 --- a/source/packets/cPacket_InventorySlot.cpp +++ b/source/packets/cPacket_InventorySlot.cpp @@ -1,23 +1,23 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_InventorySlot.h"
-#include "cPacket_WholeInventory.h"
-#include "cPacket_ItemData.h"
-
-
-
-
-
-void cPacket_InventorySlot::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendByte (a_Data, m_WindowID);
- AppendShort(a_Data, m_SlotNum);
-
- cPacket_ItemData::AppendItem(a_Data, m_ItemID, m_ItemCount, m_ItemUses);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_InventorySlot.h" +#include "cPacket_WholeInventory.h" +#include "cPacket_ItemData.h" + + + + + +void cPacket_InventorySlot::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendByte (a_Data, m_WindowID); + AppendShort(a_Data, m_SlotNum); + + cPacket_ItemData::AppendItem(a_Data, m_ItemID, m_ItemCount, m_ItemUses); +} + + + + diff --git a/source/packets/cPacket_InventorySlot.h b/source/packets/cPacket_InventorySlot.h index cc04a0bb0..3f9fdc13f 100644 --- a/source/packets/cPacket_InventorySlot.h +++ b/source/packets/cPacket_InventorySlot.h @@ -1,44 +1,44 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-#include "../BlockID.h"
-
-
-
-
-
-class cPacket_InventorySlot : public cPacket // Set item [S -> C] ?
-{
-public:
- cPacket_InventorySlot()
- : m_WindowID( 0 )
- , m_SlotNum( 0 )
- , m_ItemID( E_ITEM_EMPTY )
- , m_ItemCount( 0 )
- , m_ItemUses( 0 )
- { m_PacketID = E_INVENTORY_SLOT; }
- virtual cPacket* Clone() const { return new cPacket_InventorySlot(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- char m_WindowID;
- short m_SlotNum; // Slot
- // 0 = craft result
- // 1-4 = crafting table
- // 5-8 = armor
- // 9-35 = inventory
- // 36-44 = Hot bar
-
- // Below = item
- short m_ItemID; // if this is -1 the next stuff dont exist
- char m_ItemCount;
- short m_ItemUses;
-
- static const unsigned int c_Size = 1 + 1 + 2; // Minimal size ( +1+1 = max)
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + +#include "../BlockID.h" + + + + + +class cPacket_InventorySlot : public cPacket // Set item [S -> C] ? +{ +public: + cPacket_InventorySlot() + : m_WindowID( 0 ) + , m_SlotNum( 0 ) + , m_ItemID( E_ITEM_EMPTY ) + , m_ItemCount( 0 ) + , m_ItemUses( 0 ) + { m_PacketID = E_INVENTORY_SLOT; } + virtual cPacket* Clone() const { return new cPacket_InventorySlot(*this); } + + virtual void Serialize(AString & a_Data) const override; + + char m_WindowID; + short m_SlotNum; // Slot + // 0 = craft result + // 1-4 = crafting table + // 5-8 = armor + // 9-35 = inventory + // 36-44 = Hot bar + + // Below = item + short m_ItemID; // if this is -1 the next stuff dont exist + char m_ItemCount; + short m_ItemUses; + + static const unsigned int c_Size = 1 + 1 + 2; // Minimal size ( +1+1 = max) +}; + + + + diff --git a/source/packets/cPacket_ItemData.cpp b/source/packets/cPacket_ItemData.cpp index db025a838..0892f433a 100644 --- a/source/packets/cPacket_ItemData.cpp +++ b/source/packets/cPacket_ItemData.cpp @@ -1,81 +1,81 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_ItemData.h"
-
-
-
-
-
-int cPacket_ItemData::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadShort, m_ItemID, TotalBytes);
-
- if (m_ItemID <= -1)
- {
- m_ItemCount = 0;
- m_ItemUses = 0;
- return TotalBytes;
- }
-
- HANDLE_PACKET_READ(ReadByte , m_ItemCount, TotalBytes);
- HANDLE_PACKET_READ(ReadShort, m_ItemUses, TotalBytes);
-
- if (cItem::IsEnchantable((ENUM_ITEM_ID) m_ItemID))
- {
- HANDLE_PACKET_READ(ReadShort, m_EnchantNums, TotalBytes);
-
- if ( m_EnchantNums > -1 )
- {
- // TODO: Enchantment not implemented yet!
- }
- }
- return TotalBytes;
-}
-
-
-
-
-
-int cPacket_ItemData::GetSize(short a_ItemID)
-{
- if(a_ItemID <= -1)
- return 2;
- if(cItem::IsEnchantable((ENUM_ITEM_ID) a_ItemID))
- return 7;
- return 5;
-}
-
-
-
-
-
-void cPacket_ItemData::AppendItem(AString & a_Data, const cItem * a_Item)
-{
- return AppendItem(a_Data, a_Item->m_ItemID, a_Item->m_ItemCount, a_Item->m_ItemHealth);
-}
-
-
-
-
-
-void cPacket_ItemData::AppendItem(AString & a_Data, short a_ItemID, char a_Quantity, short a_Damage)
-{
- AppendShort(a_Data, (short) a_ItemID);
- if (a_ItemID > -1)
- {
- AppendByte (a_Data, a_Quantity);
- AppendShort(a_Data, a_Damage);
-
- if (cItem::IsEnchantable((ENUM_ITEM_ID) a_ItemID))
- {
- // TODO: Implement enchantments
- AppendShort(a_Data, (short) -1);
- }
- }
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_ItemData.h" + + + + + +int cPacket_ItemData::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadShort, m_ItemID, TotalBytes); + + if (m_ItemID <= -1) + { + m_ItemCount = 0; + m_ItemUses = 0; + return TotalBytes; + } + + HANDLE_PACKET_READ(ReadByte , m_ItemCount, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_ItemUses, TotalBytes); + + if (cItem::IsEnchantable((ENUM_ITEM_ID) m_ItemID)) + { + HANDLE_PACKET_READ(ReadShort, m_EnchantNums, TotalBytes); + + if ( m_EnchantNums > -1 ) + { + // TODO: Enchantment not implemented yet! + } + } + return TotalBytes; +} + + + + + +int cPacket_ItemData::GetSize(short a_ItemID) +{ + if(a_ItemID <= -1) + return 2; + if(cItem::IsEnchantable((ENUM_ITEM_ID) a_ItemID)) + return 7; + return 5; +} + + + + + +void cPacket_ItemData::AppendItem(AString & a_Data, const cItem * a_Item) +{ + return AppendItem(a_Data, a_Item->m_ItemID, a_Item->m_ItemCount, a_Item->m_ItemHealth); +} + + + + + +void cPacket_ItemData::AppendItem(AString & a_Data, short a_ItemID, char a_Quantity, short a_Damage) +{ + AppendShort(a_Data, (short) a_ItemID); + if (a_ItemID > -1) + { + AppendByte (a_Data, a_Quantity); + AppendShort(a_Data, a_Damage); + + if (cItem::IsEnchantable((ENUM_ITEM_ID) a_ItemID)) + { + // TODO: Implement enchantments + AppendShort(a_Data, (short) -1); + } + } +} + + + + diff --git a/source/packets/cPacket_ItemData.h b/source/packets/cPacket_ItemData.h index 6aa1eed69..47878969f 100644 --- a/source/packets/cPacket_ItemData.h +++ b/source/packets/cPacket_ItemData.h @@ -1,35 +1,35 @@ -#pragma once
-
-
-#include "cPacket.h"
-#include "../cItem.h"
-
-class cPacket_ItemData : public cPacket
-{
-public:
- cPacket_ItemData()
- : m_ItemID( 0 )
- , m_ItemCount( 0 )
- , m_ItemUses( 0 )
- , m_EnchantNums(-1)
- {
- }
-
- virtual cPacket* Clone() const { return new cPacket_ItemData(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
-
- static void AppendItem(AString & a_Data, short a_ItemID, char a_Quantity, short a_Damage);
- static void AppendItem(AString & a_Data, const cItem * a_Item);
-
- int GetSize(short a_ItemID);
-
- // Below = item
- short m_ItemID; // if this is -1 the next stuff dont exist
- char m_ItemCount;
- short m_ItemUses;
-
- short m_EnchantNums;
-
- static unsigned int c_Size; // Minimal size ( +1+1 = max)
+#pragma once + + +#include "cPacket.h" +#include "../cItem.h" + +class cPacket_ItemData : public cPacket +{ +public: + cPacket_ItemData() + : m_ItemID( 0 ) + , m_ItemCount( 0 ) + , m_ItemUses( 0 ) + , m_EnchantNums(-1) + { + } + + virtual cPacket* Clone() const { return new cPacket_ItemData(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + + static void AppendItem(AString & a_Data, short a_ItemID, char a_Quantity, short a_Damage); + static void AppendItem(AString & a_Data, const cItem * a_Item); + + int GetSize(short a_ItemID); + + // Below = item + short m_ItemID; // if this is -1 the next stuff dont exist + char m_ItemCount; + short m_ItemUses; + + short m_EnchantNums; + + static unsigned int c_Size; // Minimal size ( +1+1 = max) };
\ No newline at end of file diff --git a/source/packets/cPacket_ItemSwitch.cpp b/source/packets/cPacket_ItemSwitch.cpp index 630c2ada4..bd4532938 100644 --- a/source/packets/cPacket_ItemSwitch.cpp +++ b/source/packets/cPacket_ItemSwitch.cpp @@ -1,29 +1,29 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_ItemSwitch.h"
-
-
-
-
-
-int cPacket_ItemSwitch::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadShort, m_SlotNum, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_ItemSwitch::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendShort(a_Data, m_SlotNum);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_ItemSwitch.h" + + + + + +int cPacket_ItemSwitch::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadShort, m_SlotNum, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_ItemSwitch::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendShort(a_Data, m_SlotNum); +} + + + + diff --git a/source/packets/cPacket_ItemSwitch.h b/source/packets/cPacket_ItemSwitch.h index 00e37b9c8..fb6860624 100644 --- a/source/packets/cPacket_ItemSwitch.h +++ b/source/packets/cPacket_ItemSwitch.h @@ -1,28 +1,28 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_ItemSwitch : public cPacket
-{
-public:
- cPacket_ItemSwitch()
- : m_SlotNum( 0 )
- { m_PacketID = E_ITEM_SWITCH; }
- virtual cPacket* Clone() const { return new cPacket_ItemSwitch(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- short m_SlotNum;
-
- static const unsigned int c_Size = 1 + 2;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_ItemSwitch : public cPacket +{ +public: + cPacket_ItemSwitch() + : m_SlotNum( 0 ) + { m_PacketID = E_ITEM_SWITCH; } + virtual cPacket* Clone() const { return new cPacket_ItemSwitch(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + short m_SlotNum; + + static const unsigned int c_Size = 1 + 2; +}; + + + + diff --git a/source/packets/cPacket_KeepAlive.cpp b/source/packets/cPacket_KeepAlive.cpp index cf251bf16..cfc6b99b3 100644 --- a/source/packets/cPacket_KeepAlive.cpp +++ b/source/packets/cPacket_KeepAlive.cpp @@ -1,29 +1,29 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_KeepAlive.h"
-
-
-
-
-
-void cPacket_KeepAlive::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_KeepAliveID);
-}
-
-
-
-
-
-int cPacket_KeepAlive::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadInteger, m_KeepAliveID, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_KeepAlive.h" + + + + + +void cPacket_KeepAlive::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_KeepAliveID); +} + + + + + +int cPacket_KeepAlive::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_KeepAliveID, TotalBytes); + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_KeepAlive.h b/source/packets/cPacket_KeepAlive.h index 3611b6e18..e94ec72a6 100644 --- a/source/packets/cPacket_KeepAlive.h +++ b/source/packets/cPacket_KeepAlive.h @@ -1,27 +1,27 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_KeepAlive : public cPacket
-{
-public:
- cPacket_KeepAlive() { m_PacketID = E_KEEP_ALIVE; }
- cPacket_KeepAlive(int a_PingID) { m_KeepAliveID = a_PingID; }
- virtual cPacket* Clone() const { return new cPacket_KeepAlive(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- int m_KeepAliveID;
-
- static const unsigned int c_Size = 1 + 4;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_KeepAlive : public cPacket +{ +public: + cPacket_KeepAlive() { m_PacketID = E_KEEP_ALIVE; } + cPacket_KeepAlive(int a_PingID) { m_KeepAliveID = a_PingID; } + virtual cPacket* Clone() const { return new cPacket_KeepAlive(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + int m_KeepAliveID; + + static const unsigned int c_Size = 1 + 4; +}; + + + + diff --git a/source/packets/cPacket_Login.cpp b/source/packets/cPacket_Login.cpp index 588892b3a..2a8ae7135 100644 --- a/source/packets/cPacket_Login.cpp +++ b/source/packets/cPacket_Login.cpp @@ -1,52 +1,52 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_Login.h"
-
-
-
-
-
-const std::string cPacket_Login::LEVEL_TYPE_DEFAULT = "DEFAULT";
-const std::string cPacket_Login::LEVEL_TYPE_SUPERFLAT = "SUPERFLAT";
-
-
-
-
-
-int cPacket_Login::Parse(const char * a_Data, int a_Size)
-{
- //printf("Parse: NEW Login\n");
- int TotalBytes = 0;
- m_Username.clear();
- HANDLE_PACKET_READ(ReadInteger, m_ProtocolVersion, TotalBytes);
- HANDLE_PACKET_READ(ReadString16, m_Username, TotalBytes);
- HANDLE_PACKET_READ(ReadString16, m_LevelType, TotalBytes);
- HANDLE_PACKET_READ(ReadInteger, m_ServerMode, TotalBytes);
- HANDLE_PACKET_READ(ReadInteger, m_Dimension, TotalBytes);
- HANDLE_PACKET_READ(ReadByte, m_Difficulty, TotalBytes);
- HANDLE_PACKET_READ(ReadByte, m_WorldHeight, TotalBytes);
- HANDLE_PACKET_READ(ReadByte, m_MaxPlayers, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_Login::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger (a_Data, m_ProtocolVersion);
- AppendString16(a_Data, m_Username);
- AppendString16(a_Data, m_LevelType);
- AppendInteger (a_Data, m_ServerMode);
- AppendInteger (a_Data, m_Dimension);
- AppendByte (a_Data, m_Difficulty);
- AppendByte (a_Data, m_WorldHeight);
- AppendByte (a_Data, m_MaxPlayers);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_Login.h" + + + + + +const std::string cPacket_Login::LEVEL_TYPE_DEFAULT = "DEFAULT"; +const std::string cPacket_Login::LEVEL_TYPE_SUPERFLAT = "SUPERFLAT"; + + + + + +int cPacket_Login::Parse(const char * a_Data, int a_Size) +{ + //printf("Parse: NEW Login\n"); + int TotalBytes = 0; + m_Username.clear(); + HANDLE_PACKET_READ(ReadInteger, m_ProtocolVersion, TotalBytes); + HANDLE_PACKET_READ(ReadString16, m_Username, TotalBytes); + HANDLE_PACKET_READ(ReadString16, m_LevelType, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_ServerMode, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_Dimension, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Difficulty, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_WorldHeight, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_MaxPlayers, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_Login::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger (a_Data, m_ProtocolVersion); + AppendString16(a_Data, m_Username); + AppendString16(a_Data, m_LevelType); + AppendInteger (a_Data, m_ServerMode); + AppendInteger (a_Data, m_Dimension); + AppendByte (a_Data, m_Difficulty); + AppendByte (a_Data, m_WorldHeight); + AppendByte (a_Data, m_MaxPlayers); +} + + + + diff --git a/source/packets/cPacket_Login.h b/source/packets/cPacket_Login.h index 86666090c..b9769fdec 100644 --- a/source/packets/cPacket_Login.h +++ b/source/packets/cPacket_Login.h @@ -1,42 +1,42 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_Login : public cPacket //tolua_export
-{ //tolua_export
-public:
- cPacket_Login()
- : m_ProtocolVersion( 0 )
- , m_ServerMode( 0 )
- , m_Dimension( 0 )
- , m_Difficulty( 0 )
- , m_WorldHeight( 0 )
- , m_MaxPlayers( 0 )
- , m_LevelType( LEVEL_TYPE_DEFAULT )
- { m_PacketID = E_LOGIN; }
- virtual cPacket* Clone() const { return new cPacket_Login(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- int m_ProtocolVersion; //tolua_export
- AString m_Username; //tolua_export
- AString m_LevelType; //tolua_export
- int m_ServerMode; //tolua_export
- int m_Dimension;
- char m_Difficulty; //tolua_export
- unsigned char m_WorldHeight; //tolua_export
- unsigned char m_MaxPlayers; //tolua_export
-
- static const AString LEVEL_TYPE_DEFAULT;
- static const AString LEVEL_TYPE_SUPERFLAT;
-}; //tolua_export
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_Login : public cPacket //tolua_export +{ //tolua_export +public: + cPacket_Login() + : m_ProtocolVersion( 0 ) + , m_ServerMode( 0 ) + , m_Dimension( 0 ) + , m_Difficulty( 0 ) + , m_WorldHeight( 0 ) + , m_MaxPlayers( 0 ) + , m_LevelType( LEVEL_TYPE_DEFAULT ) + { m_PacketID = E_LOGIN; } + virtual cPacket* Clone() const { return new cPacket_Login(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + int m_ProtocolVersion; //tolua_export + AString m_Username; //tolua_export + AString m_LevelType; //tolua_export + int m_ServerMode; //tolua_export + int m_Dimension; + char m_Difficulty; //tolua_export + unsigned char m_WorldHeight; //tolua_export + unsigned char m_MaxPlayers; //tolua_export + + static const AString LEVEL_TYPE_DEFAULT; + static const AString LEVEL_TYPE_SUPERFLAT; +}; //tolua_export + + + + diff --git a/source/packets/cPacket_MapChunk.cpp b/source/packets/cPacket_MapChunk.cpp index 279dee808..21c62da45 100644 --- a/source/packets/cPacket_MapChunk.cpp +++ b/source/packets/cPacket_MapChunk.cpp @@ -1,154 +1,154 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_MapChunk.h"
-#include "../ChunkDef.h"
-
-#include "zlib.h"
-
-
-
-
-
-cPacket_MapChunk::~cPacket_MapChunk()
-{
- delete [] m_CompressedData;
-}
-
-
-
-
-
-cPacket_MapChunk::cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const BLOCKTYPE * a_BlockData, const unsigned char * a_BiomeData)
-{
- m_PacketID = E_MAP_CHUNK;
-
- m_PosX = a_ChunkX; // Chunk coordinates now, instead of block coordinates
- m_PosZ = a_ChunkZ;
-
- m_bContiguous = true; // false = no biome data, true = with biome data
- m_BitMap1 = 0;
- m_BitMap2 = 0;
-
- m_UnusedInt = 0;
-
-
- const int BlockDataSize = (cChunkDef::Height / 16) * (4096 + 2048 + 2048 + 2048);
- const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width;
- char AllData [ BlockDataSize + BiomeDataSize ];
-
-#if AXIS_ORDER == AXIS_ORDER_YZX
- memset( AllData, 0, BlockDataSize );
-
- unsigned int iterator = 0;
- for ( int i = 0; i < (cChunkDef::Height / 16); ++i )
- {
- m_BitMap1 |= (1 << i); // This tells what chunks are sent. Use this to NOT send air only chunks (right now everything is sent)
- for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) for( int x = 0; x < 16; ++x )
- {
- int idx = cChunk::MakeIndex(x, y + i * 16, z);
- AllData[iterator] = a_BlockData[idx];
- ++iterator;
- } // for y, z, x
- }
-
- // Send block metadata:
- char * Meta = a_BlockData + cChunkDef::NumBlocks;
- for ( int i = 0; i < (cChunkDef::Height / 16); ++i )
- {
- for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z )
- {
- for ( int x = 0; x < 8; ++x )
- {
- AllData[iterator] = cChunk::GetNibble(Meta, x * 2 + 0, y + i * 16, z) | (cChunk::GetNibble(Meta, x * 2 + 1, y + i * 16, z ) << 4);
- ++iterator;
- } // for x
- } // for y, z
- }
-
- // Send block light:
- char * Light = Meta + cChunkDef::NumBlocks / 2;
- for ( int i = 0; i < (cChunkDef::Height / 16); ++i )
- {
- for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z )
- {
- for ( int x = 0; x < 8; ++x )
- {
- AllData[iterator] = cChunk::GetNibble(Light, x * 2 + 0, y + i * 16, z ) | (cChunk::GetNibble(Light, x * 2 + 1, y + i * 16, z ) << 4);
- ++iterator;
- }
- }
- }
-
- // Send sky light:
- char * SkyLight = Light + cChunkDef::NumBlocks / 2;
- for( int i = 0; i < (cChunkDef::Height/16); ++i )
- {
- for( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z )
- {
- for( int x = 0; x < 8; ++x )
- {
- AllData[iterator] = cChunk::GetNibble(SkyLight, x * 2 + 0, y + i * 16, z ) | (cChunk::GetNibble(SkyLight, x * 2 + 1, y + i * 16, z ) << 4);
- ++iterator;
- }
- }
- }
- memcpy(AllData + BlockDataSize, a_BiomeData, BiomeDataSize);
-#elif AXIS_ORDER == AXIS_ORDER_XZY
- for ( int i = 0; i < 16; ++i )
- {
- m_BitMap1 |= (1 << i);
- }
- memcpy(AllData, a_BlockData, BlockDataSize);
- memcpy(AllData + BlockDataSize, a_BiomeData, BiomeDataSize);
-#endif // AXIS_ORDER
-
- uLongf CompressedSize = compressBound( sizeof(AllData) );
- char * CompressedBlockData = new char[CompressedSize];
-
- compress2( (Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)AllData, sizeof(AllData), Z_DEFAULT_COMPRESSION);
-
- m_CompressedData = CompressedBlockData;
- m_CompressedSize = CompressedSize;
-}
-
-
-
-
-
-cPacket_MapChunk::cPacket_MapChunk( const cPacket_MapChunk & a_Copy )
-{
- m_PacketID = E_MAP_CHUNK;
-
- m_PosX = a_Copy.m_PosX;
- m_PosZ = a_Copy.m_PosZ;
- m_bContiguous = a_Copy.m_bContiguous;
- m_BitMap1 = a_Copy.m_BitMap1;
- m_BitMap2 = a_Copy.m_BitMap2;
-
- m_CompressedSize = a_Copy.m_CompressedSize;
- m_CompressedData = new char[m_CompressedSize];
- memcpy( m_CompressedData, a_Copy.m_CompressedData, m_CompressedSize );
-}
-
-
-
-
-
-void cPacket_MapChunk::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
-
- AppendInteger(a_Data, m_PosX);
- AppendInteger(a_Data, m_PosZ);
- AppendBool (a_Data, m_bContiguous);
- AppendShort (a_Data, m_BitMap1);
- AppendShort (a_Data, m_BitMap2);
- AppendInteger(a_Data, m_CompressedSize);
- AppendInteger(a_Data, m_UnusedInt);
- AppendData (a_Data, m_CompressedData, m_CompressedSize);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_MapChunk.h" +#include "../ChunkDef.h" + +#include "zlib.h" + + + + + +cPacket_MapChunk::~cPacket_MapChunk() +{ + delete [] m_CompressedData; +} + + + + + +cPacket_MapChunk::cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const BLOCKTYPE * a_BlockData, const unsigned char * a_BiomeData) +{ + m_PacketID = E_MAP_CHUNK; + + m_PosX = a_ChunkX; // Chunk coordinates now, instead of block coordinates + m_PosZ = a_ChunkZ; + + m_bContiguous = true; // false = no biome data, true = with biome data + m_BitMap1 = 0; + m_BitMap2 = 0; + + m_UnusedInt = 0; + + + const int BlockDataSize = (cChunkDef::Height / 16) * (4096 + 2048 + 2048 + 2048); + const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width; + char AllData [ BlockDataSize + BiomeDataSize ]; + +#if AXIS_ORDER == AXIS_ORDER_YZX + memset( AllData, 0, BlockDataSize ); + + unsigned int iterator = 0; + for ( int i = 0; i < (cChunkDef::Height / 16); ++i ) + { + m_BitMap1 |= (1 << i); // This tells what chunks are sent. Use this to NOT send air only chunks (right now everything is sent) + for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) for( int x = 0; x < 16; ++x ) + { + int idx = cChunk::MakeIndex(x, y + i * 16, z); + AllData[iterator] = a_BlockData[idx]; + ++iterator; + } // for y, z, x + } + + // Send block metadata: + char * Meta = a_BlockData + cChunkDef::NumBlocks; + for ( int i = 0; i < (cChunkDef::Height / 16); ++i ) + { + for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) + { + for ( int x = 0; x < 8; ++x ) + { + AllData[iterator] = cChunk::GetNibble(Meta, x * 2 + 0, y + i * 16, z) | (cChunk::GetNibble(Meta, x * 2 + 1, y + i * 16, z ) << 4); + ++iterator; + } // for x + } // for y, z + } + + // Send block light: + char * Light = Meta + cChunkDef::NumBlocks / 2; + for ( int i = 0; i < (cChunkDef::Height / 16); ++i ) + { + for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) + { + for ( int x = 0; x < 8; ++x ) + { + AllData[iterator] = cChunk::GetNibble(Light, x * 2 + 0, y + i * 16, z ) | (cChunk::GetNibble(Light, x * 2 + 1, y + i * 16, z ) << 4); + ++iterator; + } + } + } + + // Send sky light: + char * SkyLight = Light + cChunkDef::NumBlocks / 2; + for( int i = 0; i < (cChunkDef::Height/16); ++i ) + { + for( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) + { + for( int x = 0; x < 8; ++x ) + { + AllData[iterator] = cChunk::GetNibble(SkyLight, x * 2 + 0, y + i * 16, z ) | (cChunk::GetNibble(SkyLight, x * 2 + 1, y + i * 16, z ) << 4); + ++iterator; + } + } + } + memcpy(AllData + BlockDataSize, a_BiomeData, BiomeDataSize); +#elif AXIS_ORDER == AXIS_ORDER_XZY + for ( int i = 0; i < 16; ++i ) + { + m_BitMap1 |= (1 << i); + } + memcpy(AllData, a_BlockData, BlockDataSize); + memcpy(AllData + BlockDataSize, a_BiomeData, BiomeDataSize); +#endif // AXIS_ORDER + + uLongf CompressedSize = compressBound( sizeof(AllData) ); + char * CompressedBlockData = new char[CompressedSize]; + + compress2( (Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)AllData, sizeof(AllData), Z_DEFAULT_COMPRESSION); + + m_CompressedData = CompressedBlockData; + m_CompressedSize = CompressedSize; +} + + + + + +cPacket_MapChunk::cPacket_MapChunk( const cPacket_MapChunk & a_Copy ) +{ + m_PacketID = E_MAP_CHUNK; + + m_PosX = a_Copy.m_PosX; + m_PosZ = a_Copy.m_PosZ; + m_bContiguous = a_Copy.m_bContiguous; + m_BitMap1 = a_Copy.m_BitMap1; + m_BitMap2 = a_Copy.m_BitMap2; + + m_CompressedSize = a_Copy.m_CompressedSize; + m_CompressedData = new char[m_CompressedSize]; + memcpy( m_CompressedData, a_Copy.m_CompressedData, m_CompressedSize ); +} + + + + + +void cPacket_MapChunk::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + + AppendInteger(a_Data, m_PosX); + AppendInteger(a_Data, m_PosZ); + AppendBool (a_Data, m_bContiguous); + AppendShort (a_Data, m_BitMap1); + AppendShort (a_Data, m_BitMap2); + AppendInteger(a_Data, m_CompressedSize); + AppendInteger(a_Data, m_UnusedInt); + AppendData (a_Data, m_CompressedData, m_CompressedSize); +} + + + + diff --git a/source/packets/cPacket_MapChunk.h b/source/packets/cPacket_MapChunk.h index 0daf5af34..ec2f68632 100644 --- a/source/packets/cPacket_MapChunk.h +++ b/source/packets/cPacket_MapChunk.h @@ -1,45 +1,45 @@ -
-#pragma once
-
-#include "cPacket.h"
-#include "../ChunkDef.h"
-
-
-
-
-
-class cPacket_MapChunk :
- public cPacket
-{
-public:
- cPacket_MapChunk()
- : m_PosX( 0 )
- , m_PosZ( 0 )
- , m_bContiguous( false )
- , m_BitMap1( 0 )
- , m_BitMap2( 0 )
- , m_CompressedSize( 0 )
- , m_UnusedInt( 0 )
- , m_CompressedData( NULL )
- { m_PacketID = E_MAP_CHUNK; }
-
- cPacket_MapChunk( const cPacket_MapChunk & a_Copy );
- cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const BLOCKTYPE * a_BlockData, const unsigned char * a_BiomeData);
- ~cPacket_MapChunk();
- virtual cPacket* Clone() const { return new cPacket_MapChunk(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- int m_PosX;
- int m_PosZ;
- bool m_bContiguous;
- short m_BitMap1;
- short m_BitMap2;
- int m_CompressedSize;
- int m_UnusedInt;
- char * m_CompressedData;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" +#include "../ChunkDef.h" + + + + + +class cPacket_MapChunk : + public cPacket +{ +public: + cPacket_MapChunk() + : m_PosX( 0 ) + , m_PosZ( 0 ) + , m_bContiguous( false ) + , m_BitMap1( 0 ) + , m_BitMap2( 0 ) + , m_CompressedSize( 0 ) + , m_UnusedInt( 0 ) + , m_CompressedData( NULL ) + { m_PacketID = E_MAP_CHUNK; } + + cPacket_MapChunk( const cPacket_MapChunk & a_Copy ); + cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const BLOCKTYPE * a_BlockData, const unsigned char * a_BiomeData); + ~cPacket_MapChunk(); + virtual cPacket* Clone() const { return new cPacket_MapChunk(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_PosX; + int m_PosZ; + bool m_bContiguous; + short m_BitMap1; + short m_BitMap2; + int m_CompressedSize; + int m_UnusedInt; + char * m_CompressedData; +}; + + + + diff --git a/source/packets/cPacket_MultiBlock.cpp b/source/packets/cPacket_MultiBlock.cpp index cfa13c4d4..9ae175508 100644 --- a/source/packets/cPacket_MultiBlock.cpp +++ b/source/packets/cPacket_MultiBlock.cpp @@ -1,50 +1,50 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_MultiBlock.h"
-
-
-
-
-
-cPacket_MultiBlock::cPacket_MultiBlock( const cPacket_MultiBlock & a_Copy )
-{
- m_PacketID = E_MULTI_BLOCK;
- m_ChunkX = a_Copy.m_ChunkX;
- m_ChunkZ = a_Copy.m_ChunkZ;
- m_NumBlocks = a_Copy.m_NumBlocks;
- m_DataSize = a_Copy.m_DataSize;
- m_Data = new sBlockChange[m_NumBlocks];
- memcpy( m_Data, a_Copy.m_Data, sizeof(sBlockChange)*m_NumBlocks );
-}
-
-
-
-
-
-cPacket_MultiBlock::~cPacket_MultiBlock()
-{
- delete [] m_Data;
-}
-
-
-
-
-
-void cPacket_MultiBlock::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_ChunkX);
- AppendInteger(a_Data, m_ChunkZ);
- AppendShort (a_Data, m_NumBlocks);
-
- AppendInteger(a_Data, m_DataSize);
- for( int i = 0; i < m_NumBlocks; ++i )
- {
- AppendInteger(a_Data, m_Data[i].Data);
- }
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_MultiBlock.h" + + + + + +cPacket_MultiBlock::cPacket_MultiBlock( const cPacket_MultiBlock & a_Copy ) +{ + m_PacketID = E_MULTI_BLOCK; + m_ChunkX = a_Copy.m_ChunkX; + m_ChunkZ = a_Copy.m_ChunkZ; + m_NumBlocks = a_Copy.m_NumBlocks; + m_DataSize = a_Copy.m_DataSize; + m_Data = new sBlockChange[m_NumBlocks]; + memcpy( m_Data, a_Copy.m_Data, sizeof(sBlockChange)*m_NumBlocks ); +} + + + + + +cPacket_MultiBlock::~cPacket_MultiBlock() +{ + delete [] m_Data; +} + + + + + +void cPacket_MultiBlock::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_ChunkX); + AppendInteger(a_Data, m_ChunkZ); + AppendShort (a_Data, m_NumBlocks); + + AppendInteger(a_Data, m_DataSize); + for( int i = 0; i < m_NumBlocks; ++i ) + { + AppendInteger(a_Data, m_Data[i].Data); + } +} + + + + diff --git a/source/packets/cPacket_MultiBlock.h b/source/packets/cPacket_MultiBlock.h index 31cb96628..af3d24267 100644 --- a/source/packets/cPacket_MultiBlock.h +++ b/source/packets/cPacket_MultiBlock.h @@ -1,47 +1,47 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_MultiBlock : public cPacket
-{
-public:
- struct sBlockChange
- {
- sBlockChange()
- : Data( 0 )
- {}
- unsigned int Data;
-// short Data; // 4bits metadata ... 12bits block ID
-// short Coords; // 8bits Y ... 4bits Z ... 4bits X
- };
-
- cPacket_MultiBlock()
- : m_ChunkX( 0 )
- , m_ChunkZ( 0 )
- , m_NumBlocks( 0 )
- , m_DataSize( 0 )
- , m_Data( NULL )
- { m_PacketID = E_MULTI_BLOCK; }
-
- cPacket_MultiBlock( const cPacket_MultiBlock & a_Copy );
- ~cPacket_MultiBlock();
- virtual cPacket* Clone() const { return new cPacket_MultiBlock(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- int m_ChunkX;
- int m_ChunkZ;
- short m_NumBlocks;
-
- int m_DataSize; // Should be 4 * m_NumBlocks ??
- sBlockChange * m_Data;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_MultiBlock : public cPacket +{ +public: + struct sBlockChange + { + sBlockChange() + : Data( 0 ) + {} + unsigned int Data; +// short Data; // 4bits metadata ... 12bits block ID +// short Coords; // 8bits Y ... 4bits Z ... 4bits X + }; + + cPacket_MultiBlock() + : m_ChunkX( 0 ) + , m_ChunkZ( 0 ) + , m_NumBlocks( 0 ) + , m_DataSize( 0 ) + , m_Data( NULL ) + { m_PacketID = E_MULTI_BLOCK; } + + cPacket_MultiBlock( const cPacket_MultiBlock & a_Copy ); + ~cPacket_MultiBlock(); + virtual cPacket* Clone() const { return new cPacket_MultiBlock(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_ChunkX; + int m_ChunkZ; + short m_NumBlocks; + + int m_DataSize; // Should be 4 * m_NumBlocks ?? + sBlockChange * m_Data; +}; + + + + diff --git a/source/packets/cPacket_NamedEntitySpawn.cpp b/source/packets/cPacket_NamedEntitySpawn.cpp index 8b4b912d8..798376372 100644 --- a/source/packets/cPacket_NamedEntitySpawn.cpp +++ b/source/packets/cPacket_NamedEntitySpawn.cpp @@ -1,34 +1,34 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_NamedEntitySpawn.h"
-
-
-
-
-
-void cPacket_NamedEntitySpawn::Serialize(AString & a_Data) const
-{
- short CurrentItem = m_CurrentItem;
- ASSERT(CurrentItem >= 0);
- if (CurrentItem <= 0)
- {
- CurrentItem = 0;
- // Fix, to make sure no invalid values are sent.
- // WARNING: HERE ITS 0, BUT IN EQUIP PACKET ITS -1 !!
- }
-
- AppendByte (a_Data, m_PacketID);
- AppendInteger (a_Data, m_UniqueID);
- AppendString16(a_Data, m_PlayerName);
- AppendInteger (a_Data, m_PosX);
- AppendInteger (a_Data, m_PosY);
- AppendInteger (a_Data, m_PosZ);
- AppendByte (a_Data, m_Rotation);
- AppendByte (a_Data, m_Pitch);
- AppendShort (a_Data, CurrentItem);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_NamedEntitySpawn.h" + + + + + +void cPacket_NamedEntitySpawn::Serialize(AString & a_Data) const +{ + short CurrentItem = m_CurrentItem; + ASSERT(CurrentItem >= 0); + if (CurrentItem <= 0) + { + CurrentItem = 0; + // Fix, to make sure no invalid values are sent. + // WARNING: HERE ITS 0, BUT IN EQUIP PACKET ITS -1 !! + } + + AppendByte (a_Data, m_PacketID); + AppendInteger (a_Data, m_UniqueID); + AppendString16(a_Data, m_PlayerName); + AppendInteger (a_Data, m_PosX); + AppendInteger (a_Data, m_PosY); + AppendInteger (a_Data, m_PosZ); + AppendByte (a_Data, m_Rotation); + AppendByte (a_Data, m_Pitch); + AppendShort (a_Data, CurrentItem); +} + + + + diff --git a/source/packets/cPacket_NamedEntitySpawn.h b/source/packets/cPacket_NamedEntitySpawn.h index ceec10c35..365d28c37 100644 --- a/source/packets/cPacket_NamedEntitySpawn.h +++ b/source/packets/cPacket_NamedEntitySpawn.h @@ -1,40 +1,40 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_NamedEntitySpawn : public cPacket
-{
-public:
- cPacket_NamedEntitySpawn()
- : m_UniqueID( 0 )
- , m_PosX( 0 )
- , m_PosY( 0 )
- , m_PosZ( 0 )
- , m_Rotation( 0 )
- , m_Pitch( 0 )
- , m_CurrentItem( 0 )
- { m_PacketID = E_NAMED_ENTITY_SPAWN; }
- virtual cPacket* Clone() const { return new cPacket_NamedEntitySpawn(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- int m_UniqueID;
- AString m_PlayerName;
- int m_PosX; // Pixel position, devide by 32 for block position
- int m_PosY;
- int m_PosZ;
- char m_Rotation;
- char m_Pitch;
- short m_CurrentItem;
-
- static const unsigned int c_Size = 1 + 4 + 2 + 4 + 4 + 4 + 1 + 1 + 2; // Minimum size
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_NamedEntitySpawn : public cPacket +{ +public: + cPacket_NamedEntitySpawn() + : m_UniqueID( 0 ) + , m_PosX( 0 ) + , m_PosY( 0 ) + , m_PosZ( 0 ) + , m_Rotation( 0 ) + , m_Pitch( 0 ) + , m_CurrentItem( 0 ) + { m_PacketID = E_NAMED_ENTITY_SPAWN; } + virtual cPacket* Clone() const { return new cPacket_NamedEntitySpawn(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + AString m_PlayerName; + int m_PosX; // Pixel position, devide by 32 for block position + int m_PosY; + int m_PosZ; + char m_Rotation; + char m_Pitch; + short m_CurrentItem; + + static const unsigned int c_Size = 1 + 4 + 2 + 4 + 4 + 4 + 1 + 1 + 2; // Minimum size +}; + + + + diff --git a/source/packets/cPacket_PickupSpawn.cpp b/source/packets/cPacket_PickupSpawn.cpp index d8970650d..a1a60947d 100644 --- a/source/packets/cPacket_PickupSpawn.cpp +++ b/source/packets/cPacket_PickupSpawn.cpp @@ -1,47 +1,47 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_PickupSpawn.h"
-
-
-
-
-
-int cPacket_PickupSpawn::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadInteger, m_UniqueID, TotalBytes);
- HANDLE_PACKET_READ(ReadShort, m_Item, TotalBytes);
- HANDLE_PACKET_READ(ReadByte, m_Count, TotalBytes);
- HANDLE_PACKET_READ(ReadShort, m_Health, TotalBytes);
- HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes);
- HANDLE_PACKET_READ(ReadInteger, m_PosY, TotalBytes);
- HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes);
- HANDLE_PACKET_READ(ReadByte, m_Rotation, TotalBytes);
- HANDLE_PACKET_READ(ReadByte, m_Pitch, TotalBytes);
- HANDLE_PACKET_READ(ReadByte, m_Roll, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_PickupSpawn::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_UniqueID);
- AppendShort (a_Data, m_Item);
- AppendByte (a_Data, m_Count);
- AppendShort (a_Data, m_Health);
- AppendInteger(a_Data, m_PosX);
- AppendInteger(a_Data, m_PosY);
- AppendInteger(a_Data, m_PosZ);
- AppendByte (a_Data, m_Rotation);
- AppendByte (a_Data, m_Pitch);
- AppendByte (a_Data, m_Roll);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_PickupSpawn.h" + + + + + +int cPacket_PickupSpawn::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_UniqueID, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_Item, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Count, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_Health, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_PosY, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Rotation, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Pitch, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Roll, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_PickupSpawn::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendShort (a_Data, m_Item); + AppendByte (a_Data, m_Count); + AppendShort (a_Data, m_Health); + AppendInteger(a_Data, m_PosX); + AppendInteger(a_Data, m_PosY); + AppendInteger(a_Data, m_PosZ); + AppendByte (a_Data, m_Rotation); + AppendByte (a_Data, m_Pitch); + AppendByte (a_Data, m_Roll); +} + + + + diff --git a/source/packets/cPacket_PickupSpawn.h b/source/packets/cPacket_PickupSpawn.h index d46999a5a..1c1a6c640 100644 --- a/source/packets/cPacket_PickupSpawn.h +++ b/source/packets/cPacket_PickupSpawn.h @@ -1,46 +1,46 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_PickupSpawn : public cPacket
-{
-public:
- cPacket_PickupSpawn()
- : m_UniqueID( 0 )
- , m_Item( 0 )
- , m_Count( 0 )
- , m_Health( 0 )
- , m_PosX( 0 )
- , m_PosY( 0 )
- , m_PosZ( 0 )
- , m_Rotation( 0 )
- , m_Pitch( 0 )
- , m_Roll( 0 )
- { m_PacketID = E_PICKUP_SPAWN; }
- virtual cPacket* Clone() const { return new cPacket_PickupSpawn(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- int m_UniqueID;
- short m_Item;
- char m_Count;
- short m_Health;
- int m_PosX;
- int m_PosY;
- int m_PosZ;
- char m_Rotation;
- char m_Pitch;
- char m_Roll;
-
- static const unsigned int c_Size = 1 + 4 + 2 + 1 + 2 + 4 + 4 + 4 + 1 + 1 + 1;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_PickupSpawn : public cPacket +{ +public: + cPacket_PickupSpawn() + : m_UniqueID( 0 ) + , m_Item( 0 ) + , m_Count( 0 ) + , m_Health( 0 ) + , m_PosX( 0 ) + , m_PosY( 0 ) + , m_PosZ( 0 ) + , m_Rotation( 0 ) + , m_Pitch( 0 ) + , m_Roll( 0 ) + { m_PacketID = E_PICKUP_SPAWN; } + virtual cPacket* Clone() const { return new cPacket_PickupSpawn(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + short m_Item; + char m_Count; + short m_Health; + int m_PosX; + int m_PosY; + int m_PosZ; + char m_Rotation; + char m_Pitch; + char m_Roll; + + static const unsigned int c_Size = 1 + 4 + 2 + 1 + 2 + 4 + 4 + 4 + 1 + 1 + 1; +}; + + + + diff --git a/source/packets/cPacket_Ping.h b/source/packets/cPacket_Ping.h index 0a0609aeb..0a856c7ec 100644 --- a/source/packets/cPacket_Ping.h +++ b/source/packets/cPacket_Ping.h @@ -1,24 +1,24 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_Ping : public cPacket
-{
-public:
- cPacket_Ping()
- { m_PacketID = E_PING; }
- virtual cPacket* Clone() const { return new cPacket_Ping(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override {return 0; }
-
- static const unsigned int c_Size = 1;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_Ping : public cPacket +{ +public: + cPacket_Ping() + { m_PacketID = E_PING; } + virtual cPacket* Clone() const { return new cPacket_Ping(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override {return 0; } + + static const unsigned int c_Size = 1; +}; + + + + diff --git a/source/packets/cPacket_Player.cpp b/source/packets/cPacket_Player.cpp index 86214d725..7d9a5de6b 100644 --- a/source/packets/cPacket_Player.cpp +++ b/source/packets/cPacket_Player.cpp @@ -1,243 +1,243 @@ -
-// cPacket_Player.cpp
-
-/* Implements the player-related packets:
- - PlayerAbilities (0xca)
- - PlayerListItem (0xc9)
- - PlayerLook (0x0c)
- - PlayerMoveLook (0x0d)
- - PlayerPosition (0x0b)
-*/
-
-#include "Globals.h"
-
-#include "cPacket_Player.h"
-#include "../cPlayer.h"
-#include "../cChatColor.h"
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cPacket_PlayerAbilities:
-
-int cPacket_PlayerAbilities::Parse(const char * a_Data, int a_Size)
-{
- if (a_Size < 4)
- {
- return PACKET_INCOMPLETE;
- }
- m_Invulnerable = (a_Data[0] != 0);
- m_IsFlying = (a_Data[1] != 0);
- m_CanFly = (a_Data[2] != 0);
- m_InstaMine = (a_Data[3] != 0);
- return 4;
-}
-
-
-
-
-
-void cPacket_PlayerAbilities::Serialize(AString & a_Data) const
-{
- char Data[5];
- Data[0] = m_PacketID;
- Data[1] = (char)m_Invulnerable;
- Data[2] = (char)m_IsFlying;
- Data[3] = (char)m_CanFly;
- Data[4] = (char)m_InstaMine;
- a_Data.append(Data, 5);
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cPacket_PlayerListItem:
-
-cPacket_PlayerListItem::cPacket_PlayerListItem(const AString & a_PlayerName, bool a_Online, short a_Ping)
-{
- m_PacketID = E_PLAYER_LIST_ITEM;
- m_PlayerName = a_PlayerName;
- m_Online = a_Online;
- m_Ping = a_Ping;
-}
-
-
-
-
-
-int cPacket_PlayerListItem::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadString16, m_PlayerName, TotalBytes);
- HANDLE_PACKET_READ(ReadBool, m_Online, TotalBytes);
- HANDLE_PACKET_READ(ReadShort, m_Ping, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_PlayerListItem::Serialize(AString & a_Data) const
-{
- AString PlayerName(m_PlayerName);
- if (PlayerName.length() > 16)
- {
- PlayerName.erase(16);
- }
- else if (PlayerName.length() <= 14)
- {
- PlayerName += cChatColor::White;
- }
-
- AppendByte (a_Data, m_PacketID);
- AppendString16(a_Data, PlayerName);
- AppendBool (a_Data, m_Online);
- AppendShort (a_Data, m_Ping);
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cPacket_PlayerLook:
-
-cPacket_PlayerLook::cPacket_PlayerLook( cPlayer* a_Player )
-{
- m_PacketID = E_PLAYERLOOK;
- m_Rotation = a_Player->GetRotation();
- m_Pitch = a_Player->GetPitch();
- m_bFlying = a_Player->GetFlying();
-}
-
-
-
-
-
-int cPacket_PlayerLook::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadFloat, m_Rotation, TotalBytes);
- HANDLE_PACKET_READ(ReadFloat, m_Pitch, TotalBytes);
- HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_PlayerLook::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendFloat (a_Data, m_Rotation);
- AppendFloat (a_Data, m_Pitch);
- AppendBool (a_Data, m_bFlying);
-}
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cPacket_PlayerMoveLook:
-
-cPacket_PlayerMoveLook::cPacket_PlayerMoveLook( cPlayer* a_Player )
-{
- m_PacketID = E_PLAYERMOVELOOK;
- m_PosX = a_Player->GetPosX();
- m_PosY = a_Player->GetPosY() + 1.65;
- m_PosZ = a_Player->GetPosZ();
- m_Stance = a_Player->GetStance();
- m_Rotation = a_Player->GetRotation();
- m_Pitch = a_Player->GetPitch();
- m_bFlying = a_Player->GetFlying();
-}
-
-
-
-
-
-int cPacket_PlayerMoveLook::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadDouble, m_PosX, TotalBytes);
- HANDLE_PACKET_READ(ReadDouble, m_PosY, TotalBytes);
- HANDLE_PACKET_READ(ReadDouble, m_Stance, TotalBytes);
- HANDLE_PACKET_READ(ReadDouble, m_PosZ, TotalBytes);
- HANDLE_PACKET_READ(ReadFloat, m_Rotation, TotalBytes);
- HANDLE_PACKET_READ(ReadFloat, m_Pitch, TotalBytes);
- HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_PlayerMoveLook::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendDouble(a_Data, m_PosX);
- AppendDouble(a_Data, m_PosY);
- AppendDouble(a_Data, m_Stance);
- AppendDouble(a_Data, m_PosZ);
- AppendFloat (a_Data, m_Rotation);
- AppendFloat (a_Data, m_Pitch);
- AppendBool (a_Data, m_bFlying);
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cPacket_PlayerPosition:
-
-cPacket_PlayerPosition::cPacket_PlayerPosition( cPlayer* a_Player )
-{
- m_PacketID = E_PLAYERPOS;
-
- m_PosX = a_Player->GetPosX();
- m_PosY = a_Player->GetPosY() + 1.65;
- m_PosZ = a_Player->GetPosZ();
- m_Stance = a_Player->GetStance();
- m_bFlying = a_Player->GetFlying();
-}
-
-
-
-
-
-int cPacket_PlayerPosition::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadDouble, m_PosX, TotalBytes);
- HANDLE_PACKET_READ(ReadDouble, m_PosY, TotalBytes);
- HANDLE_PACKET_READ(ReadDouble, m_Stance, TotalBytes);
- HANDLE_PACKET_READ(ReadDouble, m_PosZ, TotalBytes);
- HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_PlayerPosition::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendDouble (a_Data, m_PosX);
- AppendDouble (a_Data, m_PosY);
- AppendDouble (a_Data, m_Stance);
- AppendDouble (a_Data, m_PosZ);
- AppendBool (a_Data, m_bFlying);
-}
-
-
-
-
+ +// cPacket_Player.cpp + +/* Implements the player-related packets: + - PlayerAbilities (0xca) + - PlayerListItem (0xc9) + - PlayerLook (0x0c) + - PlayerMoveLook (0x0d) + - PlayerPosition (0x0b) +*/ + +#include "Globals.h" + +#include "cPacket_Player.h" +#include "../cPlayer.h" +#include "../cChatColor.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerAbilities: + +int cPacket_PlayerAbilities::Parse(const char * a_Data, int a_Size) +{ + if (a_Size < 4) + { + return PACKET_INCOMPLETE; + } + m_Invulnerable = (a_Data[0] != 0); + m_IsFlying = (a_Data[1] != 0); + m_CanFly = (a_Data[2] != 0); + m_InstaMine = (a_Data[3] != 0); + return 4; +} + + + + + +void cPacket_PlayerAbilities::Serialize(AString & a_Data) const +{ + char Data[5]; + Data[0] = m_PacketID; + Data[1] = (char)m_Invulnerable; + Data[2] = (char)m_IsFlying; + Data[3] = (char)m_CanFly; + Data[4] = (char)m_InstaMine; + a_Data.append(Data, 5); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerListItem: + +cPacket_PlayerListItem::cPacket_PlayerListItem(const AString & a_PlayerName, bool a_Online, short a_Ping) +{ + m_PacketID = E_PLAYER_LIST_ITEM; + m_PlayerName = a_PlayerName; + m_Online = a_Online; + m_Ping = a_Ping; +} + + + + + +int cPacket_PlayerListItem::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadString16, m_PlayerName, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_Online, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_Ping, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_PlayerListItem::Serialize(AString & a_Data) const +{ + AString PlayerName(m_PlayerName); + if (PlayerName.length() > 16) + { + PlayerName.erase(16); + } + else if (PlayerName.length() <= 14) + { + PlayerName += cChatColor::White; + } + + AppendByte (a_Data, m_PacketID); + AppendString16(a_Data, PlayerName); + AppendBool (a_Data, m_Online); + AppendShort (a_Data, m_Ping); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerLook: + +cPacket_PlayerLook::cPacket_PlayerLook( cPlayer* a_Player ) +{ + m_PacketID = E_PLAYERLOOK; + m_Rotation = a_Player->GetRotation(); + m_Pitch = a_Player->GetPitch(); + m_bFlying = a_Player->GetFlying(); +} + + + + + +int cPacket_PlayerLook::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadFloat, m_Rotation, TotalBytes); + HANDLE_PACKET_READ(ReadFloat, m_Pitch, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_PlayerLook::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendFloat (a_Data, m_Rotation); + AppendFloat (a_Data, m_Pitch); + AppendBool (a_Data, m_bFlying); +} + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerMoveLook: + +cPacket_PlayerMoveLook::cPacket_PlayerMoveLook( cPlayer* a_Player ) +{ + m_PacketID = E_PLAYERMOVELOOK; + m_PosX = a_Player->GetPosX(); + m_PosY = a_Player->GetPosY() + 1.65; + m_PosZ = a_Player->GetPosZ(); + m_Stance = a_Player->GetStance(); + m_Rotation = a_Player->GetRotation(); + m_Pitch = a_Player->GetPitch(); + m_bFlying = a_Player->GetFlying(); +} + + + + + +int cPacket_PlayerMoveLook::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadDouble, m_PosX, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_PosY, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_Stance, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadFloat, m_Rotation, TotalBytes); + HANDLE_PACKET_READ(ReadFloat, m_Pitch, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_PlayerMoveLook::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendDouble(a_Data, m_PosX); + AppendDouble(a_Data, m_PosY); + AppendDouble(a_Data, m_Stance); + AppendDouble(a_Data, m_PosZ); + AppendFloat (a_Data, m_Rotation); + AppendFloat (a_Data, m_Pitch); + AppendBool (a_Data, m_bFlying); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerPosition: + +cPacket_PlayerPosition::cPacket_PlayerPosition( cPlayer* a_Player ) +{ + m_PacketID = E_PLAYERPOS; + + m_PosX = a_Player->GetPosX(); + m_PosY = a_Player->GetPosY() + 1.65; + m_PosZ = a_Player->GetPosZ(); + m_Stance = a_Player->GetStance(); + m_bFlying = a_Player->GetFlying(); +} + + + + + +int cPacket_PlayerPosition::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadDouble, m_PosX, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_PosY, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_Stance, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_PlayerPosition::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendDouble (a_Data, m_PosX); + AppendDouble (a_Data, m_PosY); + AppendDouble (a_Data, m_Stance); + AppendDouble (a_Data, m_PosZ); + AppendBool (a_Data, m_bFlying); +} + + + + diff --git a/source/packets/cPacket_Player.h b/source/packets/cPacket_Player.h index ce88cc451..5b17feabf 100644 --- a/source/packets/cPacket_Player.h +++ b/source/packets/cPacket_Player.h @@ -1,150 +1,150 @@ -
-// cPacket_Player.h
-
-/* Interfaces to the player-related packets:
- - PlayerAbilities (0xca)
- - PlayerListItem (0xc9)
- - PlayerLook (0x0c)
- - PlayerMoveLook (0x0d)
- - PlayerPosition (0x0b)
-*/
-
-#pragma once
-
-
-
-
-
-#include "cPacket.h"
-
-
-
-
-
-// fwd:
-class cPlayer;
-
-
-
-
-
-class cPacket_PlayerAbilities : public cPacket
-{
-public:
- cPacket_PlayerAbilities(void) { m_PacketID = E_PLAYER_LIST_ITEM; }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- virtual cPacket * Clone() const { return new cPacket_PlayerAbilities(*this); }
-
- bool m_Invulnerable; // Speculation
- bool m_IsFlying;
- bool m_CanFly;
- bool m_InstaMine; // Speculation
-} ;
-
-
-
-
-
-class cPacket_PlayerListItem : public cPacket
-{
-public:
- cPacket_PlayerListItem() { m_PacketID = E_PLAYER_LIST_ITEM; }
- cPacket_PlayerListItem(const AString & a_PlayerName, bool a_Online, short a_Ping);
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- virtual cPacket* Clone() const { return new cPacket_PlayerListItem(*this); }
-
- AString m_PlayerName; // Supports chat coloring, limited to 16 characters.
- bool m_Online;
- short m_Ping;
-} ;
-
-
-
-
-
-class cPacket_PlayerLook : public cPacket
-{
-public:
- cPacket_PlayerLook()
- : m_Rotation( 0 )
- , m_Pitch( 0 )
- , m_bFlying( false )
- { m_PacketID = E_PLAYERLOOK; }
- cPacket_PlayerLook( cPlayer* a_Player );
- virtual cPacket* Clone() const { return new cPacket_PlayerLook(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- float m_Rotation;
- float m_Pitch;
- bool m_bFlying; // Yeah.. wtf
-} ;
-
-
-
-
-
-class cPacket_PlayerMoveLook : public cPacket
-{
-public:
- cPacket_PlayerMoveLook()
- : m_PosX( 0.0 )
- , m_PosY( 0.0 )
- , m_Stance( 0.0 )
- , m_PosZ( 0.0 )
- , m_Rotation( 0.f )
- , m_Pitch( 0.f )
- , m_bFlying( false )
- { m_PacketID = E_PLAYERMOVELOOK; }
- cPacket_PlayerMoveLook( cPlayer* a_Player );
- virtual cPacket* Clone() const { return new cPacket_PlayerMoveLook(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- double m_PosX;
- double m_PosY;
- double m_Stance;
- double m_PosZ;
- float m_Rotation;
- float m_Pitch;
- bool m_bFlying; // Yeah.. wtf
-} ;
-
-
-
-
-
-class cPacket_PlayerPosition : public cPacket
-{
-public:
- cPacket_PlayerPosition( cPlayer* a_Player );
- cPacket_PlayerPosition()
- : m_PosX( 0.0 )
- , m_PosY( 0.0 )
- , m_Stance( 0.0 )
- , m_PosZ( 0.0 )
- , m_bFlying( false )
- { m_PacketID = E_PLAYERPOS; }
- virtual cPacket* Clone() const { return new cPacket_PlayerPosition(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- double m_PosX;
- double m_PosY;
- double m_Stance;
- double m_PosZ;
- bool m_bFlying; // Yeah.. wtf
-} ;
-
-
-
-
+ +// cPacket_Player.h + +/* Interfaces to the player-related packets: + - PlayerAbilities (0xca) + - PlayerListItem (0xc9) + - PlayerLook (0x0c) + - PlayerMoveLook (0x0d) + - PlayerPosition (0x0b) +*/ + +#pragma once + + + + + +#include "cPacket.h" + + + + + +// fwd: +class cPlayer; + + + + + +class cPacket_PlayerAbilities : public cPacket +{ +public: + cPacket_PlayerAbilities(void) { m_PacketID = E_PLAYER_LIST_ITEM; } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + virtual cPacket * Clone() const { return new cPacket_PlayerAbilities(*this); } + + bool m_Invulnerable; // Speculation + bool m_IsFlying; + bool m_CanFly; + bool m_InstaMine; // Speculation +} ; + + + + + +class cPacket_PlayerListItem : public cPacket +{ +public: + cPacket_PlayerListItem() { m_PacketID = E_PLAYER_LIST_ITEM; } + cPacket_PlayerListItem(const AString & a_PlayerName, bool a_Online, short a_Ping); + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + virtual cPacket* Clone() const { return new cPacket_PlayerListItem(*this); } + + AString m_PlayerName; // Supports chat coloring, limited to 16 characters. + bool m_Online; + short m_Ping; +} ; + + + + + +class cPacket_PlayerLook : public cPacket +{ +public: + cPacket_PlayerLook() + : m_Rotation( 0 ) + , m_Pitch( 0 ) + , m_bFlying( false ) + { m_PacketID = E_PLAYERLOOK; } + cPacket_PlayerLook( cPlayer* a_Player ); + virtual cPacket* Clone() const { return new cPacket_PlayerLook(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + float m_Rotation; + float m_Pitch; + bool m_bFlying; // Yeah.. wtf +} ; + + + + + +class cPacket_PlayerMoveLook : public cPacket +{ +public: + cPacket_PlayerMoveLook() + : m_PosX( 0.0 ) + , m_PosY( 0.0 ) + , m_Stance( 0.0 ) + , m_PosZ( 0.0 ) + , m_Rotation( 0.f ) + , m_Pitch( 0.f ) + , m_bFlying( false ) + { m_PacketID = E_PLAYERMOVELOOK; } + cPacket_PlayerMoveLook( cPlayer* a_Player ); + virtual cPacket* Clone() const { return new cPacket_PlayerMoveLook(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + double m_PosX; + double m_PosY; + double m_Stance; + double m_PosZ; + float m_Rotation; + float m_Pitch; + bool m_bFlying; // Yeah.. wtf +} ; + + + + + +class cPacket_PlayerPosition : public cPacket +{ +public: + cPacket_PlayerPosition( cPlayer* a_Player ); + cPacket_PlayerPosition() + : m_PosX( 0.0 ) + , m_PosY( 0.0 ) + , m_Stance( 0.0 ) + , m_PosZ( 0.0 ) + , m_bFlying( false ) + { m_PacketID = E_PLAYERPOS; } + virtual cPacket* Clone() const { return new cPacket_PlayerPosition(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + double m_PosX; + double m_PosY; + double m_Stance; + double m_PosZ; + bool m_bFlying; // Yeah.. wtf +} ; + + + + diff --git a/source/packets/cPacket_PreChunk.cpp b/source/packets/cPacket_PreChunk.cpp index a792ce124..f7824bba2 100644 --- a/source/packets/cPacket_PreChunk.cpp +++ b/source/packets/cPacket_PreChunk.cpp @@ -1,20 +1,20 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_PreChunk.h"
-
-
-
-
-
-void cPacket_PreChunk::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_PosX);
- AppendInteger(a_Data, m_PosZ);
- AppendBool (a_Data, m_bLoad);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_PreChunk.h" + + + + + +void cPacket_PreChunk::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_PosX); + AppendInteger(a_Data, m_PosZ); + AppendBool (a_Data, m_bLoad); +} + + + + diff --git a/source/packets/cPacket_PreChunk.h b/source/packets/cPacket_PreChunk.h index cc8147c4a..902fa2a02 100644 --- a/source/packets/cPacket_PreChunk.h +++ b/source/packets/cPacket_PreChunk.h @@ -1,36 +1,36 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_PreChunk: public cPacket
-{
-public:
- cPacket_PreChunk()
- : m_PosX( 0 )
- , m_PosZ( 0 )
- , m_bLoad( false )
- { m_PacketID = E_PRE_CHUNK; }
- cPacket_PreChunk( int a_PosX, int a_PosZ, bool a_bLoad )
- : m_PosX( a_PosX )
- , m_PosZ( a_PosZ )
- , m_bLoad( a_bLoad )
- { m_PacketID = E_PRE_CHUNK; }
- virtual cPacket* Clone() const { return new cPacket_PreChunk(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- int m_PosX;
- int m_PosZ;
- bool m_bLoad;
-
- static const unsigned int c_Size = 10;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_PreChunk: public cPacket +{ +public: + cPacket_PreChunk() + : m_PosX( 0 ) + , m_PosZ( 0 ) + , m_bLoad( false ) + { m_PacketID = E_PRE_CHUNK; } + cPacket_PreChunk( int a_PosX, int a_PosZ, bool a_bLoad ) + : m_PosX( a_PosX ) + , m_PosZ( a_PosZ ) + , m_bLoad( a_bLoad ) + { m_PacketID = E_PRE_CHUNK; } + virtual cPacket* Clone() const { return new cPacket_PreChunk(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_PosX; + int m_PosZ; + bool m_bLoad; + + static const unsigned int c_Size = 10; +}; + + + + diff --git a/source/packets/cPacket_RelativeEntityMove.cpp b/source/packets/cPacket_RelativeEntityMove.cpp index c4d0f3196..de3746024 100644 --- a/source/packets/cPacket_RelativeEntityMove.cpp +++ b/source/packets/cPacket_RelativeEntityMove.cpp @@ -1,21 +1,21 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_RelativeEntityMove.h"
-
-
-
-
-
-void cPacket_RelativeEntityMove::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_UniqueID);
- AppendByte (a_Data, m_MoveX);
- AppendByte (a_Data, m_MoveY);
- AppendByte (a_Data, m_MoveZ);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_RelativeEntityMove.h" + + + + + +void cPacket_RelativeEntityMove::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendByte (a_Data, m_MoveX); + AppendByte (a_Data, m_MoveY); + AppendByte (a_Data, m_MoveZ); +} + + + + diff --git a/source/packets/cPacket_RelativeEntityMove.h b/source/packets/cPacket_RelativeEntityMove.h index 9ccf0d95f..7dd2cbdbc 100644 --- a/source/packets/cPacket_RelativeEntityMove.h +++ b/source/packets/cPacket_RelativeEntityMove.h @@ -1,33 +1,33 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_RelativeEntityMove : public cPacket
-{
-public:
- cPacket_RelativeEntityMove()
- : m_UniqueID( 0 )
- , m_MoveX( 0 )
- , m_MoveY( 0 )
- , m_MoveZ( 0 )
- { m_PacketID = E_REL_ENT_MOVE; }
- virtual cPacket* Clone() const { return new cPacket_RelativeEntityMove(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- int m_UniqueID;
- char m_MoveX; // Pixels, devide by 32 for block
- char m_MoveY;
- char m_MoveZ;
-
- static const unsigned int c_Size = 1 + 4 + 1 + 1 + 1;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_RelativeEntityMove : public cPacket +{ +public: + cPacket_RelativeEntityMove() + : m_UniqueID( 0 ) + , m_MoveX( 0 ) + , m_MoveY( 0 ) + , m_MoveZ( 0 ) + { m_PacketID = E_REL_ENT_MOVE; } + virtual cPacket* Clone() const { return new cPacket_RelativeEntityMove(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + char m_MoveX; // Pixels, devide by 32 for block + char m_MoveY; + char m_MoveZ; + + static const unsigned int c_Size = 1 + 4 + 1 + 1 + 1; +}; + + + + diff --git a/source/packets/cPacket_RelativeEntityMoveLook.cpp b/source/packets/cPacket_RelativeEntityMoveLook.cpp index 1e8a9ae6c..fad2c0620 100644 --- a/source/packets/cPacket_RelativeEntityMoveLook.cpp +++ b/source/packets/cPacket_RelativeEntityMoveLook.cpp @@ -1,24 +1,24 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_RelativeEntityMoveLook.h"
-
-
-
-
-
-void cPacket_RelativeEntityMoveLook::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_UniqueID);
- AppendByte (a_Data, m_MoveX);
- AppendByte (a_Data, m_MoveY);
- AppendByte (a_Data, m_MoveZ);
- AppendByte (a_Data, m_Yaw);
- AppendByte (a_Data, m_Pitch);
-}
-
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_RelativeEntityMoveLook.h" + + + + + +void cPacket_RelativeEntityMoveLook::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendByte (a_Data, m_MoveX); + AppendByte (a_Data, m_MoveY); + AppendByte (a_Data, m_MoveZ); + AppendByte (a_Data, m_Yaw); + AppendByte (a_Data, m_Pitch); +} + + + + + diff --git a/source/packets/cPacket_RelativeEntityMoveLook.h b/source/packets/cPacket_RelativeEntityMoveLook.h index 79cb1a7eb..8fa6bf015 100644 --- a/source/packets/cPacket_RelativeEntityMoveLook.h +++ b/source/packets/cPacket_RelativeEntityMoveLook.h @@ -1,37 +1,37 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_RelativeEntityMoveLook : public cPacket
-{
-public:
- cPacket_RelativeEntityMoveLook()
- : m_UniqueID( 0 )
- , m_MoveX( 0 )
- , m_MoveY( 0 )
- , m_MoveZ( 0 )
- , m_Yaw( 0 )
- , m_Pitch( 0 )
- { m_PacketID = E_REL_ENT_MOVE_LOOK; }
- virtual cPacket* Clone() const { return new cPacket_RelativeEntityMoveLook(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- int m_UniqueID;
- char m_MoveX; // Pixels, divide by 32 for block
- char m_MoveY;
- char m_MoveZ;
- char m_Yaw;
- char m_Pitch;
-
- static const unsigned int c_Size = 1 + 4 + 1 + 1 + 1 + 1 + 1;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_RelativeEntityMoveLook : public cPacket +{ +public: + cPacket_RelativeEntityMoveLook() + : m_UniqueID( 0 ) + , m_MoveX( 0 ) + , m_MoveY( 0 ) + , m_MoveZ( 0 ) + , m_Yaw( 0 ) + , m_Pitch( 0 ) + { m_PacketID = E_REL_ENT_MOVE_LOOK; } + virtual cPacket* Clone() const { return new cPacket_RelativeEntityMoveLook(*this); } + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + char m_MoveX; // Pixels, divide by 32 for block + char m_MoveY; + char m_MoveZ; + char m_Yaw; + char m_Pitch; + + static const unsigned int c_Size = 1 + 4 + 1 + 1 + 1 + 1 + 1; +}; + + + + diff --git a/source/packets/cPacket_Respawn.cpp b/source/packets/cPacket_Respawn.cpp index a6b3b5bc4..657fd70b5 100644 --- a/source/packets/cPacket_Respawn.cpp +++ b/source/packets/cPacket_Respawn.cpp @@ -1,39 +1,39 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_Respawn.h"
-
-
-
-
-
-void cPacket_Respawn::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
-
- AppendInteger (a_Data, m_Dimension);
- AppendByte (a_Data, m_Difficulty);
- AppendByte (a_Data, m_CreativeMode);
- AppendShort (a_Data, m_WorldHeight);
- AppendString16(a_Data, m_LevelType);
-}
-
-
-
-
-
-int cPacket_Respawn::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
-
- HANDLE_PACKET_READ(ReadInteger, m_Dimension, TotalBytes);
- HANDLE_PACKET_READ(ReadByte, m_Difficulty, TotalBytes);
- HANDLE_PACKET_READ(ReadByte, m_CreativeMode, TotalBytes);
- HANDLE_PACKET_READ(ReadShort, m_WorldHeight, TotalBytes);
- HANDLE_PACKET_READ(ReadString16, m_LevelType, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_Respawn.h" + + + + + +void cPacket_Respawn::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + + AppendInteger (a_Data, m_Dimension); + AppendByte (a_Data, m_Difficulty); + AppendByte (a_Data, m_CreativeMode); + AppendShort (a_Data, m_WorldHeight); + AppendString16(a_Data, m_LevelType); +} + + + + + +int cPacket_Respawn::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + + HANDLE_PACKET_READ(ReadInteger, m_Dimension, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_Difficulty, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_CreativeMode, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_WorldHeight, TotalBytes); + HANDLE_PACKET_READ(ReadString16, m_LevelType, TotalBytes); + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_Respawn.h b/source/packets/cPacket_Respawn.h index b95ecc384..302dbe25e 100644 --- a/source/packets/cPacket_Respawn.h +++ b/source/packets/cPacket_Respawn.h @@ -1,37 +1,37 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-#include "cPacket_Login.h"
-
-
-
-
-
-class cPacket_Respawn : public cPacket
-{
-public:
- cPacket_Respawn()
- : m_Dimension( 0 )
- , m_Difficulty( 0 )
- , m_CreativeMode( 0 )
- , m_WorldHeight( 0 )
- , m_LevelType( cPacket_Login::LEVEL_TYPE_DEFAULT )
- { m_PacketID = E_RESPAWN; }
-
- virtual cPacket* Clone() const { return new cPacket_Respawn( *this ); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- int m_Dimension;
- char m_Difficulty;
- char m_CreativeMode;
- short m_WorldHeight;
- AString m_LevelType;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + +#include "cPacket_Login.h" + + + + + +class cPacket_Respawn : public cPacket +{ +public: + cPacket_Respawn() + : m_Dimension( 0 ) + , m_Difficulty( 0 ) + , m_CreativeMode( 0 ) + , m_WorldHeight( 0 ) + , m_LevelType( cPacket_Login::LEVEL_TYPE_DEFAULT ) + { m_PacketID = E_RESPAWN; } + + virtual cPacket* Clone() const { return new cPacket_Respawn( *this ); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + int m_Dimension; + char m_Difficulty; + char m_CreativeMode; + short m_WorldHeight; + AString m_LevelType; +}; + + + + diff --git a/source/packets/cPacket_SpawnMob.cpp b/source/packets/cPacket_SpawnMob.cpp index d3f1850b3..47339c7e0 100644 --- a/source/packets/cPacket_SpawnMob.cpp +++ b/source/packets/cPacket_SpawnMob.cpp @@ -1,75 +1,75 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_SpawnMob.h"
-#include "../Vector3i.h"
-
-
-
-
-
-cPacket_SpawnMob::~cPacket_SpawnMob()
-{
- if( m_MetaData ) delete [] m_MetaData;
- delete m_Pos;
-}
-
-
-
-
-
-cPacket_SpawnMob::cPacket_SpawnMob()
- : m_UniqueID( 0 )
- , m_Type( 0 )
- , m_Pos( new Vector3i() )
- , m_Yaw( 0 )
- , m_Pitch( 0 )
- , m_MetaDataSize( 0 )
- , m_MetaData( 0 )
- , m_HeadYaw(0)
-{
- m_PacketID = E_SPAWN_MOB;
-}
-
-
-
-
-
-cPacket_SpawnMob::cPacket_SpawnMob( const cPacket_SpawnMob & a_Clone )
-{
- m_Pos = new Vector3i();
-
- m_PacketID = E_SPAWN_MOB;
- m_UniqueID = a_Clone.m_UniqueID;
- m_Type = a_Clone.m_Type;
- *m_Pos = *a_Clone.m_Pos;
- m_Yaw = a_Clone.m_Yaw;
- m_Pitch = a_Clone.m_Pitch;
- m_HeadYaw = a_Clone.m_HeadYaw;
-
- m_MetaDataSize = a_Clone.m_MetaDataSize;
- m_MetaData = new char[m_MetaDataSize];
- memcpy( m_MetaData, a_Clone.m_MetaData, sizeof( char ) * m_MetaDataSize );
-}
-
-
-
-
-
-void cPacket_SpawnMob::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger (a_Data, m_UniqueID);
- AppendByte (a_Data, m_Type);
- AppendInteger (a_Data, m_Pos->x);
- AppendInteger (a_Data, m_Pos->y);
- AppendInteger (a_Data, m_Pos->z);
- AppendByte (a_Data, m_Yaw);
- AppendByte (a_Data, m_Pitch);
- AppendByte (a_Data, m_HeadYaw);
- AppendData (a_Data, m_MetaData, m_MetaDataSize);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_SpawnMob.h" +#include "../Vector3i.h" + + + + + +cPacket_SpawnMob::~cPacket_SpawnMob() +{ + if( m_MetaData ) delete [] m_MetaData; + delete m_Pos; +} + + + + + +cPacket_SpawnMob::cPacket_SpawnMob() + : m_UniqueID( 0 ) + , m_Type( 0 ) + , m_Pos( new Vector3i() ) + , m_Yaw( 0 ) + , m_Pitch( 0 ) + , m_MetaDataSize( 0 ) + , m_MetaData( 0 ) + , m_HeadYaw(0) +{ + m_PacketID = E_SPAWN_MOB; +} + + + + + +cPacket_SpawnMob::cPacket_SpawnMob( const cPacket_SpawnMob & a_Clone ) +{ + m_Pos = new Vector3i(); + + m_PacketID = E_SPAWN_MOB; + m_UniqueID = a_Clone.m_UniqueID; + m_Type = a_Clone.m_Type; + *m_Pos = *a_Clone.m_Pos; + m_Yaw = a_Clone.m_Yaw; + m_Pitch = a_Clone.m_Pitch; + m_HeadYaw = a_Clone.m_HeadYaw; + + m_MetaDataSize = a_Clone.m_MetaDataSize; + m_MetaData = new char[m_MetaDataSize]; + memcpy( m_MetaData, a_Clone.m_MetaData, sizeof( char ) * m_MetaDataSize ); +} + + + + + +void cPacket_SpawnMob::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger (a_Data, m_UniqueID); + AppendByte (a_Data, m_Type); + AppendInteger (a_Data, m_Pos->x); + AppendInteger (a_Data, m_Pos->y); + AppendInteger (a_Data, m_Pos->z); + AppendByte (a_Data, m_Yaw); + AppendByte (a_Data, m_Pitch); + AppendByte (a_Data, m_HeadYaw); + AppendData (a_Data, m_MetaData, m_MetaDataSize); +} + + + + diff --git a/source/packets/cPacket_SpawnMob.h b/source/packets/cPacket_SpawnMob.h index ff579af99..bc7fbe235 100644 --- a/source/packets/cPacket_SpawnMob.h +++ b/source/packets/cPacket_SpawnMob.h @@ -1,39 +1,39 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class Vector3i;
-
-
-
-
-
-class cPacket_SpawnMob : public cPacket
-{
-public:
- cPacket_SpawnMob();
- cPacket_SpawnMob( const cPacket_SpawnMob & a_Clone );
- virtual cPacket* Clone() const { return new cPacket_SpawnMob( *this ); }
- ~cPacket_SpawnMob();
-
- virtual void Serialize(AString & a_Data) const override;
-
- int m_UniqueID;
- char m_Type;
- Vector3i* m_Pos;
- char m_Yaw;
- char m_Pitch;
- char m_HeadYaw;
-
- unsigned int m_MetaDataSize;
- char * m_MetaData;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class Vector3i; + + + + + +class cPacket_SpawnMob : public cPacket +{ +public: + cPacket_SpawnMob(); + cPacket_SpawnMob( const cPacket_SpawnMob & a_Clone ); + virtual cPacket* Clone() const { return new cPacket_SpawnMob( *this ); } + ~cPacket_SpawnMob(); + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + char m_Type; + Vector3i* m_Pos; + char m_Yaw; + char m_Pitch; + char m_HeadYaw; + + unsigned int m_MetaDataSize; + char * m_MetaData; +}; + + + + diff --git a/source/packets/cPacket_TeleportEntity.cpp b/source/packets/cPacket_TeleportEntity.cpp index a888f009d..396095037 100644 --- a/source/packets/cPacket_TeleportEntity.cpp +++ b/source/packets/cPacket_TeleportEntity.cpp @@ -1,41 +1,41 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_TeleportEntity.h"
-
-#include "../cEntity.h"
-
-
-
-
-
-cPacket_TeleportEntity::cPacket_TeleportEntity(cEntity* a_Client)
-{
- m_PacketID = E_ENT_TELEPORT;
-
- m_UniqueID = a_Client->GetUniqueID();
- m_PosX = (int)(a_Client->GetPosX() * 32);
- m_PosY = (int)(a_Client->GetPosY() * 32);
- m_PosZ = (int)(a_Client->GetPosZ() * 32);
- m_Rotation = (char)((a_Client->GetRotation() / 360.f) * 256);
- m_Pitch = (char)((a_Client->GetPitch() / 360.f) * 256);
-}
-
-
-
-
-
-void cPacket_TeleportEntity::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger(a_Data, m_UniqueID);
- AppendInteger(a_Data, m_PosX);
- AppendInteger(a_Data, m_PosY);
- AppendInteger(a_Data, m_PosZ);
- AppendByte (a_Data, m_Rotation);
- AppendByte (a_Data, m_Pitch);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_TeleportEntity.h" + +#include "../cEntity.h" + + + + + +cPacket_TeleportEntity::cPacket_TeleportEntity(cEntity* a_Client) +{ + m_PacketID = E_ENT_TELEPORT; + + m_UniqueID = a_Client->GetUniqueID(); + m_PosX = (int)(a_Client->GetPosX() * 32); + m_PosY = (int)(a_Client->GetPosY() * 32); + m_PosZ = (int)(a_Client->GetPosZ() * 32); + m_Rotation = (char)((a_Client->GetRotation() / 360.f) * 256); + m_Pitch = (char)((a_Client->GetPitch() / 360.f) * 256); +} + + + + + +void cPacket_TeleportEntity::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger(a_Data, m_UniqueID); + AppendInteger(a_Data, m_PosX); + AppendInteger(a_Data, m_PosY); + AppendInteger(a_Data, m_PosZ); + AppendByte (a_Data, m_Rotation); + AppendByte (a_Data, m_Pitch); +} + + + + diff --git a/source/packets/cPacket_TeleportEntity.h b/source/packets/cPacket_TeleportEntity.h index 0cff50a85..d0504f901 100644 --- a/source/packets/cPacket_TeleportEntity.h +++ b/source/packets/cPacket_TeleportEntity.h @@ -1,39 +1,39 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cEntity;
-class cPacket_TeleportEntity : public cPacket
-{
-public:
- cPacket_TeleportEntity()
- : m_UniqueID( 0 )
- , m_PosX( 0 )
- , m_PosY( 0 )
- , m_PosZ( 0 )
- , m_Rotation( 0 )
- , m_Pitch( 0 )
- { m_PacketID = E_ENT_TELEPORT; }
- virtual cPacket* Clone() const { return new cPacket_TeleportEntity(*this); }
- cPacket_TeleportEntity(cEntity* a_Client);
-
- virtual void Serialize(AString & a_Data) const override;
-
- int m_UniqueID;
- int m_PosX; // Pixel position, divide by 32 for block position
- int m_PosY;
- int m_PosZ;
- char m_Rotation;
- char m_Pitch;
-
- static const unsigned int c_Size = 1 + 4 + 4 + 4 + 4 + 1 + 1;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cEntity; +class cPacket_TeleportEntity : public cPacket +{ +public: + cPacket_TeleportEntity() + : m_UniqueID( 0 ) + , m_PosX( 0 ) + , m_PosY( 0 ) + , m_PosZ( 0 ) + , m_Rotation( 0 ) + , m_Pitch( 0 ) + { m_PacketID = E_ENT_TELEPORT; } + virtual cPacket* Clone() const { return new cPacket_TeleportEntity(*this); } + cPacket_TeleportEntity(cEntity* a_Client); + + virtual void Serialize(AString & a_Data) const override; + + int m_UniqueID; + int m_PosX; // Pixel position, divide by 32 for block position + int m_PosY; + int m_PosZ; + char m_Rotation; + char m_Pitch; + + static const unsigned int c_Size = 1 + 4 + 4 + 4 + 4 + 1 + 1; +}; + + + + diff --git a/source/packets/cPacket_TimeUpdate.cpp b/source/packets/cPacket_TimeUpdate.cpp index a0bf05677..be54e1484 100644 --- a/source/packets/cPacket_TimeUpdate.cpp +++ b/source/packets/cPacket_TimeUpdate.cpp @@ -1,29 +1,29 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_TimeUpdate.h"
-
-
-
-
-
-int cPacket_TimeUpdate::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadLong, m_Time, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_TimeUpdate::Serialize(AString & a_Data) const
-{
- AppendByte(a_Data, m_PacketID);
- AppendLong(a_Data, m_Time);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_TimeUpdate.h" + + + + + +int cPacket_TimeUpdate::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadLong, m_Time, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_TimeUpdate::Serialize(AString & a_Data) const +{ + AppendByte(a_Data, m_PacketID); + AppendLong(a_Data, m_Time); +} + + + + diff --git a/source/packets/cPacket_TimeUpdate.h b/source/packets/cPacket_TimeUpdate.h index 1cc66c2f9..8864c9b00 100644 --- a/source/packets/cPacket_TimeUpdate.h +++ b/source/packets/cPacket_TimeUpdate.h @@ -1,29 +1,29 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_TimeUpdate : public cPacket
-{
-public:
- cPacket_TimeUpdate()
- : m_Time( 0 )
- { m_PacketID = E_UPDATE_TIME; }
- cPacket_TimeUpdate( long long a_Time ) { m_PacketID = E_UPDATE_TIME; m_Time = a_Time; }
- virtual cPacket* Clone() const { return new cPacket_TimeUpdate(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- long long m_Time;
-
- static const unsigned int c_Size = 1 + 8;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_TimeUpdate : public cPacket +{ +public: + cPacket_TimeUpdate() + : m_Time( 0 ) + { m_PacketID = E_UPDATE_TIME; } + cPacket_TimeUpdate( long long a_Time ) { m_PacketID = E_UPDATE_TIME; m_Time = a_Time; } + virtual cPacket* Clone() const { return new cPacket_TimeUpdate(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + long long m_Time; + + static const unsigned int c_Size = 1 + 8; +}; + + + + diff --git a/source/packets/cPacket_UpdateHealth.cpp b/source/packets/cPacket_UpdateHealth.cpp index 4380e25d6..ff54b6530 100644 --- a/source/packets/cPacket_UpdateHealth.cpp +++ b/source/packets/cPacket_UpdateHealth.cpp @@ -1,20 +1,20 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_UpdateHealth.h"
-
-
-
-
-
-void cPacket_UpdateHealth::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendShort(a_Data, m_Health);
- AppendShort(a_Data, m_Food);
- AppendFloat(a_Data, m_Saturation);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_UpdateHealth.h" + + + + + +void cPacket_UpdateHealth::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendShort(a_Data, m_Health); + AppendShort(a_Data, m_Food); + AppendFloat(a_Data, m_Saturation); +} + + + + diff --git a/source/packets/cPacket_UpdateHealth.h b/source/packets/cPacket_UpdateHealth.h index 3a6135e07..67fd32399 100644 --- a/source/packets/cPacket_UpdateHealth.h +++ b/source/packets/cPacket_UpdateHealth.h @@ -1,32 +1,32 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_UpdateHealth : public cPacket
-{
-public:
- cPacket_UpdateHealth()
- : m_Health( 0 )
- , m_Food( 0 )
- , m_Saturation( 0.f )
- { m_PacketID = E_UPDATE_HEALTH; }
- cPacket_UpdateHealth( short a_Health ) { m_Health = a_Health; m_PacketID = E_UPDATE_HEALTH; }
- virtual cPacket* Clone() const { return new cPacket_UpdateHealth( *this ); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- short m_Health;
- short m_Food;
- float m_Saturation;
-
- static const unsigned int c_Size = 1 + 2 + 2 + 4;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_UpdateHealth : public cPacket +{ +public: + cPacket_UpdateHealth() + : m_Health( 0 ) + , m_Food( 0 ) + , m_Saturation( 0.f ) + { m_PacketID = E_UPDATE_HEALTH; } + cPacket_UpdateHealth( short a_Health ) { m_Health = a_Health; m_PacketID = E_UPDATE_HEALTH; } + virtual cPacket* Clone() const { return new cPacket_UpdateHealth( *this ); } + + virtual void Serialize(AString & a_Data) const override; + + short m_Health; + short m_Food; + float m_Saturation; + + static const unsigned int c_Size = 1 + 2 + 2 + 4; +}; + + + + diff --git a/source/packets/cPacket_UpdateSign.cpp b/source/packets/cPacket_UpdateSign.cpp index 723fca6af..a3ea53968 100644 --- a/source/packets/cPacket_UpdateSign.cpp +++ b/source/packets/cPacket_UpdateSign.cpp @@ -1,41 +1,41 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_UpdateSign.h"
-
-
-
-
-
-int cPacket_UpdateSign::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes);
- HANDLE_PACKET_READ(ReadShort, m_PosY, TotalBytes);
- HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes);
- HANDLE_PACKET_READ(ReadString16, m_Line1, TotalBytes);
- HANDLE_PACKET_READ(ReadString16, m_Line2, TotalBytes);
- HANDLE_PACKET_READ(ReadString16, m_Line3, TotalBytes);
- HANDLE_PACKET_READ(ReadString16, m_Line4, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_UpdateSign::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendInteger (a_Data, m_PosX);
- AppendShort (a_Data, m_PosY);
- AppendInteger (a_Data, m_PosZ);
- AppendString16(a_Data, m_Line1);
- AppendString16(a_Data, m_Line2);
- AppendString16(a_Data, m_Line3);
- AppendString16(a_Data, m_Line4);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_UpdateSign.h" + + + + + +int cPacket_UpdateSign::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_PosX, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_PosY, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadString16, m_Line1, TotalBytes); + HANDLE_PACKET_READ(ReadString16, m_Line2, TotalBytes); + HANDLE_PACKET_READ(ReadString16, m_Line3, TotalBytes); + HANDLE_PACKET_READ(ReadString16, m_Line4, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_UpdateSign::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendInteger (a_Data, m_PosX); + AppendShort (a_Data, m_PosY); + AppendInteger (a_Data, m_PosZ); + AppendString16(a_Data, m_Line1); + AppendString16(a_Data, m_Line2); + AppendString16(a_Data, m_Line3); + AppendString16(a_Data, m_Line4); +} + + + + diff --git a/source/packets/cPacket_UpdateSign.h b/source/packets/cPacket_UpdateSign.h index 1e4da6471..b2c0effad 100644 --- a/source/packets/cPacket_UpdateSign.h +++ b/source/packets/cPacket_UpdateSign.h @@ -1,36 +1,36 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_UpdateSign : public cPacket
-{
-public:
- cPacket_UpdateSign()
- : m_PosX( 0 )
- , m_PosY( 0 )
- , m_PosZ( 0 )
- { m_PacketID = E_UPDATE_SIGN; }
- virtual cPacket* Clone() const { return new cPacket_UpdateSign( *this ); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- int m_PosX;
- short m_PosY;
- int m_PosZ;
- AString m_Line1;
- AString m_Line2;
- AString m_Line3;
- AString m_Line4;
-
- static const unsigned int c_Size = 1 + 4 + 2 + 4 + 2 + 2 + 2 + 2; // minimum size
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_UpdateSign : public cPacket +{ +public: + cPacket_UpdateSign() + : m_PosX( 0 ) + , m_PosY( 0 ) + , m_PosZ( 0 ) + { m_PacketID = E_UPDATE_SIGN; } + virtual cPacket* Clone() const { return new cPacket_UpdateSign( *this ); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + int m_PosX; + short m_PosY; + int m_PosZ; + AString m_Line1; + AString m_Line2; + AString m_Line3; + AString m_Line4; + + static const unsigned int c_Size = 1 + 4 + 2 + 4 + 2 + 2 + 2 + 2; // minimum size +}; + + + + diff --git a/source/packets/cPacket_UseEntity.cpp b/source/packets/cPacket_UseEntity.cpp index b131cb4fa..6f296e96b 100644 --- a/source/packets/cPacket_UseEntity.cpp +++ b/source/packets/cPacket_UseEntity.cpp @@ -1,21 +1,21 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_UseEntity.h"
-
-
-
-
-
-int cPacket_UseEntity::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadInteger, m_UniqueID, TotalBytes);
- HANDLE_PACKET_READ(ReadInteger, m_TargetID, TotalBytes);
- HANDLE_PACKET_READ(ReadBool, m_bLeftClick, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_UseEntity.h" + + + + + +int cPacket_UseEntity::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadInteger, m_UniqueID, TotalBytes); + HANDLE_PACKET_READ(ReadInteger, m_TargetID, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_bLeftClick, TotalBytes); + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_UseEntity.h b/source/packets/cPacket_UseEntity.h index a81352664..7a35bd54c 100644 --- a/source/packets/cPacket_UseEntity.h +++ b/source/packets/cPacket_UseEntity.h @@ -1,31 +1,31 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_UseEntity : public cPacket
-{
-public:
- cPacket_UseEntity()
- : m_UniqueID( 0 )
- , m_TargetID( 0 )
- , m_bLeftClick( false )
- { m_PacketID = E_USE_ENTITY; }
- virtual cPacket* Clone() const { return new cPacket_UseEntity(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
-
- int m_UniqueID;
- int m_TargetID;
- bool m_bLeftClick;
-
- static const unsigned int c_Size = 1 + 4 + 4 + 1;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_UseEntity : public cPacket +{ +public: + cPacket_UseEntity() + : m_UniqueID( 0 ) + , m_TargetID( 0 ) + , m_bLeftClick( false ) + { m_PacketID = E_USE_ENTITY; } + virtual cPacket* Clone() const { return new cPacket_UseEntity(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + + int m_UniqueID; + int m_TargetID; + bool m_bLeftClick; + + static const unsigned int c_Size = 1 + 4 + 4 + 1; +}; + + + + diff --git a/source/packets/cPacket_WholeInventory.cpp b/source/packets/cPacket_WholeInventory.cpp index 5e83f481f..3b8fa5cde 100644 --- a/source/packets/cPacket_WholeInventory.cpp +++ b/source/packets/cPacket_WholeInventory.cpp @@ -1,77 +1,77 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_WholeInventory.h"
-#include "../cItem.h"
-#include "../cInventory.h"
-#include "../cWindow.h"
-#include "cPacket_ItemData.h"
-
-
-
-
-
-cPacket_WholeInventory::cPacket_WholeInventory( const cPacket_WholeInventory & a_Clone )
-{
- m_PacketID = E_INVENTORY_WHOLE;
- m_WindowID = a_Clone.m_WindowID;
- m_Count = a_Clone.m_Count;
- m_Items = new cItem[m_Count];
- memcpy( m_Items, a_Clone.m_Items, sizeof(cItem)*m_Count );
-}
-
-
-
-
-
-cPacket_WholeInventory::cPacket_WholeInventory( cInventory* a_Inventory )
-{
- m_PacketID = E_INVENTORY_WHOLE;
- m_WindowID = 0;
- m_Count = a_Inventory->c_NumSlots;
- m_Items = new cItem[m_Count];
- memcpy( m_Items, a_Inventory->GetSlots(), sizeof(cItem)*m_Count );
-}
-
-
-
-
-
-cPacket_WholeInventory::cPacket_WholeInventory( cWindow* a_Window )
-{
- m_PacketID = E_INVENTORY_WHOLE;
- m_WindowID = (char)a_Window->GetWindowID();
- m_Count = (short)a_Window->GetNumSlots();
- m_Items = new cItem[m_Count];
- memcpy( m_Items, a_Window->GetSlots(), sizeof(cItem)*m_Count );
-}
-
-
-
-
-
-cPacket_WholeInventory::~cPacket_WholeInventory()
-{
- delete [] m_Items;
-}
-
-
-
-
-
-void cPacket_WholeInventory::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendByte (a_Data, m_WindowID);
- AppendShort(a_Data, m_Count);
-
- for (int j = 0; j < m_Count; j++)
- {
- cPacket_ItemData::AppendItem(a_Data, &(m_Items[j]));
- }
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_WholeInventory.h" +#include "../cItem.h" +#include "../cInventory.h" +#include "../cWindow.h" +#include "cPacket_ItemData.h" + + + + + +cPacket_WholeInventory::cPacket_WholeInventory( const cPacket_WholeInventory & a_Clone ) +{ + m_PacketID = E_INVENTORY_WHOLE; + m_WindowID = a_Clone.m_WindowID; + m_Count = a_Clone.m_Count; + m_Items = new cItem[m_Count]; + memcpy( m_Items, a_Clone.m_Items, sizeof(cItem)*m_Count ); +} + + + + + +cPacket_WholeInventory::cPacket_WholeInventory( cInventory* a_Inventory ) +{ + m_PacketID = E_INVENTORY_WHOLE; + m_WindowID = 0; + m_Count = a_Inventory->c_NumSlots; + m_Items = new cItem[m_Count]; + memcpy( m_Items, a_Inventory->GetSlots(), sizeof(cItem)*m_Count ); +} + + + + + +cPacket_WholeInventory::cPacket_WholeInventory( cWindow* a_Window ) +{ + m_PacketID = E_INVENTORY_WHOLE; + m_WindowID = (char)a_Window->GetWindowID(); + m_Count = (short)a_Window->GetNumSlots(); + m_Items = new cItem[m_Count]; + memcpy( m_Items, a_Window->GetSlots(), sizeof(cItem)*m_Count ); +} + + + + + +cPacket_WholeInventory::~cPacket_WholeInventory() +{ + delete [] m_Items; +} + + + + + +void cPacket_WholeInventory::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendByte (a_Data, m_WindowID); + AppendShort(a_Data, m_Count); + + for (int j = 0; j < m_Count; j++) + { + cPacket_ItemData::AppendItem(a_Data, &(m_Items[j])); + } +} + + + +
\ No newline at end of file diff --git a/source/packets/cPacket_WholeInventory.h b/source/packets/cPacket_WholeInventory.h index 5d895b367..3a9cc0a1b 100644 --- a/source/packets/cPacket_WholeInventory.h +++ b/source/packets/cPacket_WholeInventory.h @@ -1,47 +1,47 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-#include "../BlockID.h"
-
-
-
-
-
-class cInventory;
-class cWindow;
-class cItem;
-
-
-
-
-
-class cPacket_WholeInventory : public cPacket // full inventory [S -> C] ?
-{
-public:
- cPacket_WholeInventory( const cPacket_WholeInventory & a_Clone );
- cPacket_WholeInventory( cInventory* a_Inventory );
- cPacket_WholeInventory( cWindow* a_Window );
- ~cPacket_WholeInventory();
- cPacket_WholeInventory()
- : m_WindowID( 0 )
- , m_Count( 0 )
- , m_Items( 0 )
- { m_PacketID = E_INVENTORY_WHOLE; }
-
-
- virtual cPacket* Clone() const { return new cPacket_WholeInventory(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- char m_WindowID; // WTF?
- short m_Count; // Number of items
- cItem * m_Items; // Array of m_Count items
-
- static const unsigned int c_Size = 1 + 1 + 2; // Minimal size
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + +#include "../BlockID.h" + + + + + +class cInventory; +class cWindow; +class cItem; + + + + + +class cPacket_WholeInventory : public cPacket // full inventory [S -> C] ? +{ +public: + cPacket_WholeInventory( const cPacket_WholeInventory & a_Clone ); + cPacket_WholeInventory( cInventory* a_Inventory ); + cPacket_WholeInventory( cWindow* a_Window ); + ~cPacket_WholeInventory(); + cPacket_WholeInventory() + : m_WindowID( 0 ) + , m_Count( 0 ) + , m_Items( 0 ) + { m_PacketID = E_INVENTORY_WHOLE; } + + + virtual cPacket* Clone() const { return new cPacket_WholeInventory(*this); } + + virtual void Serialize(AString & a_Data) const override; + + char m_WindowID; // WTF? + short m_Count; // Number of items + cItem * m_Items; // Array of m_Count items + + static const unsigned int c_Size = 1 + 1 + 2; // Minimal size +}; + + + + diff --git a/source/packets/cPacket_WindowClick.cpp b/source/packets/cPacket_WindowClick.cpp index 0b2d18415..ac3191c28 100644 --- a/source/packets/cPacket_WindowClick.cpp +++ b/source/packets/cPacket_WindowClick.cpp @@ -1,43 +1,43 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_WindowClick.h"
-#include "cPacket_WholeInventory.h"
-#include "cPacket_ItemData.h"
-
-
-
-
-
-int cPacket_WindowClick::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadByte, m_WindowID, TotalBytes);
- HANDLE_PACKET_READ(ReadShort, m_SlotNum, TotalBytes);
- HANDLE_PACKET_READ(ReadByte, m_RightMouse, TotalBytes);
- HANDLE_PACKET_READ(ReadShort, m_NumClicks, TotalBytes);
- HANDLE_PACKET_READ(ReadBool, m_Bool, TotalBytes);
-
- // LOG("WindowClick: WindowID: %i; FromSlot: %i; Right/Le: %i; NumClick: %i", m_Type, m_SlotNum, m_RightMouse, m_NumClicks );
-
- cPacket_ItemData Item;
-
- int res = Item.Parse(a_Data + TotalBytes, a_Size - TotalBytes);
- if (res < 0)
- {
- return res;
- }
- TotalBytes += res;
-
- m_ItemID = Item.m_ItemID;
- m_ItemCount = Item.m_ItemCount;
- m_ItemUses = Item.m_ItemUses;
-
- m_EnchantNums = Item.m_EnchantNums;
-
- return TotalBytes;
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_WindowClick.h" +#include "cPacket_WholeInventory.h" +#include "cPacket_ItemData.h" + + + + + +int cPacket_WindowClick::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadByte, m_WindowID, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_SlotNum, TotalBytes); + HANDLE_PACKET_READ(ReadByte, m_RightMouse, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_NumClicks, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_Bool, TotalBytes); + + // LOG("WindowClick: WindowID: %i; FromSlot: %i; Right/Le: %i; NumClick: %i", m_Type, m_SlotNum, m_RightMouse, m_NumClicks ); + + cPacket_ItemData Item; + + int res = Item.Parse(a_Data + TotalBytes, a_Size - TotalBytes); + if (res < 0) + { + return res; + } + TotalBytes += res; + + m_ItemID = Item.m_ItemID; + m_ItemCount = Item.m_ItemCount; + m_ItemUses = Item.m_ItemUses; + + m_EnchantNums = Item.m_EnchantNums; + + return TotalBytes; +} + + + + diff --git a/source/packets/cPacket_WindowClick.h b/source/packets/cPacket_WindowClick.h index 09fc1d862..2d78d3f00 100644 --- a/source/packets/cPacket_WindowClick.h +++ b/source/packets/cPacket_WindowClick.h @@ -1,52 +1,52 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_WindowClick : public cPacket // [C -> S]
-{
-public:
- cPacket_WindowClick()
- : m_WindowID( 0 )
- , m_SlotNum( 0 )
- , m_RightMouse( 0 )
- , m_NumClicks( 0 )
- , m_Bool( false )
- , m_ItemID( 0 )
- , m_ItemCount( 0 )
- , m_ItemUses( 0 )
- , m_EnchantNums(-1)
- { m_PacketID = E_WINDOW_CLICK; }
- virtual cPacket* Clone() const { return new cPacket_WindowClick(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
-
- char m_WindowID;
- short m_SlotNum; // Slot
- // 0 = craft result
- // 1-4 = crafting table
- // 5-8 = armor
- // 9-35 = inventory
- // 36-44 = Hot bar
-
- char m_RightMouse; // 0 = left 1 = Right mb
- short m_NumClicks; // Num clicks
- bool m_Bool; // unkown???????????? SHIFT clicked
-
- // Below = item
- short m_ItemID; // if this is -1 the next stuff dont exist
- char m_ItemCount;
- short m_ItemUses;
-
- short m_EnchantNums;
-
- static const unsigned int c_Size = 1 + 1 + 2 + 1 + 2 + 2; // Minimal size ( +1+1 = max)
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_WindowClick : public cPacket // [C -> S] +{ +public: + cPacket_WindowClick() + : m_WindowID( 0 ) + , m_SlotNum( 0 ) + , m_RightMouse( 0 ) + , m_NumClicks( 0 ) + , m_Bool( false ) + , m_ItemID( 0 ) + , m_ItemCount( 0 ) + , m_ItemUses( 0 ) + , m_EnchantNums(-1) + { m_PacketID = E_WINDOW_CLICK; } + virtual cPacket* Clone() const { return new cPacket_WindowClick(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + + char m_WindowID; + short m_SlotNum; // Slot + // 0 = craft result + // 1-4 = crafting table + // 5-8 = armor + // 9-35 = inventory + // 36-44 = Hot bar + + char m_RightMouse; // 0 = left 1 = Right mb + short m_NumClicks; // Num clicks + bool m_Bool; // unkown???????????? SHIFT clicked + + // Below = item + short m_ItemID; // if this is -1 the next stuff dont exist + char m_ItemCount; + short m_ItemUses; + + short m_EnchantNums; + + static const unsigned int c_Size = 1 + 1 + 2 + 1 + 2 + 2; // Minimal size ( +1+1 = max) +}; + + + + diff --git a/source/packets/cPacket_WindowClose.cpp b/source/packets/cPacket_WindowClose.cpp index 25669bf79..f4361e4a1 100644 --- a/source/packets/cPacket_WindowClose.cpp +++ b/source/packets/cPacket_WindowClose.cpp @@ -1,29 +1,29 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_WindowClose.h"
-
-
-
-
-
-int cPacket_WindowClose::Parse(const char * a_Data, int a_Size)
-{
- int TotalBytes = 0;
- HANDLE_PACKET_READ(ReadByte, m_Close, TotalBytes);
- return TotalBytes;
-}
-
-
-
-
-
-void cPacket_WindowClose::Serialize(AString & a_Data) const
-{
- AppendByte(a_Data, m_PacketID);
- AppendByte(a_Data, m_Close);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_WindowClose.h" + + + + + +int cPacket_WindowClose::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadByte, m_Close, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_WindowClose::Serialize(AString & a_Data) const +{ + AppendByte(a_Data, m_PacketID); + AppendByte(a_Data, m_Close); +} + + + + diff --git a/source/packets/cPacket_WindowClose.h b/source/packets/cPacket_WindowClose.h index 1063896ff..674c071d1 100644 --- a/source/packets/cPacket_WindowClose.h +++ b/source/packets/cPacket_WindowClose.h @@ -1,28 +1,28 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_WindowClose : public cPacket
-{
-public:
- cPacket_WindowClose()
- : m_Close( 0 )
- { m_PacketID = E_WINDOW_CLOSE; }
- virtual cPacket* Clone() const { return new cPacket_WindowClose(*this); }
-
- virtual int Parse(const char * a_Data, int a_Size) override;
- virtual void Serialize(AString & a_Data) const override;
-
- char m_Close; // m_Close == cWindow WindowType number
-
- static const unsigned int c_Size = 1 + 1;
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_WindowClose : public cPacket +{ +public: + cPacket_WindowClose() + : m_Close( 0 ) + { m_PacketID = E_WINDOW_CLOSE; } + virtual cPacket* Clone() const { return new cPacket_WindowClose(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + char m_Close; // m_Close == cWindow WindowType number + + static const unsigned int c_Size = 1 + 1; +}; + + + + diff --git a/source/packets/cPacket_WindowOpen.cpp b/source/packets/cPacket_WindowOpen.cpp index a5c3ade7e..8c4402139 100644 --- a/source/packets/cPacket_WindowOpen.cpp +++ b/source/packets/cPacket_WindowOpen.cpp @@ -1,21 +1,21 @@ -
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "cPacket_WindowOpen.h"
-
-
-
-
-
-void cPacket_WindowOpen::Serialize(AString & a_Data) const
-{
- AppendByte (a_Data, m_PacketID);
- AppendByte (a_Data, m_WindowID);
- AppendByte (a_Data, m_InventoryType);
- AppendString16(a_Data, m_WindowTitle);
- AppendByte (a_Data, m_NumSlots);
-}
-
-
-
-
+ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "cPacket_WindowOpen.h" + + + + + +void cPacket_WindowOpen::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendByte (a_Data, m_WindowID); + AppendByte (a_Data, m_InventoryType); + AppendString16(a_Data, m_WindowTitle); + AppendByte (a_Data, m_NumSlots); +} + + + + diff --git a/source/packets/cPacket_WindowOpen.h b/source/packets/cPacket_WindowOpen.h index f3b225639..3896f5f02 100644 --- a/source/packets/cPacket_WindowOpen.h +++ b/source/packets/cPacket_WindowOpen.h @@ -1,32 +1,32 @@ -
-#pragma once
-
-#include "cPacket.h"
-
-
-
-
-
-class cPacket_WindowOpen : public cPacket
-{
-public:
- cPacket_WindowOpen()
- : m_WindowID( 0 )
- , m_InventoryType( 0 )
- , m_NumSlots( 0 )
- { m_PacketID = E_WINDOW_OPEN; }
- virtual cPacket* Clone() const { return new cPacket_WindowOpen(*this); }
-
- virtual void Serialize(AString & a_Data) const override;
-
- char m_WindowID;
- char m_InventoryType;
- AString m_WindowTitle;
- char m_NumSlots;
-
- static const unsigned int c_Size = 1 + 1 + 1 + 2 + 1; // + sizeof(string)
-};
-
-
-
-
+ +#pragma once + +#include "cPacket.h" + + + + + +class cPacket_WindowOpen : public cPacket +{ +public: + cPacket_WindowOpen() + : m_WindowID( 0 ) + , m_InventoryType( 0 ) + , m_NumSlots( 0 ) + { m_PacketID = E_WINDOW_OPEN; } + virtual cPacket* Clone() const { return new cPacket_WindowOpen(*this); } + + virtual void Serialize(AString & a_Data) const override; + + char m_WindowID; + char m_InventoryType; + AString m_WindowTitle; + char m_NumSlots; + + static const unsigned int c_Size = 1 + 1 + 1 + 2 + 1; // + sizeof(string) +}; + + + + diff --git a/source/tolua_base.h b/source/tolua_base.h index 28708eb59..4f1038c09 100644 --- a/source/tolua_base.h +++ b/source/tolua_base.h @@ -1,128 +1,128 @@ -#ifndef TOLUA_BASE_H
-#define TOLUA_BASE_H
-
-#pragma warning(disable:4800) // This file is ONLY included by Bindings.cpp and it throws lots of C4800 warnings
-
-#include "tolua++.h"
-
-
-
-
-
-class ToluaBase {
-
- int lua_instance;
-
-protected:
-
- lua_State* lua_state;
-
- void lua_stacktrace(lua_State* L) const
- {
- lua_Debug entry;
- int depth = 0;
-
- while (lua_getstack(L, depth, &entry))
- {
- lua_getinfo(L, "Sln", &entry);
-
- LOGERROR("%s(%d): %s", entry.short_src, entry.currentline, entry.name ? entry.name : "?");
- depth++;
- }
- }
-
-
- bool report_errors(int status) const
- {
- if ( status!=0 )
- {
- const char* s = lua_tostring(lua_state, -1);
- LOGERROR("-- %s", s );
- //lua_pop(lua_state, 1);
- LOGERROR("Stack:");
- lua_stacktrace( lua_state );
- return true;
- }
- return false;
- }
-
- bool push_method(const char* name, lua_CFunction f) const {
-
- if (!lua_state) return false;
-
- lua_getref(lua_state, lua_instance);
- lua_pushstring(lua_state, name);
- //LOGINFO("1. push_method() Stack size: %i", lua_gettop( lua_state ) );
- lua_gettable(lua_state, -2);
- //LOGINFO("2. push_method() Stack size: %i", lua_gettop( lua_state ) );
-
- if (lua_isnil(lua_state, -1)) {
-
- // pop the table
- lua_pop(lua_state, 2);
- return false;
-
- } else {
-
- if (f) {
- if (lua_iscfunction(lua_state, -1)) {
- lua_pop(lua_state, 2);
- return false;
- };
- /* // not for now
- lua_pushcfunction(lua_state, f);
- if (lua_rawequal(lua_state, -1, -2)) {
-
- // avoid recursion, pop both functions and the table
- lua_pop(lua_state, 3);
- return false;
- };
-
- // pop f
- lua_pop(lua_state, 1);
- */
- };
-
- // swap table with function
- lua_insert(lua_state, -2);
- };
-
- return true;
- };
-
- void dbcall(lua_State* L, int nargs, int nresults) const {
-
- // using lua_call for now
- int s = lua_pcall(L, nargs, nresults, 0);
- report_errors( s );
- };
-public:
-
- int GetInstance() { return lua_instance; }
- lua_State* GetLuaState() { return lua_state; }
-
- void tolua__set_instance(lua_State* L, lua_Object lo) {
-
- lua_state = L;
-
- lua_pushvalue(L, lo);
- lua_instance = lua_ref(lua_state, 1);
- };
-
- ToluaBase() {
-
- lua_state = NULL;
- };
-
- ~ToluaBase() {
-
- if (lua_state) {
-
- lua_unref(lua_state, lua_instance);
- };
- };
-};
-
-#endif
-
-
+#ifndef TOLUA_BASE_H +#define TOLUA_BASE_H + +#pragma warning(disable:4800) // This file is ONLY included by Bindings.cpp and it throws lots of C4800 warnings + +#include "tolua++.h" + + + + + +class ToluaBase { + + int lua_instance; + +protected: + + lua_State* lua_state; + + void lua_stacktrace(lua_State* L) const + { + lua_Debug entry; + int depth = 0; + + while (lua_getstack(L, depth, &entry)) + { + lua_getinfo(L, "Sln", &entry); + + LOGERROR("%s(%d): %s", entry.short_src, entry.currentline, entry.name ? entry.name : "?"); + depth++; + } + } + + + bool report_errors(int status) const + { + if ( status!=0 ) + { + const char* s = lua_tostring(lua_state, -1); + LOGERROR("-- %s", s ); + //lua_pop(lua_state, 1); + LOGERROR("Stack:"); + lua_stacktrace( lua_state ); + return true; + } + return false; + } + + bool push_method(const char* name, lua_CFunction f) const { + + if (!lua_state) return false; + + lua_getref(lua_state, lua_instance); + lua_pushstring(lua_state, name); + //LOGINFO("1. push_method() Stack size: %i", lua_gettop( lua_state ) ); + lua_gettable(lua_state, -2); + //LOGINFO("2. push_method() Stack size: %i", lua_gettop( lua_state ) ); + + if (lua_isnil(lua_state, -1)) { + + // pop the table + lua_pop(lua_state, 2); + return false; + + } else { + + if (f) { + if (lua_iscfunction(lua_state, -1)) { + lua_pop(lua_state, 2); + return false; + }; + /* // not for now + lua_pushcfunction(lua_state, f); + if (lua_rawequal(lua_state, -1, -2)) { + + // avoid recursion, pop both functions and the table + lua_pop(lua_state, 3); + return false; + }; + + // pop f + lua_pop(lua_state, 1); + */ + }; + + // swap table with function + lua_insert(lua_state, -2); + }; + + return true; + }; + + void dbcall(lua_State* L, int nargs, int nresults) const { + + // using lua_call for now + int s = lua_pcall(L, nargs, nresults, 0); + report_errors( s ); + }; +public: + + int GetInstance() { return lua_instance; } + lua_State* GetLuaState() { return lua_state; } + + void tolua__set_instance(lua_State* L, lua_Object lo) { + + lua_state = L; + + lua_pushvalue(L, lo); + lua_instance = lua_ref(lua_state, 1); + }; + + ToluaBase() { + + lua_state = NULL; + }; + + ~ToluaBase() { + + if (lua_state) { + + lua_unref(lua_state, lua_instance); + }; + }; +}; + +#endif + + diff --git a/squirrel_3_0_1_stable/include/sqstdaux.h b/squirrel_3_0_1_stable/include/sqstdaux.h index b90034823..c16b04373 100644 --- a/squirrel_3_0_1_stable/include/sqstdaux.h +++ b/squirrel_3_0_1_stable/include/sqstdaux.h @@ -1,16 +1,16 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_AUXLIB_H_
-#define _SQSTD_AUXLIB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v);
-SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /* _SQSTD_AUXLIB_H_ */
+/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_AUXLIB_H_ +#define _SQSTD_AUXLIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v); +SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* _SQSTD_AUXLIB_H_ */ diff --git a/squirrel_3_0_1_stable/include/sqstdblob.h b/squirrel_3_0_1_stable/include/sqstdblob.h index eda4cc9c5..1d9a4cdc3 100644 --- a/squirrel_3_0_1_stable/include/sqstdblob.h +++ b/squirrel_3_0_1_stable/include/sqstdblob.h @@ -1,20 +1,20 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQSTDBLOB_H_
-#define _SQSTDBLOB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size);
-SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr);
-SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx);
-
-SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTDBLOB_H_*/
-
+/* see copyright notice in squirrel.h */ +#ifndef _SQSTDBLOB_H_ +#define _SQSTDBLOB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size); +SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr); +SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx); + +SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQSTDBLOB_H_*/ + diff --git a/squirrel_3_0_1_stable/include/sqstdio.h b/squirrel_3_0_1_stable/include/sqstdio.h index 1174201a9..2cb744bcf 100644 --- a/squirrel_3_0_1_stable/include/sqstdio.h +++ b/squirrel_3_0_1_stable/include/sqstdio.h @@ -1,53 +1,53 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQSTDIO_H_
-#define _SQSTDIO_H_
-
-#ifdef __cplusplus
-
-#define SQSTD_STREAM_TYPE_TAG 0x80000000
-
-struct SQStream {
- virtual SQInteger Read(void *buffer, SQInteger size) = 0;
- virtual SQInteger Write(void *buffer, SQInteger size) = 0;
- virtual SQInteger Flush() = 0;
- virtual SQInteger Tell() = 0;
- virtual SQInteger Len() = 0;
- virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0;
- virtual bool IsValid() = 0;
- virtual bool EOS() = 0;
-};
-
-extern "C" {
-#endif
-
-#define SQ_SEEK_CUR 0
-#define SQ_SEEK_END 1
-#define SQ_SEEK_SET 2
-
-typedef void* SQFILE;
-
-SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *);
-SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE);
-SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE);
-SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger);
-SQUIRREL_API SQInteger sqstd_ftell(SQFILE);
-SQUIRREL_API SQInteger sqstd_fflush(SQFILE);
-SQUIRREL_API SQInteger sqstd_fclose(SQFILE);
-SQUIRREL_API SQInteger sqstd_feof(SQFILE);
-
-SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own);
-SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file);
-
-//compiler helpers
-SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror);
-SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror);
-SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename);
-
-SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTDIO_H_*/
-
+/* see copyright notice in squirrel.h */ +#ifndef _SQSTDIO_H_ +#define _SQSTDIO_H_ + +#ifdef __cplusplus + +#define SQSTD_STREAM_TYPE_TAG 0x80000000 + +struct SQStream { + virtual SQInteger Read(void *buffer, SQInteger size) = 0; + virtual SQInteger Write(void *buffer, SQInteger size) = 0; + virtual SQInteger Flush() = 0; + virtual SQInteger Tell() = 0; + virtual SQInteger Len() = 0; + virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0; + virtual bool IsValid() = 0; + virtual bool EOS() = 0; +}; + +extern "C" { +#endif + +#define SQ_SEEK_CUR 0 +#define SQ_SEEK_END 1 +#define SQ_SEEK_SET 2 + +typedef void* SQFILE; + +SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *); +SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE); +SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE); +SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger); +SQUIRREL_API SQInteger sqstd_ftell(SQFILE); +SQUIRREL_API SQInteger sqstd_fflush(SQFILE); +SQUIRREL_API SQInteger sqstd_fclose(SQFILE); +SQUIRREL_API SQInteger sqstd_feof(SQFILE); + +SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own); +SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file); + +//compiler helpers +SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror); +SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror); +SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename); + +SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQSTDIO_H_*/ + diff --git a/squirrel_3_0_1_stable/include/sqstdmath.h b/squirrel_3_0_1_stable/include/sqstdmath.h index 420f2ce67..65de6fd72 100644 --- a/squirrel_3_0_1_stable/include/sqstdmath.h +++ b/squirrel_3_0_1_stable/include/sqstdmath.h @@ -1,15 +1,15 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_MATH_H_
-#define _SQSTD_MATH_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTD_MATH_H_*/
+/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_MATH_H_ +#define _SQSTD_MATH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQSTD_MATH_H_*/ diff --git a/squirrel_3_0_1_stable/include/sqstdstring.h b/squirrel_3_0_1_stable/include/sqstdstring.h index 771c2f658..3c3bce826 100644 --- a/squirrel_3_0_1_stable/include/sqstdstring.h +++ b/squirrel_3_0_1_stable/include/sqstdstring.h @@ -1,33 +1,33 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_STRING_H_
-#define _SQSTD_STRING_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef unsigned int SQRexBool;
-typedef struct SQRex SQRex;
-
-typedef struct {
- const SQChar *begin;
- SQInteger len;
-} SQRexMatch;
-
-SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error);
-SQUIRREL_API void sqstd_rex_free(SQRex *exp);
-SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text);
-SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end);
-SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end);
-SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp);
-SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp);
-
-SQUIRREL_API SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output);
-
-SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTD_STRING_H_*/
+/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_STRING_H_ +#define _SQSTD_STRING_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned int SQRexBool; +typedef struct SQRex SQRex; + +typedef struct { + const SQChar *begin; + SQInteger len; +} SQRexMatch; + +SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error); +SQUIRREL_API void sqstd_rex_free(SQRex *exp); +SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text); +SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end); +SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end); +SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp); +SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp); + +SQUIRREL_API SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output); + +SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQSTD_STRING_H_*/ diff --git a/squirrel_3_0_1_stable/include/sqstdsystem.h b/squirrel_3_0_1_stable/include/sqstdsystem.h index daefa0fd5..b155a91f8 100644 --- a/squirrel_3_0_1_stable/include/sqstdsystem.h +++ b/squirrel_3_0_1_stable/include/sqstdsystem.h @@ -1,15 +1,15 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_SYSTEMLIB_H_
-#define _SQSTD_SYSTEMLIB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /* _SQSTD_SYSTEMLIB_H_ */
+/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_SYSTEMLIB_H_ +#define _SQSTD_SYSTEMLIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* _SQSTD_SYSTEMLIB_H_ */ diff --git a/squirrel_3_0_1_stable/include/squirrel.h b/squirrel_3_0_1_stable/include/squirrel.h index baaaf39c5..e030a31da 100644 --- a/squirrel_3_0_1_stable/include/squirrel.h +++ b/squirrel_3_0_1_stable/include/squirrel.h @@ -1,500 +1,500 @@ -/*
-Copyright (c) 2003-2011 Alberto Demichelis
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-#ifndef _SQUIRREL_H_
-#define _SQUIRREL_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef SQUIRREL_API
-#define SQUIRREL_API extern
-#endif
-
-#if (defined(_WIN64) || defined(_LP64))
-#ifndef _SQ64
-#define _SQ64
-#endif
-#endif
-
-#ifdef _SQ64
-
-#ifdef _MSC_VER
-typedef __int64 SQInteger;
-typedef unsigned __int64 SQUnsignedInteger;
-typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/
-#else
-typedef long long SQInteger;
-typedef unsigned long long SQUnsignedInteger;
-typedef unsigned long long SQHash; /*should be the same size of a pointer*/
-#endif
-typedef int SQInt32;
-typedef unsigned int SQUnsignedInteger32;
-#else
-typedef int SQInteger;
-typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/
-typedef unsigned int SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/
-typedef unsigned int SQUnsignedInteger;
-typedef unsigned int SQHash; /*should be the same size of a pointer*/
-#endif
-
-
-#ifdef SQUSEDOUBLE
-typedef double SQFloat;
-#else
-typedef float SQFloat;
-#endif
-
-#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64)
-#ifdef _MSC_VER
-typedef __int64 SQRawObjectVal; //must be 64bits
-#else
-typedef long long SQRawObjectVal; //must be 64bits
-#endif
-#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; }
-#else
-typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise
-#define SQ_OBJECT_RAWINIT()
-#endif
-
-#ifndef SQ_ALIGNMENT // SQ_ALIGNMENT shall be less than or equal to SQ_MALLOC alignments, and its value shall be power of 2.
-#if defined(SQUSEDOUBLE) || defined(_SQ64)
-#define SQ_ALIGNMENT 8
-#else
-#define SQ_ALIGNMENT 4
-#endif
-#endif
-
-typedef void* SQUserPointer;
-typedef SQUnsignedInteger SQBool;
-typedef SQInteger SQRESULT;
-
-#define SQTrue (1)
-#define SQFalse (0)
-
-struct SQVM;
-struct SQTable;
-struct SQArray;
-struct SQString;
-struct SQClosure;
-struct SQGenerator;
-struct SQNativeClosure;
-struct SQUserData;
-struct SQFunctionProto;
-struct SQRefCounted;
-struct SQClass;
-struct SQInstance;
-struct SQDelegable;
-struct SQOuter;
-
-#ifdef _UNICODE
-#define SQUNICODE
-#endif
-
-#ifdef SQUNICODE
-#if (defined(_MSC_VER) && _MSC_VER >= 1400) // 1400 = VS8
-
-#if !defined(_NATIVE_WCHAR_T_DEFINED) //this is if the compiler considers wchar_t as native type
-#define wchar_t unsigned short
-#endif
-
-#else
-typedef unsigned short wchar_t;
-#endif
-
-typedef wchar_t SQChar;
-#define _SC(a) L##a
-#define scstrcmp wcscmp
-#define scsprintf swprintf
-#define scstrlen wcslen
-#define scstrtod wcstod
-#ifdef _SQ64
-#define scstrtol _wcstoi64
-#else
-#define scstrtol wcstol
-#endif
-#define scatoi _wtoi
-#define scstrtoul wcstoul
-#define scvsprintf vswprintf
-#define scstrstr wcsstr
-#define scisspace iswspace
-#define scisdigit iswdigit
-#define scisxdigit iswxdigit
-#define scisalpha iswalpha
-#define sciscntrl iswcntrl
-#define scisalnum iswalnum
-#define scprintf wprintf
-#define MAX_CHAR 0xFFFF
-#else
-typedef char SQChar;
-#define _SC(a) a
-#define scstrcmp strcmp
-#define scsprintf sprintf
-#define scstrlen strlen
-#define scstrtod strtod
-#ifdef _SQ64
-#ifdef _MSC_VER
-#define scstrtol _strtoi64
-#else
-#define scstrtol strtoll
-#endif
-#else
-#define scstrtol strtol
-#endif
-#define scatoi atoi
-#define scstrtoul strtoul
-#define scvsprintf vsprintf
-#define scstrstr strstr
-#define scisspace isspace
-#define scisdigit isdigit
-#define scisxdigit isxdigit
-#define sciscntrl iscntrl
-#define scisalpha isalpha
-#define scisalnum isalnum
-#define scprintf printf
-#define MAX_CHAR 0xFF
-#endif
-
-#ifdef _SQ64
-#define _PRINT_INT_PREC _SC("ll")
-#define _PRINT_INT_FMT _SC("%lld")
-#else
-#define _PRINT_INT_FMT _SC("%d")
-#endif
-
-#define SQUIRREL_VERSION _SC("Squirrel 3.0.1 stable")
-#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2011 Alberto Demichelis")
-#define SQUIRREL_AUTHOR _SC("Alberto Demichelis")
-#define SQUIRREL_VERSION_NUMBER 301
-
-#define SQ_VMSTATE_IDLE 0
-#define SQ_VMSTATE_RUNNING 1
-#define SQ_VMSTATE_SUSPENDED 2
-
-#define SQUIRREL_EOB 0
-#define SQ_BYTECODE_STREAM_TAG 0xFAFA
-
-#define SQOBJECT_REF_COUNTED 0x08000000
-#define SQOBJECT_NUMERIC 0x04000000
-#define SQOBJECT_DELEGABLE 0x02000000
-#define SQOBJECT_CANBEFALSE 0x01000000
-
-#define SQ_MATCHTYPEMASKSTRING (-99999)
-
-#define _RT_MASK 0x00FFFFFF
-#define _RAW_TYPE(type) (type&_RT_MASK)
-
-#define _RT_NULL 0x00000001
-#define _RT_INTEGER 0x00000002
-#define _RT_FLOAT 0x00000004
-#define _RT_BOOL 0x00000008
-#define _RT_STRING 0x00000010
-#define _RT_TABLE 0x00000020
-#define _RT_ARRAY 0x00000040
-#define _RT_USERDATA 0x00000080
-#define _RT_CLOSURE 0x00000100
-#define _RT_NATIVECLOSURE 0x00000200
-#define _RT_GENERATOR 0x00000400
-#define _RT_USERPOINTER 0x00000800
-#define _RT_THREAD 0x00001000
-#define _RT_FUNCPROTO 0x00002000
-#define _RT_CLASS 0x00004000
-#define _RT_INSTANCE 0x00008000
-#define _RT_WEAKREF 0x00010000
-#define _RT_OUTER 0x00020000
-
-typedef enum tagSQObjectType{
- OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE),
- OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
- OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
- OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE),
- OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED),
- OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
- OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED),
- OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
- OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED),
- OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),
- OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED),
- OT_USERPOINTER = _RT_USERPOINTER,
- OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) ,
- OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only
- OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED),
- OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
- OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED),
- OT_OUTER = (_RT_OUTER|SQOBJECT_REF_COUNTED) //internal usage only
-}SQObjectType;
-
-#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)
-
-
-typedef union tagSQObjectValue
-{
- struct SQTable *pTable;
- struct SQArray *pArray;
- struct SQClosure *pClosure;
- struct SQOuter *pOuter;
- struct SQGenerator *pGenerator;
- struct SQNativeClosure *pNativeClosure;
- struct SQString *pString;
- struct SQUserData *pUserData;
- SQInteger nInteger;
- SQFloat fFloat;
- SQUserPointer pUserPointer;
- struct SQFunctionProto *pFunctionProto;
- struct SQRefCounted *pRefCounted;
- struct SQDelegable *pDelegable;
- struct SQVM *pThread;
- struct SQClass *pClass;
- struct SQInstance *pInstance;
- struct SQWeakRef *pWeakRef;
- SQRawObjectVal raw;
-}SQObjectValue;
-
-
-typedef struct tagSQObject
-{
- SQObjectType _type;
- SQObjectValue _unVal;
-}SQObject;
-
-typedef struct tagSQMemberHandle{
- SQBool _static;
- SQInteger _index;
-}SQMemberHandle;
-
-typedef struct tagSQStackInfos{
- const SQChar* funcname;
- const SQChar* source;
- SQInteger line;
-}SQStackInfos;
-
-typedef struct SQVM* HSQUIRRELVM;
-typedef SQObject HSQOBJECT;
-typedef SQMemberHandle HSQMEMBERHANDLE;
-typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);
-typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size);
-typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/);
-typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);
-typedef void (*SQDEBUGHOOK)(HSQUIRRELVM /*v*/, SQInteger /*type*/, const SQChar * /*sourcename*/, SQInteger /*line*/, const SQChar * /*funcname*/);
-typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger);
-typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger);
-
-typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer);
-
-typedef struct tagSQRegFunction{
- const SQChar *name;
- SQFUNCTION f;
- SQInteger nparamscheck;
- const SQChar *typemask;
-}SQRegFunction;
-
-typedef struct tagSQFunctionInfo {
- SQUserPointer funcid;
- const SQChar *name;
- const SQChar *source;
-}SQFunctionInfo;
-
-/*vm*/
-SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize);
-SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize);
-SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v);
-SQUIRREL_API void sq_close(HSQUIRRELVM v);
-SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p);
-SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v);
-SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc);
-SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v);
-SQUIRREL_API SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror,SQBool throwerror);
-SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v);
-
-/*compiler*/
-SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror);
-SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror);
-SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable);
-SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable);
-SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f);
-
-/*stack operations*/
-SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop);
-SQUIRREL_API void sq_poptop(HSQUIRRELVM v);
-SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v);
-SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop);
-SQUIRREL_API SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize);
-SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v);
-SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx);
-
-/*object creation handling*/
-SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size);
-SQUIRREL_API void sq_newtable(HSQUIRRELVM v);
-SQUIRREL_API void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity);
-SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size);
-SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars);
-SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask);
-SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len);
-SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f);
-SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n);
-SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b);
-SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);
-SQUIRREL_API void sq_pushnull(HSQUIRRELVM v);
-SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b);
-SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c);
-SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i);
-SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f);
-SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b);
-SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread);
-SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p);
-SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag);
-SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag);
-SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag);
-SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook);
-SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize);
-SQUIRREL_API SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger idx,SQFunctionInfo *fi);
-SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars);
-SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name);
-SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p);
-SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag);
-SQUIRREL_API SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize);
-SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase);
-SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t);
-SQUIRREL_API SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle);
-SQUIRREL_API SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle);
-SQUIRREL_API SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle);
-
-/*object manipulation*/
-SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v);
-SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v);
-SQUIRREL_API void sq_pushconsttable(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_setconsttable(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic);
-SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
-SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
-SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
-SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize);
-SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx);
-SQUIRREL_API SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos);
-SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
-SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx);
-
-/*calls*/
-SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror);
-SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror);
-SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx);
-SQUIRREL_API SQRESULT sq_getcallee(HSQUIRRELVM v);
-SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
-SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err);
-SQUIRREL_API SQRESULT sq_throwobject(HSQUIRRELVM v);
-SQUIRREL_API void sq_reseterror(HSQUIRRELVM v);
-SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v);
-
-/*raw object handling*/
-SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po);
-SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj);
-SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po);
-SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po);
-SQUIRREL_API SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po);
-SQUIRREL_API void sq_resetobject(HSQOBJECT *po);
-SQUIRREL_API const SQChar *sq_objtostring(const HSQOBJECT *o);
-SQUIRREL_API SQBool sq_objtobool(const HSQOBJECT *o);
-SQUIRREL_API SQInteger sq_objtointeger(const HSQOBJECT *o);
-SQUIRREL_API SQFloat sq_objtofloat(const HSQOBJECT *o);
-SQUIRREL_API SQUserPointer sq_objtouserpointer(const HSQOBJECT *o);
-SQUIRREL_API SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag);
-
-/*GC*/
-SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_resurrectunreachable(HSQUIRRELVM v);
-
-/*serialization*/
-SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up);
-SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up);
-
-/*mem allocation*/
-SQUIRREL_API void *sq_malloc(SQUnsignedInteger size);
-SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize);
-SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size);
-
-/*debug*/
-SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si);
-SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v);
-SQUIRREL_API void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook);
-
-/*UTILITY MACRO*/
-#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC)
-#define sq_istable(o) ((o)._type==OT_TABLE)
-#define sq_isarray(o) ((o)._type==OT_ARRAY)
-#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO)
-#define sq_isclosure(o) ((o)._type==OT_CLOSURE)
-#define sq_isgenerator(o) ((o)._type==OT_GENERATOR)
-#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE)
-#define sq_isstring(o) ((o)._type==OT_STRING)
-#define sq_isinteger(o) ((o)._type==OT_INTEGER)
-#define sq_isfloat(o) ((o)._type==OT_FLOAT)
-#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER)
-#define sq_isuserdata(o) ((o)._type==OT_USERDATA)
-#define sq_isthread(o) ((o)._type==OT_THREAD)
-#define sq_isnull(o) ((o)._type==OT_NULL)
-#define sq_isclass(o) ((o)._type==OT_CLASS)
-#define sq_isinstance(o) ((o)._type==OT_INSTANCE)
-#define sq_isbool(o) ((o)._type==OT_BOOL)
-#define sq_isweakref(o) ((o)._type==OT_WEAKREF)
-#define sq_type(o) ((o)._type)
-
-/* deprecated */
-#define sq_createslot(v,n) sq_newslot(v,n,SQFalse)
-
-#define SQ_OK (0)
-#define SQ_ERROR (-1)
-
-#define SQ_FAILED(res) (res<0)
-#define SQ_SUCCEEDED(res) (res>=0)
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQUIRREL_H_*/
+/* +Copyright (c) 2003-2011 Alberto Demichelis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +#ifndef _SQUIRREL_H_ +#define _SQUIRREL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SQUIRREL_API +#define SQUIRREL_API extern +#endif + +#if (defined(_WIN64) || defined(_LP64)) +#ifndef _SQ64 +#define _SQ64 +#endif +#endif + +#ifdef _SQ64 + +#ifdef _MSC_VER +typedef __int64 SQInteger; +typedef unsigned __int64 SQUnsignedInteger; +typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/ +#else +typedef long long SQInteger; +typedef unsigned long long SQUnsignedInteger; +typedef unsigned long long SQHash; /*should be the same size of a pointer*/ +#endif +typedef int SQInt32; +typedef unsigned int SQUnsignedInteger32; +#else +typedef int SQInteger; +typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/ +typedef unsigned int SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/ +typedef unsigned int SQUnsignedInteger; +typedef unsigned int SQHash; /*should be the same size of a pointer*/ +#endif + + +#ifdef SQUSEDOUBLE +typedef double SQFloat; +#else +typedef float SQFloat; +#endif + +#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64) +#ifdef _MSC_VER +typedef __int64 SQRawObjectVal; //must be 64bits +#else +typedef long long SQRawObjectVal; //must be 64bits +#endif +#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; } +#else +typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise +#define SQ_OBJECT_RAWINIT() +#endif + +#ifndef SQ_ALIGNMENT // SQ_ALIGNMENT shall be less than or equal to SQ_MALLOC alignments, and its value shall be power of 2. +#if defined(SQUSEDOUBLE) || defined(_SQ64) +#define SQ_ALIGNMENT 8 +#else +#define SQ_ALIGNMENT 4 +#endif +#endif + +typedef void* SQUserPointer; +typedef SQUnsignedInteger SQBool; +typedef SQInteger SQRESULT; + +#define SQTrue (1) +#define SQFalse (0) + +struct SQVM; +struct SQTable; +struct SQArray; +struct SQString; +struct SQClosure; +struct SQGenerator; +struct SQNativeClosure; +struct SQUserData; +struct SQFunctionProto; +struct SQRefCounted; +struct SQClass; +struct SQInstance; +struct SQDelegable; +struct SQOuter; + +#ifdef _UNICODE +#define SQUNICODE +#endif + +#ifdef SQUNICODE +#if (defined(_MSC_VER) && _MSC_VER >= 1400) // 1400 = VS8 + +#if !defined(_NATIVE_WCHAR_T_DEFINED) //this is if the compiler considers wchar_t as native type +#define wchar_t unsigned short +#endif + +#else +typedef unsigned short wchar_t; +#endif + +typedef wchar_t SQChar; +#define _SC(a) L##a +#define scstrcmp wcscmp +#define scsprintf swprintf +#define scstrlen wcslen +#define scstrtod wcstod +#ifdef _SQ64 +#define scstrtol _wcstoi64 +#else +#define scstrtol wcstol +#endif +#define scatoi _wtoi +#define scstrtoul wcstoul +#define scvsprintf vswprintf +#define scstrstr wcsstr +#define scisspace iswspace +#define scisdigit iswdigit +#define scisxdigit iswxdigit +#define scisalpha iswalpha +#define sciscntrl iswcntrl +#define scisalnum iswalnum +#define scprintf wprintf +#define MAX_CHAR 0xFFFF +#else +typedef char SQChar; +#define _SC(a) a +#define scstrcmp strcmp +#define scsprintf sprintf +#define scstrlen strlen +#define scstrtod strtod +#ifdef _SQ64 +#ifdef _MSC_VER +#define scstrtol _strtoi64 +#else +#define scstrtol strtoll +#endif +#else +#define scstrtol strtol +#endif +#define scatoi atoi +#define scstrtoul strtoul +#define scvsprintf vsprintf +#define scstrstr strstr +#define scisspace isspace +#define scisdigit isdigit +#define scisxdigit isxdigit +#define sciscntrl iscntrl +#define scisalpha isalpha +#define scisalnum isalnum +#define scprintf printf +#define MAX_CHAR 0xFF +#endif + +#ifdef _SQ64 +#define _PRINT_INT_PREC _SC("ll") +#define _PRINT_INT_FMT _SC("%lld") +#else +#define _PRINT_INT_FMT _SC("%d") +#endif + +#define SQUIRREL_VERSION _SC("Squirrel 3.0.1 stable") +#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2011 Alberto Demichelis") +#define SQUIRREL_AUTHOR _SC("Alberto Demichelis") +#define SQUIRREL_VERSION_NUMBER 301 + +#define SQ_VMSTATE_IDLE 0 +#define SQ_VMSTATE_RUNNING 1 +#define SQ_VMSTATE_SUSPENDED 2 + +#define SQUIRREL_EOB 0 +#define SQ_BYTECODE_STREAM_TAG 0xFAFA + +#define SQOBJECT_REF_COUNTED 0x08000000 +#define SQOBJECT_NUMERIC 0x04000000 +#define SQOBJECT_DELEGABLE 0x02000000 +#define SQOBJECT_CANBEFALSE 0x01000000 + +#define SQ_MATCHTYPEMASKSTRING (-99999) + +#define _RT_MASK 0x00FFFFFF +#define _RAW_TYPE(type) (type&_RT_MASK) + +#define _RT_NULL 0x00000001 +#define _RT_INTEGER 0x00000002 +#define _RT_FLOAT 0x00000004 +#define _RT_BOOL 0x00000008 +#define _RT_STRING 0x00000010 +#define _RT_TABLE 0x00000020 +#define _RT_ARRAY 0x00000040 +#define _RT_USERDATA 0x00000080 +#define _RT_CLOSURE 0x00000100 +#define _RT_NATIVECLOSURE 0x00000200 +#define _RT_GENERATOR 0x00000400 +#define _RT_USERPOINTER 0x00000800 +#define _RT_THREAD 0x00001000 +#define _RT_FUNCPROTO 0x00002000 +#define _RT_CLASS 0x00004000 +#define _RT_INSTANCE 0x00008000 +#define _RT_WEAKREF 0x00010000 +#define _RT_OUTER 0x00020000 + +typedef enum tagSQObjectType{ + OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE), + OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE), + OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE), + OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE), + OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED), + OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), + OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED), + OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), + OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED), + OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED), + OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED), + OT_USERPOINTER = _RT_USERPOINTER, + OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) , + OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only + OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED), + OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), + OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED), + OT_OUTER = (_RT_OUTER|SQOBJECT_REF_COUNTED) //internal usage only +}SQObjectType; + +#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED) + + +typedef union tagSQObjectValue +{ + struct SQTable *pTable; + struct SQArray *pArray; + struct SQClosure *pClosure; + struct SQOuter *pOuter; + struct SQGenerator *pGenerator; + struct SQNativeClosure *pNativeClosure; + struct SQString *pString; + struct SQUserData *pUserData; + SQInteger nInteger; + SQFloat fFloat; + SQUserPointer pUserPointer; + struct SQFunctionProto *pFunctionProto; + struct SQRefCounted *pRefCounted; + struct SQDelegable *pDelegable; + struct SQVM *pThread; + struct SQClass *pClass; + struct SQInstance *pInstance; + struct SQWeakRef *pWeakRef; + SQRawObjectVal raw; +}SQObjectValue; + + +typedef struct tagSQObject +{ + SQObjectType _type; + SQObjectValue _unVal; +}SQObject; + +typedef struct tagSQMemberHandle{ + SQBool _static; + SQInteger _index; +}SQMemberHandle; + +typedef struct tagSQStackInfos{ + const SQChar* funcname; + const SQChar* source; + SQInteger line; +}SQStackInfos; + +typedef struct SQVM* HSQUIRRELVM; +typedef SQObject HSQOBJECT; +typedef SQMemberHandle HSQMEMBERHANDLE; +typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM); +typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size); +typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/); +typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...); +typedef void (*SQDEBUGHOOK)(HSQUIRRELVM /*v*/, SQInteger /*type*/, const SQChar * /*sourcename*/, SQInteger /*line*/, const SQChar * /*funcname*/); +typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger); +typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger); + +typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer); + +typedef struct tagSQRegFunction{ + const SQChar *name; + SQFUNCTION f; + SQInteger nparamscheck; + const SQChar *typemask; +}SQRegFunction; + +typedef struct tagSQFunctionInfo { + SQUserPointer funcid; + const SQChar *name; + const SQChar *source; +}SQFunctionInfo; + +/*vm*/ +SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize); +SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize); +SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v); +SQUIRREL_API void sq_close(HSQUIRRELVM v); +SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p); +SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v); +SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc); +SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v); +SQUIRREL_API SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror,SQBool throwerror); +SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v); + +/*compiler*/ +SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror); +SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror); +SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable); +SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable); +SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f); + +/*stack operations*/ +SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop); +SQUIRREL_API void sq_poptop(HSQUIRRELVM v); +SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v); +SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop); +SQUIRREL_API SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize); +SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v); +SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx); + +/*object creation handling*/ +SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size); +SQUIRREL_API void sq_newtable(HSQUIRRELVM v); +SQUIRREL_API void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity); +SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size); +SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars); +SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask); +SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len); +SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f); +SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n); +SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b); +SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p); +SQUIRREL_API void sq_pushnull(HSQUIRRELVM v); +SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b); +SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c); +SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i); +SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f); +SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b); +SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread); +SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p); +SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag); +SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag); +SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag); +SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook); +SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize); +SQUIRREL_API SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger idx,SQFunctionInfo *fi); +SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars); +SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name); +SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p); +SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag); +SQUIRREL_API SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize); +SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase); +SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t); +SQUIRREL_API SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle); +SQUIRREL_API SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle); +SQUIRREL_API SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle); + +/*object manipulation*/ +SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v); +SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v); +SQUIRREL_API void sq_pushconsttable(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_setconsttable(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic); +SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval); +SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval); +SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval); +SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize); +SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx); +SQUIRREL_API SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos); +SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval); +SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx); + +/*calls*/ +SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror); +SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror); +SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx); +SQUIRREL_API SQRESULT sq_getcallee(HSQUIRRELVM v); +SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval); +SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err); +SQUIRREL_API SQRESULT sq_throwobject(HSQUIRRELVM v); +SQUIRREL_API void sq_reseterror(HSQUIRRELVM v); +SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v); + +/*raw object handling*/ +SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po); +SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj); +SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po); +SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po); +SQUIRREL_API SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po); +SQUIRREL_API void sq_resetobject(HSQOBJECT *po); +SQUIRREL_API const SQChar *sq_objtostring(const HSQOBJECT *o); +SQUIRREL_API SQBool sq_objtobool(const HSQOBJECT *o); +SQUIRREL_API SQInteger sq_objtointeger(const HSQOBJECT *o); +SQUIRREL_API SQFloat sq_objtofloat(const HSQOBJECT *o); +SQUIRREL_API SQUserPointer sq_objtouserpointer(const HSQOBJECT *o); +SQUIRREL_API SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag); + +/*GC*/ +SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_resurrectunreachable(HSQUIRRELVM v); + +/*serialization*/ +SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up); +SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up); + +/*mem allocation*/ +SQUIRREL_API void *sq_malloc(SQUnsignedInteger size); +SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize); +SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size); + +/*debug*/ +SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si); +SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v); +SQUIRREL_API void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook); + +/*UTILITY MACRO*/ +#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC) +#define sq_istable(o) ((o)._type==OT_TABLE) +#define sq_isarray(o) ((o)._type==OT_ARRAY) +#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO) +#define sq_isclosure(o) ((o)._type==OT_CLOSURE) +#define sq_isgenerator(o) ((o)._type==OT_GENERATOR) +#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE) +#define sq_isstring(o) ((o)._type==OT_STRING) +#define sq_isinteger(o) ((o)._type==OT_INTEGER) +#define sq_isfloat(o) ((o)._type==OT_FLOAT) +#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER) +#define sq_isuserdata(o) ((o)._type==OT_USERDATA) +#define sq_isthread(o) ((o)._type==OT_THREAD) +#define sq_isnull(o) ((o)._type==OT_NULL) +#define sq_isclass(o) ((o)._type==OT_CLASS) +#define sq_isinstance(o) ((o)._type==OT_INSTANCE) +#define sq_isbool(o) ((o)._type==OT_BOOL) +#define sq_isweakref(o) ((o)._type==OT_WEAKREF) +#define sq_type(o) ((o)._type) + +/* deprecated */ +#define sq_createslot(v,n) sq_newslot(v,n,SQFalse) + +#define SQ_OK (0) +#define SQ_ERROR (-1) + +#define SQ_FAILED(res) (res<0) +#define SQ_SUCCEEDED(res) (res>=0) + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQUIRREL_H_*/ diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp index e115770a8..804a1e4d1 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp @@ -1,129 +1,129 @@ -/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <sqstdaux.h>
-#include <assert.h>
-
-void sqstd_printcallstack(HSQUIRRELVM v)
-{
- SQPRINTFUNCTION pf = sq_geterrorfunc(v);
- if(pf) {
- SQStackInfos si;
- SQInteger i;
- SQFloat f;
- const SQChar *s;
- SQInteger level=1; //1 is to skip this function that is level 0
- const SQChar *name=0;
- SQInteger seq=0;
- pf(v,_SC("\nCALLSTACK\n"));
- while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
- {
- const SQChar *fn=_SC("unknown");
- const SQChar *src=_SC("unknown");
- if(si.funcname)fn=si.funcname;
- if(si.source)src=si.source;
- pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
- level++;
- }
- level=0;
- pf(v,_SC("\nLOCALS\n"));
-
- for(level=0;level<10;level++){
- seq=0;
- while((name = sq_getlocal(v,level,seq)))
- {
- seq++;
- switch(sq_gettype(v,-1))
- {
- case OT_NULL:
- pf(v,_SC("[%s] NULL\n"),name);
- break;
- case OT_INTEGER:
- sq_getinteger(v,-1,&i);
- pf(v,_SC("[%s] %d\n"),name,i);
- break;
- case OT_FLOAT:
- sq_getfloat(v,-1,&f);
- pf(v,_SC("[%s] %.14g\n"),name,f);
- break;
- case OT_USERPOINTER:
- pf(v,_SC("[%s] USERPOINTER\n"),name);
- break;
- case OT_STRING:
- sq_getstring(v,-1,&s);
- pf(v,_SC("[%s] \"%s\"\n"),name,s);
- break;
- case OT_TABLE:
- pf(v,_SC("[%s] TABLE\n"),name);
- break;
- case OT_ARRAY:
- pf(v,_SC("[%s] ARRAY\n"),name);
- break;
- case OT_CLOSURE:
- pf(v,_SC("[%s] CLOSURE\n"),name);
- break;
- case OT_NATIVECLOSURE:
- pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
- break;
- case OT_GENERATOR:
- pf(v,_SC("[%s] GENERATOR\n"),name);
- break;
- case OT_USERDATA:
- pf(v,_SC("[%s] USERDATA\n"),name);
- break;
- case OT_THREAD:
- pf(v,_SC("[%s] THREAD\n"),name);
- break;
- case OT_CLASS:
- pf(v,_SC("[%s] CLASS\n"),name);
- break;
- case OT_INSTANCE:
- pf(v,_SC("[%s] INSTANCE\n"),name);
- break;
- case OT_WEAKREF:
- pf(v,_SC("[%s] WEAKREF\n"),name);
- break;
- case OT_BOOL:{
- sq_getinteger(v,-1,&i);
- pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false"));
- }
- break;
- default: assert(0); break;
- }
- sq_pop(v,1);
- }
- }
- }
-}
-
-static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)
-{
- SQPRINTFUNCTION pf = sq_geterrorfunc(v);
- if(pf) {
- const SQChar *sErr = 0;
- if(sq_gettop(v)>=1) {
- if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
- pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
- }
- else{
- pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
- }
- sqstd_printcallstack(v);
- }
- }
- return 0;
-}
-
-void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column)
-{
- SQPRINTFUNCTION pf = sq_geterrorfunc(v);
- if(pf) {
- pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr);
- }
-}
-
-void sqstd_seterrorhandlers(HSQUIRRELVM v)
-{
- sq_setcompilererrorhandler(v,_sqstd_compiler_error);
- sq_newclosure(v,_sqstd_aux_printerror,0);
- sq_seterrorhandler(v);
-}
+/* see copyright notice in squirrel.h */ +#include <squirrel.h> +#include <sqstdaux.h> +#include <assert.h> + +void sqstd_printcallstack(HSQUIRRELVM v) +{ + SQPRINTFUNCTION pf = sq_geterrorfunc(v); + if(pf) { + SQStackInfos si; + SQInteger i; + SQFloat f; + const SQChar *s; + SQInteger level=1; //1 is to skip this function that is level 0 + const SQChar *name=0; + SQInteger seq=0; + pf(v,_SC("\nCALLSTACK\n")); + while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si))) + { + const SQChar *fn=_SC("unknown"); + const SQChar *src=_SC("unknown"); + if(si.funcname)fn=si.funcname; + if(si.source)src=si.source; + pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line); + level++; + } + level=0; + pf(v,_SC("\nLOCALS\n")); + + for(level=0;level<10;level++){ + seq=0; + while((name = sq_getlocal(v,level,seq))) + { + seq++; + switch(sq_gettype(v,-1)) + { + case OT_NULL: + pf(v,_SC("[%s] NULL\n"),name); + break; + case OT_INTEGER: + sq_getinteger(v,-1,&i); + pf(v,_SC("[%s] %d\n"),name,i); + break; + case OT_FLOAT: + sq_getfloat(v,-1,&f); + pf(v,_SC("[%s] %.14g\n"),name,f); + break; + case OT_USERPOINTER: + pf(v,_SC("[%s] USERPOINTER\n"),name); + break; + case OT_STRING: + sq_getstring(v,-1,&s); + pf(v,_SC("[%s] \"%s\"\n"),name,s); + break; + case OT_TABLE: + pf(v,_SC("[%s] TABLE\n"),name); + break; + case OT_ARRAY: + pf(v,_SC("[%s] ARRAY\n"),name); + break; + case OT_CLOSURE: + pf(v,_SC("[%s] CLOSURE\n"),name); + break; + case OT_NATIVECLOSURE: + pf(v,_SC("[%s] NATIVECLOSURE\n"),name); + break; + case OT_GENERATOR: + pf(v,_SC("[%s] GENERATOR\n"),name); + break; + case OT_USERDATA: + pf(v,_SC("[%s] USERDATA\n"),name); + break; + case OT_THREAD: + pf(v,_SC("[%s] THREAD\n"),name); + break; + case OT_CLASS: + pf(v,_SC("[%s] CLASS\n"),name); + break; + case OT_INSTANCE: + pf(v,_SC("[%s] INSTANCE\n"),name); + break; + case OT_WEAKREF: + pf(v,_SC("[%s] WEAKREF\n"),name); + break; + case OT_BOOL:{ + sq_getinteger(v,-1,&i); + pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false")); + } + break; + default: assert(0); break; + } + sq_pop(v,1); + } + } + } +} + +static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v) +{ + SQPRINTFUNCTION pf = sq_geterrorfunc(v); + if(pf) { + const SQChar *sErr = 0; + if(sq_gettop(v)>=1) { + if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) { + pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr); + } + else{ + pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n")); + } + sqstd_printcallstack(v); + } + } + return 0; +} + +void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column) +{ + SQPRINTFUNCTION pf = sq_geterrorfunc(v); + if(pf) { + pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr); + } +} + +void sqstd_seterrorhandlers(HSQUIRRELVM v) +{ + sq_setcompilererrorhandler(v,_sqstd_compiler_error); + sq_newclosure(v,_sqstd_aux_printerror,0); + sq_seterrorhandler(v); +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp index 11b593306..a856db5e7 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp @@ -1,275 +1,275 @@ -/* see copyright notice in squirrel.h */
-#include <new>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include <string.h>
-#include <sqstdblob.h>
-#include "sqstdstream.h"
-#include "sqstdblobimpl.h"
-
-#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002)
-
-//Blob
-
-
-#define SETUP_BLOB(v) \
- SQBlob *self = NULL; \
- { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \
- return SQ_ERROR; }
-
-
-static SQInteger _blob_resize(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger size;
- sq_getinteger(v,2,&size);
- if(!self->Resize(size))
- return sq_throwerror(v,_SC("resize failed"));
- return 0;
-}
-
-static void __swap_dword(unsigned int *n)
-{
- *n=(unsigned int)(((*n&0xFF000000)>>24) |
- ((*n&0x00FF0000)>>8) |
- ((*n&0x0000FF00)<<8) |
- ((*n&0x000000FF)<<24));
-}
-
-static void __swap_word(unsigned short *n)
-{
- *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
-}
-
-static SQInteger _blob_swap4(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger num=(self->Len()-(self->Len()%4))>>2;
- unsigned int *t=(unsigned int *)self->GetBuf();
- for(SQInteger i = 0; i < num; i++) {
- __swap_dword(&t[i]);
- }
- return 0;
-}
-
-static SQInteger _blob_swap2(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger num=(self->Len()-(self->Len()%2))>>1;
- unsigned short *t = (unsigned short *)self->GetBuf();
- for(SQInteger i = 0; i < num; i++) {
- __swap_word(&t[i]);
- }
- return 0;
-}
-
-static SQInteger _blob__set(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger idx,val;
- sq_getinteger(v,2,&idx);
- sq_getinteger(v,3,&val);
- if(idx < 0 || idx >= self->Len())
- return sq_throwerror(v,_SC("index out of range"));
- ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;
- sq_push(v,3);
- return 1;
-}
-
-static SQInteger _blob__get(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger idx;
- sq_getinteger(v,2,&idx);
- if(idx < 0 || idx >= self->Len())
- return sq_throwerror(v,_SC("index out of range"));
- sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);
- return 1;
-}
-
-static SQInteger _blob__nexti(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- if(sq_gettype(v,2) == OT_NULL) {
- sq_pushinteger(v, 0);
- return 1;
- }
- SQInteger idx;
- if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {
- if(idx+1 < self->Len()) {
- sq_pushinteger(v, idx+1);
- return 1;
- }
- sq_pushnull(v);
- return 1;
- }
- return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));
-}
-
-static SQInteger _blob__typeof(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("blob"),-1);
- return 1;
-}
-
-static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size)
-{
- SQBlob *self = (SQBlob*)p;
- self->~SQBlob();
- sq_free(self,sizeof(SQBlob));
- return 1;
-}
-
-static SQInteger _blob_constructor(HSQUIRRELVM v)
-{
- SQInteger nparam = sq_gettop(v);
- SQInteger size = 0;
- if(nparam == 2) {
- sq_getinteger(v, 2, &size);
- }
- if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));
- //SQBlob *b = new SQBlob(size);
-
- SQBlob *b = new (sq_malloc(sizeof(SQBlob)))SQBlob(size);
- if(SQ_FAILED(sq_setinstanceup(v,1,b))) {
- b->~SQBlob();
- sq_free(b,sizeof(SQBlob));
- return sq_throwerror(v, _SC("cannot create blob"));
- }
- sq_setreleasehook(v,1,_blob_releasehook);
- return 0;
-}
-
-static SQInteger _blob__cloned(HSQUIRRELVM v)
-{
- SQBlob *other = NULL;
- {
- if(SQ_FAILED(sq_getinstanceup(v,2,(SQUserPointer*)&other,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
- return SQ_ERROR;
- }
- //SQBlob *thisone = new SQBlob(other->Len());
- SQBlob *thisone = new (sq_malloc(sizeof(SQBlob)))SQBlob(other->Len());
- memcpy(thisone->GetBuf(),other->GetBuf(),thisone->Len());
- if(SQ_FAILED(sq_setinstanceup(v,1,thisone))) {
- thisone->~SQBlob();
- sq_free(thisone,sizeof(SQBlob));
- return sq_throwerror(v, _SC("cannot clone blob"));
- }
- sq_setreleasehook(v,1,_blob_releasehook);
- return 0;
-}
-
-#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck}
-static SQRegFunction _blob_methods[] = {
- _DECL_BLOB_FUNC(constructor,-1,_SC("xn")),
- _DECL_BLOB_FUNC(resize,2,_SC("xn")),
- _DECL_BLOB_FUNC(swap2,1,_SC("x")),
- _DECL_BLOB_FUNC(swap4,1,_SC("x")),
- _DECL_BLOB_FUNC(_set,3,_SC("xnn")),
- _DECL_BLOB_FUNC(_get,2,_SC("xn")),
- _DECL_BLOB_FUNC(_typeof,1,_SC("x")),
- _DECL_BLOB_FUNC(_nexti,2,_SC("x")),
- _DECL_BLOB_FUNC(_cloned,2,_SC("xx")),
- {0,0,0,0}
-};
-
-
-
-//GLOBAL FUNCTIONS
-
-static SQInteger _g_blob_casti2f(HSQUIRRELVM v)
-{
- SQInteger i;
- sq_getinteger(v,2,&i);
- sq_pushfloat(v,*((SQFloat *)&i));
- return 1;
-}
-
-static SQInteger _g_blob_castf2i(HSQUIRRELVM v)
-{
- SQFloat f;
- sq_getfloat(v,2,&f);
- sq_pushinteger(v,*((SQInteger *)&f));
- return 1;
-}
-
-static SQInteger _g_blob_swap2(HSQUIRRELVM v)
-{
- SQInteger i;
- sq_getinteger(v,2,&i);
- short s=(short)i;
- sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
- return 1;
-}
-
-static SQInteger _g_blob_swap4(HSQUIRRELVM v)
-{
- SQInteger i;
- sq_getinteger(v,2,&i);
- unsigned int t4 = (unsigned int)i;
- __swap_dword(&t4);
- sq_pushinteger(v,(SQInteger)t4);
- return 1;
-}
-
-static SQInteger _g_blob_swapfloat(HSQUIRRELVM v)
-{
- SQFloat f;
- sq_getfloat(v,2,&f);
- __swap_dword((unsigned int *)&f);
- sq_pushfloat(v,f);
- return 1;
-}
-
-#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck}
-static SQRegFunction bloblib_funcs[]={
- _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),
- {0,0}
-};
-
-SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr)
-{
- SQBlob *blob;
- if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
- return -1;
- *ptr = blob->GetBuf();
- return SQ_OK;
-}
-
-SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx)
-{
- SQBlob *blob;
- if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
- return -1;
- return blob->Len();
-}
-
-SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size)
-{
- SQInteger top = sq_gettop(v);
- sq_pushregistrytable(v);
- sq_pushstring(v,_SC("std_blob"),-1);
- if(SQ_SUCCEEDED(sq_get(v,-2))) {
- sq_remove(v,-2); //removes the registry
- sq_push(v,1); // push the this
- sq_pushinteger(v,size); //size
- SQBlob *blob = NULL;
- if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse))
- && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) {
- sq_remove(v,-2);
- return blob->GetBuf();
- }
- }
- sq_settop(v,top);
- return NULL;
-}
-
-SQRESULT sqstd_register_bloblib(HSQUIRRELVM v)
-{
- return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);
-}
-
+/* see copyright notice in squirrel.h */ +#include <new> +#include <squirrel.h> +#include <sqstdio.h> +#include <string.h> +#include <sqstdblob.h> +#include "sqstdstream.h" +#include "sqstdblobimpl.h" + +#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002) + +//Blob + + +#define SETUP_BLOB(v) \ + SQBlob *self = NULL; \ + { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \ + return SQ_ERROR; } + + +static SQInteger _blob_resize(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger size; + sq_getinteger(v,2,&size); + if(!self->Resize(size)) + return sq_throwerror(v,_SC("resize failed")); + return 0; +} + +static void __swap_dword(unsigned int *n) +{ + *n=(unsigned int)(((*n&0xFF000000)>>24) | + ((*n&0x00FF0000)>>8) | + ((*n&0x0000FF00)<<8) | + ((*n&0x000000FF)<<24)); +} + +static void __swap_word(unsigned short *n) +{ + *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00); +} + +static SQInteger _blob_swap4(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger num=(self->Len()-(self->Len()%4))>>2; + unsigned int *t=(unsigned int *)self->GetBuf(); + for(SQInteger i = 0; i < num; i++) { + __swap_dword(&t[i]); + } + return 0; +} + +static SQInteger _blob_swap2(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger num=(self->Len()-(self->Len()%2))>>1; + unsigned short *t = (unsigned short *)self->GetBuf(); + for(SQInteger i = 0; i < num; i++) { + __swap_word(&t[i]); + } + return 0; +} + +static SQInteger _blob__set(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger idx,val; + sq_getinteger(v,2,&idx); + sq_getinteger(v,3,&val); + if(idx < 0 || idx >= self->Len()) + return sq_throwerror(v,_SC("index out of range")); + ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val; + sq_push(v,3); + return 1; +} + +static SQInteger _blob__get(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger idx; + sq_getinteger(v,2,&idx); + if(idx < 0 || idx >= self->Len()) + return sq_throwerror(v,_SC("index out of range")); + sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]); + return 1; +} + +static SQInteger _blob__nexti(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + if(sq_gettype(v,2) == OT_NULL) { + sq_pushinteger(v, 0); + return 1; + } + SQInteger idx; + if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) { + if(idx+1 < self->Len()) { + sq_pushinteger(v, idx+1); + return 1; + } + sq_pushnull(v); + return 1; + } + return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type")); +} + +static SQInteger _blob__typeof(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("blob"),-1); + return 1; +} + +static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size) +{ + SQBlob *self = (SQBlob*)p; + self->~SQBlob(); + sq_free(self,sizeof(SQBlob)); + return 1; +} + +static SQInteger _blob_constructor(HSQUIRRELVM v) +{ + SQInteger nparam = sq_gettop(v); + SQInteger size = 0; + if(nparam == 2) { + sq_getinteger(v, 2, &size); + } + if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size")); + //SQBlob *b = new SQBlob(size); + + SQBlob *b = new (sq_malloc(sizeof(SQBlob)))SQBlob(size); + if(SQ_FAILED(sq_setinstanceup(v,1,b))) { + b->~SQBlob(); + sq_free(b,sizeof(SQBlob)); + return sq_throwerror(v, _SC("cannot create blob")); + } + sq_setreleasehook(v,1,_blob_releasehook); + return 0; +} + +static SQInteger _blob__cloned(HSQUIRRELVM v) +{ + SQBlob *other = NULL; + { + if(SQ_FAILED(sq_getinstanceup(v,2,(SQUserPointer*)&other,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return SQ_ERROR; + } + //SQBlob *thisone = new SQBlob(other->Len()); + SQBlob *thisone = new (sq_malloc(sizeof(SQBlob)))SQBlob(other->Len()); + memcpy(thisone->GetBuf(),other->GetBuf(),thisone->Len()); + if(SQ_FAILED(sq_setinstanceup(v,1,thisone))) { + thisone->~SQBlob(); + sq_free(thisone,sizeof(SQBlob)); + return sq_throwerror(v, _SC("cannot clone blob")); + } + sq_setreleasehook(v,1,_blob_releasehook); + return 0; +} + +#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck} +static SQRegFunction _blob_methods[] = { + _DECL_BLOB_FUNC(constructor,-1,_SC("xn")), + _DECL_BLOB_FUNC(resize,2,_SC("xn")), + _DECL_BLOB_FUNC(swap2,1,_SC("x")), + _DECL_BLOB_FUNC(swap4,1,_SC("x")), + _DECL_BLOB_FUNC(_set,3,_SC("xnn")), + _DECL_BLOB_FUNC(_get,2,_SC("xn")), + _DECL_BLOB_FUNC(_typeof,1,_SC("x")), + _DECL_BLOB_FUNC(_nexti,2,_SC("x")), + _DECL_BLOB_FUNC(_cloned,2,_SC("xx")), + {0,0,0,0} +}; + + + +//GLOBAL FUNCTIONS + +static SQInteger _g_blob_casti2f(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + sq_pushfloat(v,*((SQFloat *)&i)); + return 1; +} + +static SQInteger _g_blob_castf2i(HSQUIRRELVM v) +{ + SQFloat f; + sq_getfloat(v,2,&f); + sq_pushinteger(v,*((SQInteger *)&f)); + return 1; +} + +static SQInteger _g_blob_swap2(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + short s=(short)i; + sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF)); + return 1; +} + +static SQInteger _g_blob_swap4(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + unsigned int t4 = (unsigned int)i; + __swap_dword(&t4); + sq_pushinteger(v,(SQInteger)t4); + return 1; +} + +static SQInteger _g_blob_swapfloat(HSQUIRRELVM v) +{ + SQFloat f; + sq_getfloat(v,2,&f); + __swap_dword((unsigned int *)&f); + sq_pushfloat(v,f); + return 1; +} + +#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck} +static SQRegFunction bloblib_funcs[]={ + _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")), + {0,0} +}; + +SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr) +{ + SQBlob *blob; + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return -1; + *ptr = blob->GetBuf(); + return SQ_OK; +} + +SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx) +{ + SQBlob *blob; + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return -1; + return blob->Len(); +} + +SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size) +{ + SQInteger top = sq_gettop(v); + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_blob"),-1); + if(SQ_SUCCEEDED(sq_get(v,-2))) { + sq_remove(v,-2); //removes the registry + sq_push(v,1); // push the this + sq_pushinteger(v,size); //size + SQBlob *blob = NULL; + if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse)) + && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) { + sq_remove(v,-2); + return blob->GetBuf(); + } + } + sq_settop(v,top); + return NULL; +} + +SQRESULT sqstd_register_bloblib(HSQUIRRELVM v) +{ + return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs); +} + diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdblobimpl.h b/squirrel_3_0_1_stable/sqstdlib/sqstdblobimpl.h index b2291b73c..9f22c0ae2 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdblobimpl.h +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdblobimpl.h @@ -1,108 +1,108 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_BLOBIMPL_H_
-#define _SQSTD_BLOBIMPL_H_
-
-struct SQBlob : public SQStream
-{
- SQBlob(SQInteger size) {
- _size = size;
- _allocated = size;
- _buf = (unsigned char *)sq_malloc(size);
- memset(_buf, 0, _size);
- _ptr = 0;
- _owns = true;
- }
- virtual ~SQBlob() {
- sq_free(_buf, _allocated);
- }
- SQInteger Write(void *buffer, SQInteger size) {
- if(!CanAdvance(size)) {
- GrowBufOf(_ptr + size - _size);
- }
- memcpy(&_buf[_ptr], buffer, size);
- _ptr += size;
- return size;
- }
- SQInteger Read(void *buffer,SQInteger size) {
- SQInteger n = size;
- if(!CanAdvance(size)) {
- if((_size - _ptr) > 0)
- n = _size - _ptr;
- else return 0;
- }
- memcpy(buffer, &_buf[_ptr], n);
- _ptr += n;
- return n;
- }
- bool Resize(SQInteger n) {
- if(!_owns) return false;
- if(n != _allocated) {
- unsigned char *newbuf = (unsigned char *)sq_malloc(n);
- memset(newbuf,0,n);
- if(_size > n)
- memcpy(newbuf,_buf,n);
- else
- memcpy(newbuf,_buf,_size);
- sq_free(_buf,_allocated);
- _buf=newbuf;
- _allocated = n;
- if(_size > _allocated)
- _size = _allocated;
- if(_ptr > _allocated)
- _ptr = _allocated;
- }
- return true;
- }
- bool GrowBufOf(SQInteger n)
- {
- bool ret = true;
- if(_size + n > _allocated) {
- if(_size + n > _size * 2)
- ret = Resize(_size + n);
- else
- ret = Resize(_size * 2);
- }
- _size = _size + n;
- return ret;
- }
- bool CanAdvance(SQInteger n) {
- if(_ptr+n>_size)return false;
- return true;
- }
- SQInteger Seek(SQInteger offset, SQInteger origin) {
- switch(origin) {
- case SQ_SEEK_SET:
- if(offset > _size || offset < 0) return -1;
- _ptr = offset;
- break;
- case SQ_SEEK_CUR:
- if(_ptr + offset > _size || _ptr + offset < 0) return -1;
- _ptr += offset;
- break;
- case SQ_SEEK_END:
- if(_size + offset > _size || _size + offset < 0) return -1;
- _ptr = _size + offset;
- break;
- default: return -1;
- }
- return 0;
- }
- bool IsValid() {
- return _buf?true:false;
- }
- bool EOS() {
- return _ptr == _size;
- }
- SQInteger Flush() { return 0; }
- SQInteger Tell() { return _ptr; }
- SQInteger Len() { return _size; }
- SQUserPointer GetBuf(){ return _buf; }
-private:
- SQInteger _size;
- SQInteger _allocated;
- SQInteger _ptr;
- unsigned char *_buf;
- bool _owns;
-};
-
-#endif //_SQSTD_BLOBIMPL_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_BLOBIMPL_H_ +#define _SQSTD_BLOBIMPL_H_ + +struct SQBlob : public SQStream +{ + SQBlob(SQInteger size) { + _size = size; + _allocated = size; + _buf = (unsigned char *)sq_malloc(size); + memset(_buf, 0, _size); + _ptr = 0; + _owns = true; + } + virtual ~SQBlob() { + sq_free(_buf, _allocated); + } + SQInteger Write(void *buffer, SQInteger size) { + if(!CanAdvance(size)) { + GrowBufOf(_ptr + size - _size); + } + memcpy(&_buf[_ptr], buffer, size); + _ptr += size; + return size; + } + SQInteger Read(void *buffer,SQInteger size) { + SQInteger n = size; + if(!CanAdvance(size)) { + if((_size - _ptr) > 0) + n = _size - _ptr; + else return 0; + } + memcpy(buffer, &_buf[_ptr], n); + _ptr += n; + return n; + } + bool Resize(SQInteger n) { + if(!_owns) return false; + if(n != _allocated) { + unsigned char *newbuf = (unsigned char *)sq_malloc(n); + memset(newbuf,0,n); + if(_size > n) + memcpy(newbuf,_buf,n); + else + memcpy(newbuf,_buf,_size); + sq_free(_buf,_allocated); + _buf=newbuf; + _allocated = n; + if(_size > _allocated) + _size = _allocated; + if(_ptr > _allocated) + _ptr = _allocated; + } + return true; + } + bool GrowBufOf(SQInteger n) + { + bool ret = true; + if(_size + n > _allocated) { + if(_size + n > _size * 2) + ret = Resize(_size + n); + else + ret = Resize(_size * 2); + } + _size = _size + n; + return ret; + } + bool CanAdvance(SQInteger n) { + if(_ptr+n>_size)return false; + return true; + } + SQInteger Seek(SQInteger offset, SQInteger origin) { + switch(origin) { + case SQ_SEEK_SET: + if(offset > _size || offset < 0) return -1; + _ptr = offset; + break; + case SQ_SEEK_CUR: + if(_ptr + offset > _size || _ptr + offset < 0) return -1; + _ptr += offset; + break; + case SQ_SEEK_END: + if(_size + offset > _size || _size + offset < 0) return -1; + _ptr = _size + offset; + break; + default: return -1; + } + return 0; + } + bool IsValid() { + return _buf?true:false; + } + bool EOS() { + return _ptr == _size; + } + SQInteger Flush() { return 0; } + SQInteger Tell() { return _ptr; } + SQInteger Len() { return _size; } + SQUserPointer GetBuf(){ return _buf; } +private: + SQInteger _size; + SQInteger _allocated; + SQInteger _ptr; + unsigned char *_buf; + bool _owns; +}; + +#endif //_SQSTD_BLOBIMPL_H_ diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp index 241864bb2..cd88bb0b7 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp @@ -1,419 +1,419 @@ -/* see copyright notice in squirrel.h */
-#include <new>
-#include <stdio.h>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include "sqstdstream.h"
-
-#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001)
-//basic API
-SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)
-{
-#ifndef SQUNICODE
- return (SQFILE)fopen(filename,mode);
-#else
- return (SQFILE)_wfopen(filename,mode);
-#endif
-}
-
-SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)
-{
- return (SQInteger)fread(buffer,size,count,(FILE *)file);
-}
-
-SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)
-{
- return (SQInteger)fwrite(buffer,size,count,(FILE *)file);
-}
-
-SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin)
-{
- SQInteger realorigin;
- switch(origin) {
- case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;
- case SQ_SEEK_END: realorigin = SEEK_END; break;
- case SQ_SEEK_SET: realorigin = SEEK_SET; break;
- default: return -1; //failed
- }
- return fseek((FILE *)file,(long)offset,(int)realorigin);
-}
-
-SQInteger sqstd_ftell(SQFILE file)
-{
- return ftell((FILE *)file);
-}
-
-SQInteger sqstd_fflush(SQFILE file)
-{
- return fflush((FILE *)file);
-}
-
-SQInteger sqstd_fclose(SQFILE file)
-{
- return fclose((FILE *)file);
-}
-
-SQInteger sqstd_feof(SQFILE file)
-{
- return feof((FILE *)file);
-}
-
-//File
-struct SQFile : public SQStream {
- SQFile() { _handle = NULL; _owns = false;}
- SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}
- virtual ~SQFile() { Close(); }
- bool Open(const SQChar *filename ,const SQChar *mode) {
- Close();
- if( (_handle = sqstd_fopen(filename,mode)) ) {
- _owns = true;
- return true;
- }
- return false;
- }
- void Close() {
- if(_handle && _owns) {
- sqstd_fclose(_handle);
- _handle = NULL;
- _owns = false;
- }
- }
- SQInteger Read(void *buffer,SQInteger size) {
- return sqstd_fread(buffer,1,size,_handle);
- }
- SQInteger Write(void *buffer,SQInteger size) {
- return sqstd_fwrite(buffer,1,size,_handle);
- }
- SQInteger Flush() {
- return sqstd_fflush(_handle);
- }
- SQInteger Tell() {
- return sqstd_ftell(_handle);
- }
- SQInteger Len() {
- SQInteger prevpos=Tell();
- Seek(0,SQ_SEEK_END);
- SQInteger size=Tell();
- Seek(prevpos,SQ_SEEK_SET);
- return size;
- }
- SQInteger Seek(SQInteger offset, SQInteger origin) {
- return sqstd_fseek(_handle,offset,origin);
- }
- bool IsValid() { return _handle?true:false; }
- bool EOS() { return Tell()==Len()?true:false;}
- SQFILE GetHandle() {return _handle;}
-private:
- SQFILE _handle;
- bool _owns;
-};
-
-static SQInteger _file__typeof(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("file"),-1);
- return 1;
-}
-
-static SQInteger _file_releasehook(SQUserPointer p, SQInteger size)
-{
- SQFile *self = (SQFile*)p;
- self->~SQFile();
- sq_free(self,sizeof(SQFile));
- return 1;
-}
-
-static SQInteger _file_constructor(HSQUIRRELVM v)
-{
- const SQChar *filename,*mode;
- bool owns = true;
- SQFile *f;
- SQFILE newf;
- if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {
- sq_getstring(v, 2, &filename);
- sq_getstring(v, 3, &mode);
- newf = sqstd_fopen(filename, mode);
- if(!newf) return sq_throwerror(v, _SC("cannot open file"));
- } else if(sq_gettype(v,2) == OT_USERPOINTER) {
- owns = !(sq_gettype(v,3) == OT_NULL);
- sq_getuserpointer(v,2,&newf);
- } else {
- return sq_throwerror(v,_SC("wrong parameter"));
- }
-
- f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns);
- if(SQ_FAILED(sq_setinstanceup(v,1,f))) {
- f->~SQFile();
- sq_free(f,sizeof(SQFile));
- return sq_throwerror(v, _SC("cannot create blob with negative size"));
- }
- sq_setreleasehook(v,1,_file_releasehook);
- return 0;
-}
-
-//bindings
-#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}
-static SQRegFunction _file_methods[] = {
- _DECL_FILE_FUNC(constructor,3,_SC("x")),
- _DECL_FILE_FUNC(_typeof,1,_SC("x")),
- {0,0,0,0},
-};
-
-
-
-SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)
-{
- SQInteger top = sq_gettop(v);
- sq_pushregistrytable(v);
- sq_pushstring(v,_SC("std_file"),-1);
- if(SQ_SUCCEEDED(sq_get(v,-2))) {
- sq_remove(v,-2); //removes the registry
- sq_pushroottable(v); // push the this
- sq_pushuserpointer(v,file); //file
- if(own){
- sq_pushinteger(v,1); //true
- }
- else{
- sq_pushnull(v); //false
- }
- if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) {
- sq_remove(v,-2);
- return SQ_OK;
- }
- }
- sq_settop(v,top);
- return SQ_OK;
-}
-
-SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file)
-{
- SQFile *fileobj = NULL;
- if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) {
- *file = fileobj->GetHandle();
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("not a file"));
-}
-
-
-
-static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer file)
-{
- SQInteger ret;
- char c;
- if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
- return c;
- return 0;
-}
-
-#ifdef SQUNICODE
-static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file)
-{
-#define READ() \
- if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \
- return 0;
-
- static const SQInteger utf8_lengths[16] =
- {
- 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */
- 0,0,0,0, /* 1000 to 1011 : not valid */
- 2,2, /* 1100, 1101 : 2 bytes */
- 3, /* 1110 : 3 bytes */
- 4 /* 1111 :4 bytes */
- };
- static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07};
- unsigned char inchar;
- SQInteger c = 0;
- READ();
- c = inchar;
- //
- if(c >= 0x80) {
- SQInteger tmp;
- SQInteger codelen = utf8_lengths[c>>4];
- if(codelen == 0)
- return 0;
- //"invalid UTF-8 stream";
- tmp = c&byte_masks[codelen];
- for(SQInteger n = 0; n < codelen-1; n++) {
- tmp<<=6;
- READ();
- tmp |= inchar & 0x3F;
- }
- c = tmp;
- }
- return c;
-}
-#endif
-
-static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file)
-{
- SQInteger ret;
- wchar_t c;
- if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
- return (SQChar)c;
- return 0;
-}
-
-static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file)
-{
- SQInteger ret;
- unsigned short c;
- if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) {
- c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);
- return (SQChar)c;
- }
- return 0;
-}
-
-SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size)
-{
- SQInteger ret;
- if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;
- return -1;
-}
-
-SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size)
-{
- return sqstd_fwrite(p,1,size,(SQFILE)file);
-}
-
-SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)
-{
- SQFILE file = sqstd_fopen(filename,_SC("rb"));
- SQInteger ret;
- unsigned short us;
- unsigned char uc;
- SQLEXREADFUNC func = _io_file_lexfeed_PLAIN;
- if(file){
- ret = sqstd_fread(&us,1,2,file);
- if(ret != 2) {
- //probably an empty file
- us = 0;
- }
- if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE
- sqstd_fseek(file,0,SQ_SEEK_SET);
- if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {
- sqstd_fclose(file);
- return SQ_OK;
- }
- }
- else { //SCRIPT
- switch(us)
- {
- //gotta swap the next 2 lines on BIG endian machines
- case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian;
- case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian;
- case 0xBBEF:
- if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) {
- sqstd_fclose(file);
- return sq_throwerror(v,_SC("io error"));
- }
- if(uc != 0xBF) {
- sqstd_fclose(file);
- return sq_throwerror(v,_SC("Unrecognozed ecoding"));
- }
-#ifdef SQUNICODE
- func = _io_file_lexfeed_UTF8;
-#else
- func = _io_file_lexfeed_PLAIN;
-#endif
- break;//UTF-8 ;
- default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii
- }
-
- if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){
- sqstd_fclose(file);
- return SQ_OK;
- }
- }
- sqstd_fclose(file);
- return SQ_ERROR;
- }
- return sq_throwerror(v,_SC("cannot open the file"));
-}
-
-SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror)
-{
- if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {
- sq_push(v,-2);
- if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) {
- sq_remove(v,retval?-2:-1); //removes the closure
- return 1;
- }
- sq_pop(v,1); //removes the closure
- }
- return SQ_ERROR;
-}
-
-SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename)
-{
- SQFILE file = sqstd_fopen(filename,_SC("wb+"));
- if(!file) return sq_throwerror(v,_SC("cannot open the file"));
- if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {
- sqstd_fclose(file);
- return SQ_OK;
- }
- sqstd_fclose(file);
- return SQ_ERROR; //forward the error
-}
-
-SQInteger _g_io_loadfile(HSQUIRRELVM v)
-{
- const SQChar *filename;
- SQBool printerror = SQFalse;
- sq_getstring(v,2,&filename);
- if(sq_gettop(v) >= 3) {
- sq_getbool(v,3,&printerror);
- }
- if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))
- return 1;
- return SQ_ERROR; //propagates the error
-}
-
-SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v)
-{
- const SQChar *filename;
- sq_getstring(v,2,&filename);
- if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename)))
- return 1;
- return SQ_ERROR; //propagates the error
-}
-
-SQInteger _g_io_dofile(HSQUIRRELVM v)
-{
- const SQChar *filename;
- SQBool printerror = SQFalse;
- sq_getstring(v,2,&filename);
- if(sq_gettop(v) >= 3) {
- sq_getbool(v,3,&printerror);
- }
- sq_push(v,1); //repush the this
- if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))
- return 1;
- return SQ_ERROR; //propagates the error
-}
-
-#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}
-static SQRegFunction iolib_funcs[]={
- _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),
- _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),
- _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")),
- {0,0}
-};
-
-SQRESULT sqstd_register_iolib(HSQUIRRELVM v)
-{
- SQInteger top = sq_gettop(v);
- //create delegate
- declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);
- sq_pushstring(v,_SC("stdout"),-1);
- sqstd_createfile(v,stdout,SQFalse);
- sq_newslot(v,-3,SQFalse);
- sq_pushstring(v,_SC("stdin"),-1);
- sqstd_createfile(v,stdin,SQFalse);
- sq_newslot(v,-3,SQFalse);
- sq_pushstring(v,_SC("stderr"),-1);
- sqstd_createfile(v,stderr,SQFalse);
- sq_newslot(v,-3,SQFalse);
- sq_settop(v,top);
- return SQ_OK;
-}
+/* see copyright notice in squirrel.h */ +#include <new> +#include <stdio.h> +#include <squirrel.h> +#include <sqstdio.h> +#include "sqstdstream.h" + +#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001) +//basic API +SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode) +{ +#ifndef SQUNICODE + return (SQFILE)fopen(filename,mode); +#else + return (SQFILE)_wfopen(filename,mode); +#endif +} + +SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file) +{ + return (SQInteger)fread(buffer,size,count,(FILE *)file); +} + +SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file) +{ + return (SQInteger)fwrite(buffer,size,count,(FILE *)file); +} + +SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin) +{ + SQInteger realorigin; + switch(origin) { + case SQ_SEEK_CUR: realorigin = SEEK_CUR; break; + case SQ_SEEK_END: realorigin = SEEK_END; break; + case SQ_SEEK_SET: realorigin = SEEK_SET; break; + default: return -1; //failed + } + return fseek((FILE *)file,(long)offset,(int)realorigin); +} + +SQInteger sqstd_ftell(SQFILE file) +{ + return ftell((FILE *)file); +} + +SQInteger sqstd_fflush(SQFILE file) +{ + return fflush((FILE *)file); +} + +SQInteger sqstd_fclose(SQFILE file) +{ + return fclose((FILE *)file); +} + +SQInteger sqstd_feof(SQFILE file) +{ + return feof((FILE *)file); +} + +//File +struct SQFile : public SQStream { + SQFile() { _handle = NULL; _owns = false;} + SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;} + virtual ~SQFile() { Close(); } + bool Open(const SQChar *filename ,const SQChar *mode) { + Close(); + if( (_handle = sqstd_fopen(filename,mode)) ) { + _owns = true; + return true; + } + return false; + } + void Close() { + if(_handle && _owns) { + sqstd_fclose(_handle); + _handle = NULL; + _owns = false; + } + } + SQInteger Read(void *buffer,SQInteger size) { + return sqstd_fread(buffer,1,size,_handle); + } + SQInteger Write(void *buffer,SQInteger size) { + return sqstd_fwrite(buffer,1,size,_handle); + } + SQInteger Flush() { + return sqstd_fflush(_handle); + } + SQInteger Tell() { + return sqstd_ftell(_handle); + } + SQInteger Len() { + SQInteger prevpos=Tell(); + Seek(0,SQ_SEEK_END); + SQInteger size=Tell(); + Seek(prevpos,SQ_SEEK_SET); + return size; + } + SQInteger Seek(SQInteger offset, SQInteger origin) { + return sqstd_fseek(_handle,offset,origin); + } + bool IsValid() { return _handle?true:false; } + bool EOS() { return Tell()==Len()?true:false;} + SQFILE GetHandle() {return _handle;} +private: + SQFILE _handle; + bool _owns; +}; + +static SQInteger _file__typeof(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("file"),-1); + return 1; +} + +static SQInteger _file_releasehook(SQUserPointer p, SQInteger size) +{ + SQFile *self = (SQFile*)p; + self->~SQFile(); + sq_free(self,sizeof(SQFile)); + return 1; +} + +static SQInteger _file_constructor(HSQUIRRELVM v) +{ + const SQChar *filename,*mode; + bool owns = true; + SQFile *f; + SQFILE newf; + if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) { + sq_getstring(v, 2, &filename); + sq_getstring(v, 3, &mode); + newf = sqstd_fopen(filename, mode); + if(!newf) return sq_throwerror(v, _SC("cannot open file")); + } else if(sq_gettype(v,2) == OT_USERPOINTER) { + owns = !(sq_gettype(v,3) == OT_NULL); + sq_getuserpointer(v,2,&newf); + } else { + return sq_throwerror(v,_SC("wrong parameter")); + } + + f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns); + if(SQ_FAILED(sq_setinstanceup(v,1,f))) { + f->~SQFile(); + sq_free(f,sizeof(SQFile)); + return sq_throwerror(v, _SC("cannot create blob with negative size")); + } + sq_setreleasehook(v,1,_file_releasehook); + return 0; +} + +//bindings +#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck} +static SQRegFunction _file_methods[] = { + _DECL_FILE_FUNC(constructor,3,_SC("x")), + _DECL_FILE_FUNC(_typeof,1,_SC("x")), + {0,0,0,0}, +}; + + + +SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own) +{ + SQInteger top = sq_gettop(v); + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_file"),-1); + if(SQ_SUCCEEDED(sq_get(v,-2))) { + sq_remove(v,-2); //removes the registry + sq_pushroottable(v); // push the this + sq_pushuserpointer(v,file); //file + if(own){ + sq_pushinteger(v,1); //true + } + else{ + sq_pushnull(v); //false + } + if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) { + sq_remove(v,-2); + return SQ_OK; + } + } + sq_settop(v,top); + return SQ_OK; +} + +SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file) +{ + SQFile *fileobj = NULL; + if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) { + *file = fileobj->GetHandle(); + return SQ_OK; + } + return sq_throwerror(v,_SC("not a file")); +} + + + +static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer file) +{ + SQInteger ret; + char c; + if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) + return c; + return 0; +} + +#ifdef SQUNICODE +static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file) +{ +#define READ() \ + if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \ + return 0; + + static const SQInteger utf8_lengths[16] = + { + 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */ + 0,0,0,0, /* 1000 to 1011 : not valid */ + 2,2, /* 1100, 1101 : 2 bytes */ + 3, /* 1110 : 3 bytes */ + 4 /* 1111 :4 bytes */ + }; + static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07}; + unsigned char inchar; + SQInteger c = 0; + READ(); + c = inchar; + // + if(c >= 0x80) { + SQInteger tmp; + SQInteger codelen = utf8_lengths[c>>4]; + if(codelen == 0) + return 0; + //"invalid UTF-8 stream"; + tmp = c&byte_masks[codelen]; + for(SQInteger n = 0; n < codelen-1; n++) { + tmp<<=6; + READ(); + tmp |= inchar & 0x3F; + } + c = tmp; + } + return c; +} +#endif + +static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file) +{ + SQInteger ret; + wchar_t c; + if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) + return (SQChar)c; + return 0; +} + +static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file) +{ + SQInteger ret; + unsigned short c; + if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) { + c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00); + return (SQChar)c; + } + return 0; +} + +SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size) +{ + SQInteger ret; + if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret; + return -1; +} + +SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size) +{ + return sqstd_fwrite(p,1,size,(SQFILE)file); +} + +SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror) +{ + SQFILE file = sqstd_fopen(filename,_SC("rb")); + SQInteger ret; + unsigned short us; + unsigned char uc; + SQLEXREADFUNC func = _io_file_lexfeed_PLAIN; + if(file){ + ret = sqstd_fread(&us,1,2,file); + if(ret != 2) { + //probably an empty file + us = 0; + } + if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE + sqstd_fseek(file,0,SQ_SEEK_SET); + if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) { + sqstd_fclose(file); + return SQ_OK; + } + } + else { //SCRIPT + switch(us) + { + //gotta swap the next 2 lines on BIG endian machines + case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian; + case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian; + case 0xBBEF: + if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { + sqstd_fclose(file); + return sq_throwerror(v,_SC("io error")); + } + if(uc != 0xBF) { + sqstd_fclose(file); + return sq_throwerror(v,_SC("Unrecognozed ecoding")); + } +#ifdef SQUNICODE + func = _io_file_lexfeed_UTF8; +#else + func = _io_file_lexfeed_PLAIN; +#endif + break;//UTF-8 ; + default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii + } + + if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){ + sqstd_fclose(file); + return SQ_OK; + } + } + sqstd_fclose(file); + return SQ_ERROR; + } + return sq_throwerror(v,_SC("cannot open the file")); +} + +SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror) +{ + if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) { + sq_push(v,-2); + if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) { + sq_remove(v,retval?-2:-1); //removes the closure + return 1; + } + sq_pop(v,1); //removes the closure + } + return SQ_ERROR; +} + +SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename) +{ + SQFILE file = sqstd_fopen(filename,_SC("wb+")); + if(!file) return sq_throwerror(v,_SC("cannot open the file")); + if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) { + sqstd_fclose(file); + return SQ_OK; + } + sqstd_fclose(file); + return SQ_ERROR; //forward the error +} + +SQInteger _g_io_loadfile(HSQUIRRELVM v) +{ + const SQChar *filename; + SQBool printerror = SQFalse; + sq_getstring(v,2,&filename); + if(sq_gettop(v) >= 3) { + sq_getbool(v,3,&printerror); + } + if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) + return 1; + return SQ_ERROR; //propagates the error +} + +SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v) +{ + const SQChar *filename; + sq_getstring(v,2,&filename); + if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename))) + return 1; + return SQ_ERROR; //propagates the error +} + +SQInteger _g_io_dofile(HSQUIRRELVM v) +{ + const SQChar *filename; + SQBool printerror = SQFalse; + sq_getstring(v,2,&filename); + if(sq_gettop(v) >= 3) { + sq_getbool(v,3,&printerror); + } + sq_push(v,1); //repush the this + if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror))) + return 1; + return SQ_ERROR; //propagates the error +} + +#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck} +static SQRegFunction iolib_funcs[]={ + _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")), + _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")), + _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")), + {0,0} +}; + +SQRESULT sqstd_register_iolib(HSQUIRRELVM v) +{ + SQInteger top = sq_gettop(v); + //create delegate + declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs); + sq_pushstring(v,_SC("stdout"),-1); + sqstd_createfile(v,stdout,SQFalse); + sq_newslot(v,-3,SQFalse); + sq_pushstring(v,_SC("stdin"),-1); + sqstd_createfile(v,stdin,SQFalse); + sq_newslot(v,-3,SQFalse); + sq_pushstring(v,_SC("stderr"),-1); + sqstd_createfile(v,stderr,SQFalse); + sq_newslot(v,-3,SQFalse); + sq_settop(v,top); + return SQ_OK; +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp index ef50359bd..8d8a1917b 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp @@ -1,107 +1,107 @@ -/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <math.h>
-#include <stdlib.h>
-#include <sqstdmath.h>
-
-#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
- SQFloat f; \
- sq_getfloat(v,2,&f); \
- sq_pushfloat(v,(SQFloat)_funcname(f)); \
- return 1; \
-}
-
-#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
- SQFloat p1,p2; \
- sq_getfloat(v,2,&p1); \
- sq_getfloat(v,3,&p2); \
- sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \
- return 1; \
-}
-
-static SQInteger math_srand(HSQUIRRELVM v)
-{
- SQInteger i;
- if(SQ_FAILED(sq_getinteger(v,2,&i)))
- return sq_throwerror(v,_SC("invalid param"));
- srand((unsigned int)i);
- return 0;
-}
-
-static SQInteger math_rand(HSQUIRRELVM v)
-{
- sq_pushinteger(v,rand());
- return 1;
-}
-
-static SQInteger math_abs(HSQUIRRELVM v)
-{
- SQInteger n;
- sq_getinteger(v,2,&n);
- sq_pushinteger(v,(SQInteger)abs((int)n));
- return 1;
-}
-
-SINGLE_ARG_FUNC(sqrt)
-SINGLE_ARG_FUNC(fabs)
-SINGLE_ARG_FUNC(sin)
-SINGLE_ARG_FUNC(cos)
-SINGLE_ARG_FUNC(asin)
-SINGLE_ARG_FUNC(acos)
-SINGLE_ARG_FUNC(log)
-SINGLE_ARG_FUNC(log10)
-SINGLE_ARG_FUNC(tan)
-SINGLE_ARG_FUNC(atan)
-TWO_ARGS_FUNC(atan2)
-TWO_ARGS_FUNC(pow)
-SINGLE_ARG_FUNC(floor)
-SINGLE_ARG_FUNC(ceil)
-SINGLE_ARG_FUNC(exp)
-
-#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck}
-static SQRegFunction mathlib_funcs[] = {
- _DECL_FUNC(sqrt,2,_SC(".n")),
- _DECL_FUNC(sin,2,_SC(".n")),
- _DECL_FUNC(cos,2,_SC(".n")),
- _DECL_FUNC(asin,2,_SC(".n")),
- _DECL_FUNC(acos,2,_SC(".n")),
- _DECL_FUNC(log,2,_SC(".n")),
- _DECL_FUNC(log10,2,_SC(".n")),
- _DECL_FUNC(tan,2,_SC(".n")),
- _DECL_FUNC(atan,2,_SC(".n")),
- _DECL_FUNC(atan2,3,_SC(".nn")),
- _DECL_FUNC(pow,3,_SC(".nn")),
- _DECL_FUNC(floor,2,_SC(".n")),
- _DECL_FUNC(ceil,2,_SC(".n")),
- _DECL_FUNC(exp,2,_SC(".n")),
- _DECL_FUNC(srand,2,_SC(".n")),
- _DECL_FUNC(rand,1,NULL),
- _DECL_FUNC(fabs,2,_SC(".n")),
- _DECL_FUNC(abs,2,_SC(".n")),
- {0,0},
-};
-#undef _DECL_FUNC
-
-#ifndef M_PI
-#define M_PI (3.14159265358979323846)
-#endif
-
-SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
-{
- SQInteger i=0;
- while(mathlib_funcs[i].name!=0) {
- sq_pushstring(v,mathlib_funcs[i].name,-1);
- sq_newclosure(v,mathlib_funcs[i].f,0);
- sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
- sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);
- sq_newslot(v,-3,SQFalse);
- i++;
- }
- sq_pushstring(v,_SC("RAND_MAX"),-1);
- sq_pushinteger(v,RAND_MAX);
- sq_newslot(v,-3,SQFalse);
- sq_pushstring(v,_SC("PI"),-1);
- sq_pushfloat(v,(SQFloat)M_PI);
- sq_newslot(v,-3,SQFalse);
- return SQ_OK;
-}
+/* see copyright notice in squirrel.h */ +#include <squirrel.h> +#include <math.h> +#include <stdlib.h> +#include <sqstdmath.h> + +#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ + SQFloat f; \ + sq_getfloat(v,2,&f); \ + sq_pushfloat(v,(SQFloat)_funcname(f)); \ + return 1; \ +} + +#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ + SQFloat p1,p2; \ + sq_getfloat(v,2,&p1); \ + sq_getfloat(v,3,&p2); \ + sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \ + return 1; \ +} + +static SQInteger math_srand(HSQUIRRELVM v) +{ + SQInteger i; + if(SQ_FAILED(sq_getinteger(v,2,&i))) + return sq_throwerror(v,_SC("invalid param")); + srand((unsigned int)i); + return 0; +} + +static SQInteger math_rand(HSQUIRRELVM v) +{ + sq_pushinteger(v,rand()); + return 1; +} + +static SQInteger math_abs(HSQUIRRELVM v) +{ + SQInteger n; + sq_getinteger(v,2,&n); + sq_pushinteger(v,(SQInteger)abs((int)n)); + return 1; +} + +SINGLE_ARG_FUNC(sqrt) +SINGLE_ARG_FUNC(fabs) +SINGLE_ARG_FUNC(sin) +SINGLE_ARG_FUNC(cos) +SINGLE_ARG_FUNC(asin) +SINGLE_ARG_FUNC(acos) +SINGLE_ARG_FUNC(log) +SINGLE_ARG_FUNC(log10) +SINGLE_ARG_FUNC(tan) +SINGLE_ARG_FUNC(atan) +TWO_ARGS_FUNC(atan2) +TWO_ARGS_FUNC(pow) +SINGLE_ARG_FUNC(floor) +SINGLE_ARG_FUNC(ceil) +SINGLE_ARG_FUNC(exp) + +#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck} +static SQRegFunction mathlib_funcs[] = { + _DECL_FUNC(sqrt,2,_SC(".n")), + _DECL_FUNC(sin,2,_SC(".n")), + _DECL_FUNC(cos,2,_SC(".n")), + _DECL_FUNC(asin,2,_SC(".n")), + _DECL_FUNC(acos,2,_SC(".n")), + _DECL_FUNC(log,2,_SC(".n")), + _DECL_FUNC(log10,2,_SC(".n")), + _DECL_FUNC(tan,2,_SC(".n")), + _DECL_FUNC(atan,2,_SC(".n")), + _DECL_FUNC(atan2,3,_SC(".nn")), + _DECL_FUNC(pow,3,_SC(".nn")), + _DECL_FUNC(floor,2,_SC(".n")), + _DECL_FUNC(ceil,2,_SC(".n")), + _DECL_FUNC(exp,2,_SC(".n")), + _DECL_FUNC(srand,2,_SC(".n")), + _DECL_FUNC(rand,1,NULL), + _DECL_FUNC(fabs,2,_SC(".n")), + _DECL_FUNC(abs,2,_SC(".n")), + {0,0}, +}; +#undef _DECL_FUNC + +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + +SQRESULT sqstd_register_mathlib(HSQUIRRELVM v) +{ + SQInteger i=0; + while(mathlib_funcs[i].name!=0) { + sq_pushstring(v,mathlib_funcs[i].name,-1); + sq_newclosure(v,mathlib_funcs[i].f,0); + sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask); + sq_setnativeclosurename(v,-1,mathlib_funcs[i].name); + sq_newslot(v,-3,SQFalse); + i++; + } + sq_pushstring(v,_SC("RAND_MAX"),-1); + sq_pushinteger(v,RAND_MAX); + sq_newslot(v,-3,SQFalse); + sq_pushstring(v,_SC("PI"),-1); + sq_pushfloat(v,(SQFloat)M_PI); + sq_newslot(v,-3,SQFalse); + return SQ_OK; +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp index 921597fed..a044d19dc 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp @@ -1,638 +1,638 @@ -/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <string.h>
-#include <ctype.h>
-#include <setjmp.h>
-#include <sqstdstring.h>
-
-#ifdef _UINCODE
-#define scisprint iswprint
-#else
-#define scisprint isprint
-#endif
-
-#ifdef _DEBUG
-#include <stdio.h>
-
-static const SQChar *g_nnames[] =
-{
- _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"),
- _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"),
- _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"),
- _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB")
-};
-
-#endif
-
-#define OP_GREEDY (MAX_CHAR+1) // * + ? {n}
-#define OP_OR (MAX_CHAR+2)
-#define OP_EXPR (MAX_CHAR+3) //parentesis ()
-#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:)
-#define OP_DOT (MAX_CHAR+5)
-#define OP_CLASS (MAX_CHAR+6)
-#define OP_CCLASS (MAX_CHAR+7)
-#define OP_NCLASS (MAX_CHAR+8) //negates class the [^
-#define OP_RANGE (MAX_CHAR+9)
-#define OP_CHAR (MAX_CHAR+10)
-#define OP_EOL (MAX_CHAR+11)
-#define OP_BOL (MAX_CHAR+12)
-#define OP_WB (MAX_CHAR+13)
-
-#define SQREX_SYMBOL_ANY_CHAR ('.')
-#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+')
-#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*')
-#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?')
-#define SQREX_SYMBOL_BRANCH ('|')
-#define SQREX_SYMBOL_END_OF_STRING ('$')
-#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^')
-#define SQREX_SYMBOL_ESCAPE_CHAR ('\\')
-
-
-typedef int SQRexNodeType;
-
-typedef struct tagSQRexNode{
- SQRexNodeType type;
- SQInteger left;
- SQInteger right;
- SQInteger next;
-}SQRexNode;
-
-struct SQRex{
- const SQChar *_eol;
- const SQChar *_bol;
- const SQChar *_p;
- SQInteger _first;
- SQInteger _op;
- SQRexNode *_nodes;
- SQInteger _nallocated;
- SQInteger _nsize;
- SQInteger _nsubexpr;
- SQRexMatch *_matches;
- SQInteger _currsubexp;
- void *_jmpbuf;
- const SQChar **_error;
-};
-
-static SQInteger sqstd_rex_list(SQRex *exp);
-
-static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type)
-{
- SQRexNode n;
- n.type = type;
- n.next = n.right = n.left = -1;
- if(type == OP_EXPR)
- n.right = exp->_nsubexpr++;
- if(exp->_nallocated < (exp->_nsize + 1)) {
- SQInteger oldsize = exp->_nallocated;
- exp->_nallocated *= 2;
- exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode));
- }
- exp->_nodes[exp->_nsize++] = n;
- SQInteger newid = exp->_nsize - 1;
- return (SQInteger)newid;
-}
-
-static void sqstd_rex_error(SQRex *exp,const SQChar *error)
-{
- if(exp->_error) *exp->_error = error;
- longjmp(*((jmp_buf*)exp->_jmpbuf),-1);
-}
-
-static void sqstd_rex_expect(SQRex *exp, SQInteger n){
- if((*exp->_p) != n)
- sqstd_rex_error(exp, _SC("expected paren"));
- exp->_p++;
-}
-
-static SQChar sqstd_rex_escapechar(SQRex *exp)
-{
- if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){
- exp->_p++;
- switch(*exp->_p) {
- case 'v': exp->_p++; return '\v';
- case 'n': exp->_p++; return '\n';
- case 't': exp->_p++; return '\t';
- case 'r': exp->_p++; return '\r';
- case 'f': exp->_p++; return '\f';
- default: return (*exp->_p++);
- }
- } else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected"));
- return (*exp->_p++);
-}
-
-static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid)
-{
- SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS);
- exp->_nodes[n].left = classid;
- return n;
-}
-
-static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass)
-{
- SQChar t;
- if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) {
- exp->_p++;
- switch(*exp->_p) {
- case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n');
- case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t');
- case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r');
- case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f');
- case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v');
- case 'a': case 'A': case 'w': case 'W': case 's': case 'S':
- case 'd': case 'D': case 'x': case 'X': case 'c': case 'C':
- case 'p': case 'P': case 'l': case 'u':
- {
- t = *exp->_p; exp->_p++;
- return sqstd_rex_charclass(exp,t);
- }
- case 'b':
- case 'B':
- if(!isclass) {
- SQInteger node = sqstd_rex_newnode(exp,OP_WB);
- exp->_nodes[node].left = *exp->_p;
- exp->_p++;
- return node;
- } //else default
- default:
- t = *exp->_p; exp->_p++;
- return sqstd_rex_newnode(exp,t);
- }
- }
- else if(!scisprint(*exp->_p)) {
-
- sqstd_rex_error(exp,_SC("letter expected"));
- }
- t = *exp->_p; exp->_p++;
- return sqstd_rex_newnode(exp,t);
-}
-static SQInteger sqstd_rex_class(SQRex *exp)
-{
- SQInteger ret = -1;
- SQInteger first = -1,chain;
- if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){
- ret = sqstd_rex_newnode(exp,OP_NCLASS);
- exp->_p++;
- }else ret = sqstd_rex_newnode(exp,OP_CLASS);
-
- if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class"));
- chain = ret;
- while(*exp->_p != ']' && exp->_p != exp->_eol) {
- if(*exp->_p == '-' && first != -1){
- SQInteger r;
- if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range"));
- r = sqstd_rex_newnode(exp,OP_RANGE);
- if(exp->_nodes[first].type>*exp->_p) sqstd_rex_error(exp,_SC("invalid range"));
- if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges"));
- exp->_nodes[r].left = exp->_nodes[first].type;
- SQInteger t = sqstd_rex_escapechar(exp);
- exp->_nodes[r].right = t;
- exp->_nodes[chain].next = r;
- chain = r;
- first = -1;
- }
- else{
- if(first!=-1){
- SQInteger c = first;
- exp->_nodes[chain].next = c;
- chain = c;
- first = sqstd_rex_charnode(exp,SQTrue);
- }
- else{
- first = sqstd_rex_charnode(exp,SQTrue);
- }
- }
- }
- if(first!=-1){
- SQInteger c = first;
- exp->_nodes[chain].next = c;
- chain = c;
- first = -1;
- }
- /* hack? */
- exp->_nodes[ret].left = exp->_nodes[ret].next;
- exp->_nodes[ret].next = -1;
- return ret;
-}
-
-static SQInteger sqstd_rex_parsenumber(SQRex *exp)
-{
- SQInteger ret = *exp->_p-'0';
- SQInteger positions = 10;
- exp->_p++;
- while(isdigit(*exp->_p)) {
- ret = ret*10+(*exp->_p++-'0');
- if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant"));
- positions *= 10;
- };
- return ret;
-}
-
-static SQInteger sqstd_rex_element(SQRex *exp)
-{
- SQInteger ret = -1;
- switch(*exp->_p)
- {
- case '(': {
- SQInteger expr;
- exp->_p++;
-
-
- if(*exp->_p =='?') {
- exp->_p++;
- sqstd_rex_expect(exp,':');
- expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR);
- }
- else
- expr = sqstd_rex_newnode(exp,OP_EXPR);
- SQInteger newn = sqstd_rex_list(exp);
- exp->_nodes[expr].left = newn;
- ret = expr;
- sqstd_rex_expect(exp,')');
- }
- break;
- case '[':
- exp->_p++;
- ret = sqstd_rex_class(exp);
- sqstd_rex_expect(exp,']');
- break;
- case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break;
- case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break;
- default:
- ret = sqstd_rex_charnode(exp,SQFalse);
- break;
- }
-
-
- SQInteger op;
- SQBool isgreedy = SQFalse;
- unsigned short p0 = 0, p1 = 0;
- switch(*exp->_p){
- case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break;
- case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break;
- case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break;
- case '{':
- exp->_p++;
- if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected"));
- p0 = (unsigned short)sqstd_rex_parsenumber(exp);
- /*******************************/
- switch(*exp->_p) {
- case '}':
- p1 = p0; exp->_p++;
- break;
- case ',':
- exp->_p++;
- p1 = 0xFFFF;
- if(isdigit(*exp->_p)){
- p1 = (unsigned short)sqstd_rex_parsenumber(exp);
- }
- sqstd_rex_expect(exp,'}');
- break;
- default:
- sqstd_rex_error(exp,_SC(", or } expected"));
- }
- /*******************************/
- isgreedy = SQTrue;
- break;
-
- }
- if(isgreedy) {
- SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY);
- op = OP_GREEDY;
- exp->_nodes[nnode].left = ret;
- exp->_nodes[nnode].right = ((p0)<<16)|p1;
- ret = nnode;
- }
-
- if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) {
- SQInteger nnode = sqstd_rex_element(exp);
- exp->_nodes[ret].next = nnode;
- }
-
- return ret;
-}
-
-static SQInteger sqstd_rex_list(SQRex *exp)
-{
- SQInteger ret=-1,e;
- if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) {
- exp->_p++;
- ret = sqstd_rex_newnode(exp,OP_BOL);
- }
- e = sqstd_rex_element(exp);
- if(ret != -1) {
- exp->_nodes[ret].next = e;
- }
- else ret = e;
-
- if(*exp->_p == SQREX_SYMBOL_BRANCH) {
- SQInteger temp,tright;
- exp->_p++;
- temp = sqstd_rex_newnode(exp,OP_OR);
- exp->_nodes[temp].left = ret;
- tright = sqstd_rex_list(exp);
- exp->_nodes[temp].right = tright;
- ret = temp;
- }
- return ret;
-}
-
-static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c)
-{
- switch(cclass) {
- case 'a': return isalpha(c)?SQTrue:SQFalse;
- case 'A': return !isalpha(c)?SQTrue:SQFalse;
- case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse;
- case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse;
- case 's': return isspace(c)?SQTrue:SQFalse;
- case 'S': return !isspace(c)?SQTrue:SQFalse;
- case 'd': return isdigit(c)?SQTrue:SQFalse;
- case 'D': return !isdigit(c)?SQTrue:SQFalse;
- case 'x': return isxdigit(c)?SQTrue:SQFalse;
- case 'X': return !isxdigit(c)?SQTrue:SQFalse;
- case 'c': return iscntrl(c)?SQTrue:SQFalse;
- case 'C': return !iscntrl(c)?SQTrue:SQFalse;
- case 'p': return ispunct(c)?SQTrue:SQFalse;
- case 'P': return !ispunct(c)?SQTrue:SQFalse;
- case 'l': return islower(c)?SQTrue:SQFalse;
- case 'u': return isupper(c)?SQTrue:SQFalse;
- }
- return SQFalse; /*cannot happen*/
-}
-
-static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c)
-{
- do {
- switch(node->type) {
- case OP_RANGE:
- if(c >= node->left && c <= node->right) return SQTrue;
- break;
- case OP_CCLASS:
- if(sqstd_rex_matchcclass(node->left,c)) return SQTrue;
- break;
- default:
- if(c == node->type)return SQTrue;
- }
- } while((node->next != -1) && (node = &exp->_nodes[node->next]));
- return SQFalse;
-}
-
-static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next)
-{
-
- SQRexNodeType type = node->type;
- switch(type) {
- case OP_GREEDY: {
- //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL;
- SQRexNode *greedystop = NULL;
- SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0;
- const SQChar *s=str, *good = str;
-
- if(node->next != -1) {
- greedystop = &exp->_nodes[node->next];
- }
- else {
- greedystop = next;
- }
-
- while((nmaches == 0xFFFF || nmaches < p1)) {
-
- const SQChar *stop;
- if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop)))
- break;
- nmaches++;
- good=s;
- if(greedystop) {
- //checks that 0 matches satisfy the expression(if so skips)
- //if not would always stop(for instance if is a '?')
- if(greedystop->type != OP_GREEDY ||
- (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0))
- {
- SQRexNode *gnext = NULL;
- if(greedystop->next != -1) {
- gnext = &exp->_nodes[greedystop->next];
- }else if(next && next->next != -1){
- gnext = &exp->_nodes[next->next];
- }
- stop = sqstd_rex_matchnode(exp,greedystop,s,gnext);
- if(stop) {
- //if satisfied stop it
- if(p0 == p1 && p0 == nmaches) break;
- else if(nmaches >= p0 && p1 == 0xFFFF) break;
- else if(nmaches >= p0 && nmaches <= p1) break;
- }
- }
- }
-
- if(s >= exp->_eol)
- break;
- }
- if(p0 == p1 && p0 == nmaches) return good;
- else if(nmaches >= p0 && p1 == 0xFFFF) return good;
- else if(nmaches >= p0 && nmaches <= p1) return good;
- return NULL;
- }
- case OP_OR: {
- const SQChar *asd = str;
- SQRexNode *temp=&exp->_nodes[node->left];
- while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) {
- if(temp->next != -1)
- temp = &exp->_nodes[temp->next];
- else
- return asd;
- }
- asd = str;
- temp = &exp->_nodes[node->right];
- while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) {
- if(temp->next != -1)
- temp = &exp->_nodes[temp->next];
- else
- return asd;
- }
- return NULL;
- break;
- }
- case OP_EXPR:
- case OP_NOCAPEXPR:{
- SQRexNode *n = &exp->_nodes[node->left];
- const SQChar *cur = str;
- SQInteger capture = -1;
- if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) {
- capture = exp->_currsubexp;
- exp->_matches[capture].begin = cur;
- exp->_currsubexp++;
- }
- int tempcap = exp->_currsubexp;
- do {
- SQRexNode *subnext = NULL;
- if(n->next != -1) {
- subnext = &exp->_nodes[n->next];
- }else {
- subnext = next;
- }
- if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) {
- if(capture != -1){
- exp->_matches[capture].begin = 0;
- exp->_matches[capture].len = 0;
- }
- return NULL;
- }
- } while((n->next != -1) && (n = &exp->_nodes[n->next]));
-
- exp->_currsubexp = tempcap;
- if(capture != -1)
- exp->_matches[capture].len = cur - exp->_matches[capture].begin;
- return cur;
- }
- case OP_WB:
- if((str == exp->_bol && !isspace(*str))
- || (str == exp->_eol && !isspace(*(str-1)))
- || (!isspace(*str) && isspace(*(str+1)))
- || (isspace(*str) && !isspace(*(str+1))) ) {
- return (node->left == 'b')?str:NULL;
- }
- return (node->left == 'b')?NULL:str;
- case OP_BOL:
- if(str == exp->_bol) return str;
- return NULL;
- case OP_EOL:
- if(str == exp->_eol) return str;
- return NULL;
- case OP_DOT:{
- *str++;
- }
- return str;
- case OP_NCLASS:
- case OP_CLASS:
- if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) {
- *str++;
- return str;
- }
- return NULL;
- case OP_CCLASS:
- if(sqstd_rex_matchcclass(node->left,*str)) {
- *str++;
- return str;
- }
- return NULL;
- default: /* char */
- if(*str != node->type) return NULL;
- *str++;
- return str;
- }
- return NULL;
-}
-
-/* public api */
-SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error)
-{
- SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex));
- exp->_eol = exp->_bol = NULL;
- exp->_p = pattern;
- exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar);
- exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode));
- exp->_nsize = 0;
- exp->_matches = 0;
- exp->_nsubexpr = 0;
- exp->_first = sqstd_rex_newnode(exp,OP_EXPR);
- exp->_error = error;
- exp->_jmpbuf = sq_malloc(sizeof(jmp_buf));
- if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) {
- SQInteger res = sqstd_rex_list(exp);
- exp->_nodes[exp->_first].left = res;
- if(*exp->_p!='\0')
- sqstd_rex_error(exp,_SC("unexpected character"));
-#ifdef _DEBUG
- {
- SQInteger nsize,i;
- SQRexNode *t;
- nsize = exp->_nsize;
- t = &exp->_nodes[0];
- scprintf(_SC("\n"));
- for(i = 0;i < nsize; i++) {
- if(exp->_nodes[i].type>MAX_CHAR)
- scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]);
- else
- scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type);
- scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next);
- }
- scprintf(_SC("\n"));
- }
-#endif
- exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch));
- memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch));
- }
- else{
- sqstd_rex_free(exp);
- return NULL;
- }
- return exp;
-}
-
-void sqstd_rex_free(SQRex *exp)
-{
- if(exp) {
- if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode));
- if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf));
- if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch));
- sq_free(exp,sizeof(SQRex));
- }
-}
-
-SQBool sqstd_rex_match(SQRex* exp,const SQChar* text)
-{
- const SQChar* res = NULL;
- exp->_bol = text;
- exp->_eol = text + scstrlen(text);
- exp->_currsubexp = 0;
- res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL);
- if(res == NULL || res != exp->_eol)
- return SQFalse;
- return SQTrue;
-}
-
-SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end)
-{
- const SQChar *cur = NULL;
- SQInteger node = exp->_first;
- if(text_begin >= text_end) return SQFalse;
- exp->_bol = text_begin;
- exp->_eol = text_end;
- do {
- cur = text_begin;
- while(node != -1) {
- exp->_currsubexp = 0;
- cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL);
- if(!cur)
- break;
- node = exp->_nodes[node].next;
- }
- *text_begin++;
- } while(cur == NULL && text_begin != text_end);
-
- if(cur == NULL)
- return SQFalse;
-
- --text_begin;
-
- if(out_begin) *out_begin = text_begin;
- if(out_end) *out_end = cur;
- return SQTrue;
-}
-
-SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end)
-{
- return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end);
-}
-
-SQInteger sqstd_rex_getsubexpcount(SQRex* exp)
-{
- return exp->_nsubexpr;
-}
-
-SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp)
-{
- if( n<0 || n >= exp->_nsubexpr) return SQFalse;
- *subexp = exp->_matches[n];
- return SQTrue;
-}
-
+/* see copyright notice in squirrel.h */ +#include <squirrel.h> +#include <string.h> +#include <ctype.h> +#include <setjmp.h> +#include <sqstdstring.h> + +#ifdef _UINCODE +#define scisprint iswprint +#else +#define scisprint isprint +#endif + +#ifdef _DEBUG +#include <stdio.h> + +static const SQChar *g_nnames[] = +{ + _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"), + _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"), + _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"), + _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB") +}; + +#endif + +#define OP_GREEDY (MAX_CHAR+1) // * + ? {n} +#define OP_OR (MAX_CHAR+2) +#define OP_EXPR (MAX_CHAR+3) //parentesis () +#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:) +#define OP_DOT (MAX_CHAR+5) +#define OP_CLASS (MAX_CHAR+6) +#define OP_CCLASS (MAX_CHAR+7) +#define OP_NCLASS (MAX_CHAR+8) //negates class the [^ +#define OP_RANGE (MAX_CHAR+9) +#define OP_CHAR (MAX_CHAR+10) +#define OP_EOL (MAX_CHAR+11) +#define OP_BOL (MAX_CHAR+12) +#define OP_WB (MAX_CHAR+13) + +#define SQREX_SYMBOL_ANY_CHAR ('.') +#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') +#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*') +#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?') +#define SQREX_SYMBOL_BRANCH ('|') +#define SQREX_SYMBOL_END_OF_STRING ('$') +#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^') +#define SQREX_SYMBOL_ESCAPE_CHAR ('\\') + + +typedef int SQRexNodeType; + +typedef struct tagSQRexNode{ + SQRexNodeType type; + SQInteger left; + SQInteger right; + SQInteger next; +}SQRexNode; + +struct SQRex{ + const SQChar *_eol; + const SQChar *_bol; + const SQChar *_p; + SQInteger _first; + SQInteger _op; + SQRexNode *_nodes; + SQInteger _nallocated; + SQInteger _nsize; + SQInteger _nsubexpr; + SQRexMatch *_matches; + SQInteger _currsubexp; + void *_jmpbuf; + const SQChar **_error; +}; + +static SQInteger sqstd_rex_list(SQRex *exp); + +static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type) +{ + SQRexNode n; + n.type = type; + n.next = n.right = n.left = -1; + if(type == OP_EXPR) + n.right = exp->_nsubexpr++; + if(exp->_nallocated < (exp->_nsize + 1)) { + SQInteger oldsize = exp->_nallocated; + exp->_nallocated *= 2; + exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode)); + } + exp->_nodes[exp->_nsize++] = n; + SQInteger newid = exp->_nsize - 1; + return (SQInteger)newid; +} + +static void sqstd_rex_error(SQRex *exp,const SQChar *error) +{ + if(exp->_error) *exp->_error = error; + longjmp(*((jmp_buf*)exp->_jmpbuf),-1); +} + +static void sqstd_rex_expect(SQRex *exp, SQInteger n){ + if((*exp->_p) != n) + sqstd_rex_error(exp, _SC("expected paren")); + exp->_p++; +} + +static SQChar sqstd_rex_escapechar(SQRex *exp) +{ + if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){ + exp->_p++; + switch(*exp->_p) { + case 'v': exp->_p++; return '\v'; + case 'n': exp->_p++; return '\n'; + case 't': exp->_p++; return '\t'; + case 'r': exp->_p++; return '\r'; + case 'f': exp->_p++; return '\f'; + default: return (*exp->_p++); + } + } else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected")); + return (*exp->_p++); +} + +static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid) +{ + SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS); + exp->_nodes[n].left = classid; + return n; +} + +static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass) +{ + SQChar t; + if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) { + exp->_p++; + switch(*exp->_p) { + case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n'); + case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t'); + case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r'); + case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f'); + case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v'); + case 'a': case 'A': case 'w': case 'W': case 's': case 'S': + case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': + case 'p': case 'P': case 'l': case 'u': + { + t = *exp->_p; exp->_p++; + return sqstd_rex_charclass(exp,t); + } + case 'b': + case 'B': + if(!isclass) { + SQInteger node = sqstd_rex_newnode(exp,OP_WB); + exp->_nodes[node].left = *exp->_p; + exp->_p++; + return node; + } //else default + default: + t = *exp->_p; exp->_p++; + return sqstd_rex_newnode(exp,t); + } + } + else if(!scisprint(*exp->_p)) { + + sqstd_rex_error(exp,_SC("letter expected")); + } + t = *exp->_p; exp->_p++; + return sqstd_rex_newnode(exp,t); +} +static SQInteger sqstd_rex_class(SQRex *exp) +{ + SQInteger ret = -1; + SQInteger first = -1,chain; + if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){ + ret = sqstd_rex_newnode(exp,OP_NCLASS); + exp->_p++; + }else ret = sqstd_rex_newnode(exp,OP_CLASS); + + if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class")); + chain = ret; + while(*exp->_p != ']' && exp->_p != exp->_eol) { + if(*exp->_p == '-' && first != -1){ + SQInteger r; + if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range")); + r = sqstd_rex_newnode(exp,OP_RANGE); + if(exp->_nodes[first].type>*exp->_p) sqstd_rex_error(exp,_SC("invalid range")); + if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges")); + exp->_nodes[r].left = exp->_nodes[first].type; + SQInteger t = sqstd_rex_escapechar(exp); + exp->_nodes[r].right = t; + exp->_nodes[chain].next = r; + chain = r; + first = -1; + } + else{ + if(first!=-1){ + SQInteger c = first; + exp->_nodes[chain].next = c; + chain = c; + first = sqstd_rex_charnode(exp,SQTrue); + } + else{ + first = sqstd_rex_charnode(exp,SQTrue); + } + } + } + if(first!=-1){ + SQInteger c = first; + exp->_nodes[chain].next = c; + chain = c; + first = -1; + } + /* hack? */ + exp->_nodes[ret].left = exp->_nodes[ret].next; + exp->_nodes[ret].next = -1; + return ret; +} + +static SQInteger sqstd_rex_parsenumber(SQRex *exp) +{ + SQInteger ret = *exp->_p-'0'; + SQInteger positions = 10; + exp->_p++; + while(isdigit(*exp->_p)) { + ret = ret*10+(*exp->_p++-'0'); + if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant")); + positions *= 10; + }; + return ret; +} + +static SQInteger sqstd_rex_element(SQRex *exp) +{ + SQInteger ret = -1; + switch(*exp->_p) + { + case '(': { + SQInteger expr; + exp->_p++; + + + if(*exp->_p =='?') { + exp->_p++; + sqstd_rex_expect(exp,':'); + expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR); + } + else + expr = sqstd_rex_newnode(exp,OP_EXPR); + SQInteger newn = sqstd_rex_list(exp); + exp->_nodes[expr].left = newn; + ret = expr; + sqstd_rex_expect(exp,')'); + } + break; + case '[': + exp->_p++; + ret = sqstd_rex_class(exp); + sqstd_rex_expect(exp,']'); + break; + case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break; + case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break; + default: + ret = sqstd_rex_charnode(exp,SQFalse); + break; + } + + + SQInteger op; + SQBool isgreedy = SQFalse; + unsigned short p0 = 0, p1 = 0; + switch(*exp->_p){ + case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; + case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; + case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break; + case '{': + exp->_p++; + if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected")); + p0 = (unsigned short)sqstd_rex_parsenumber(exp); + /*******************************/ + switch(*exp->_p) { + case '}': + p1 = p0; exp->_p++; + break; + case ',': + exp->_p++; + p1 = 0xFFFF; + if(isdigit(*exp->_p)){ + p1 = (unsigned short)sqstd_rex_parsenumber(exp); + } + sqstd_rex_expect(exp,'}'); + break; + default: + sqstd_rex_error(exp,_SC(", or } expected")); + } + /*******************************/ + isgreedy = SQTrue; + break; + + } + if(isgreedy) { + SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY); + op = OP_GREEDY; + exp->_nodes[nnode].left = ret; + exp->_nodes[nnode].right = ((p0)<<16)|p1; + ret = nnode; + } + + if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) { + SQInteger nnode = sqstd_rex_element(exp); + exp->_nodes[ret].next = nnode; + } + + return ret; +} + +static SQInteger sqstd_rex_list(SQRex *exp) +{ + SQInteger ret=-1,e; + if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) { + exp->_p++; + ret = sqstd_rex_newnode(exp,OP_BOL); + } + e = sqstd_rex_element(exp); + if(ret != -1) { + exp->_nodes[ret].next = e; + } + else ret = e; + + if(*exp->_p == SQREX_SYMBOL_BRANCH) { + SQInteger temp,tright; + exp->_p++; + temp = sqstd_rex_newnode(exp,OP_OR); + exp->_nodes[temp].left = ret; + tright = sqstd_rex_list(exp); + exp->_nodes[temp].right = tright; + ret = temp; + } + return ret; +} + +static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c) +{ + switch(cclass) { + case 'a': return isalpha(c)?SQTrue:SQFalse; + case 'A': return !isalpha(c)?SQTrue:SQFalse; + case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse; + case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse; + case 's': return isspace(c)?SQTrue:SQFalse; + case 'S': return !isspace(c)?SQTrue:SQFalse; + case 'd': return isdigit(c)?SQTrue:SQFalse; + case 'D': return !isdigit(c)?SQTrue:SQFalse; + case 'x': return isxdigit(c)?SQTrue:SQFalse; + case 'X': return !isxdigit(c)?SQTrue:SQFalse; + case 'c': return iscntrl(c)?SQTrue:SQFalse; + case 'C': return !iscntrl(c)?SQTrue:SQFalse; + case 'p': return ispunct(c)?SQTrue:SQFalse; + case 'P': return !ispunct(c)?SQTrue:SQFalse; + case 'l': return islower(c)?SQTrue:SQFalse; + case 'u': return isupper(c)?SQTrue:SQFalse; + } + return SQFalse; /*cannot happen*/ +} + +static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c) +{ + do { + switch(node->type) { + case OP_RANGE: + if(c >= node->left && c <= node->right) return SQTrue; + break; + case OP_CCLASS: + if(sqstd_rex_matchcclass(node->left,c)) return SQTrue; + break; + default: + if(c == node->type)return SQTrue; + } + } while((node->next != -1) && (node = &exp->_nodes[node->next])); + return SQFalse; +} + +static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next) +{ + + SQRexNodeType type = node->type; + switch(type) { + case OP_GREEDY: { + //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL; + SQRexNode *greedystop = NULL; + SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0; + const SQChar *s=str, *good = str; + + if(node->next != -1) { + greedystop = &exp->_nodes[node->next]; + } + else { + greedystop = next; + } + + while((nmaches == 0xFFFF || nmaches < p1)) { + + const SQChar *stop; + if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop))) + break; + nmaches++; + good=s; + if(greedystop) { + //checks that 0 matches satisfy the expression(if so skips) + //if not would always stop(for instance if is a '?') + if(greedystop->type != OP_GREEDY || + (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0)) + { + SQRexNode *gnext = NULL; + if(greedystop->next != -1) { + gnext = &exp->_nodes[greedystop->next]; + }else if(next && next->next != -1){ + gnext = &exp->_nodes[next->next]; + } + stop = sqstd_rex_matchnode(exp,greedystop,s,gnext); + if(stop) { + //if satisfied stop it + if(p0 == p1 && p0 == nmaches) break; + else if(nmaches >= p0 && p1 == 0xFFFF) break; + else if(nmaches >= p0 && nmaches <= p1) break; + } + } + } + + if(s >= exp->_eol) + break; + } + if(p0 == p1 && p0 == nmaches) return good; + else if(nmaches >= p0 && p1 == 0xFFFF) return good; + else if(nmaches >= p0 && nmaches <= p1) return good; + return NULL; + } + case OP_OR: { + const SQChar *asd = str; + SQRexNode *temp=&exp->_nodes[node->left]; + while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { + if(temp->next != -1) + temp = &exp->_nodes[temp->next]; + else + return asd; + } + asd = str; + temp = &exp->_nodes[node->right]; + while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { + if(temp->next != -1) + temp = &exp->_nodes[temp->next]; + else + return asd; + } + return NULL; + break; + } + case OP_EXPR: + case OP_NOCAPEXPR:{ + SQRexNode *n = &exp->_nodes[node->left]; + const SQChar *cur = str; + SQInteger capture = -1; + if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) { + capture = exp->_currsubexp; + exp->_matches[capture].begin = cur; + exp->_currsubexp++; + } + int tempcap = exp->_currsubexp; + do { + SQRexNode *subnext = NULL; + if(n->next != -1) { + subnext = &exp->_nodes[n->next]; + }else { + subnext = next; + } + if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) { + if(capture != -1){ + exp->_matches[capture].begin = 0; + exp->_matches[capture].len = 0; + } + return NULL; + } + } while((n->next != -1) && (n = &exp->_nodes[n->next])); + + exp->_currsubexp = tempcap; + if(capture != -1) + exp->_matches[capture].len = cur - exp->_matches[capture].begin; + return cur; + } + case OP_WB: + if((str == exp->_bol && !isspace(*str)) + || (str == exp->_eol && !isspace(*(str-1))) + || (!isspace(*str) && isspace(*(str+1))) + || (isspace(*str) && !isspace(*(str+1))) ) { + return (node->left == 'b')?str:NULL; + } + return (node->left == 'b')?NULL:str; + case OP_BOL: + if(str == exp->_bol) return str; + return NULL; + case OP_EOL: + if(str == exp->_eol) return str; + return NULL; + case OP_DOT:{ + *str++; + } + return str; + case OP_NCLASS: + case OP_CLASS: + if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) { + *str++; + return str; + } + return NULL; + case OP_CCLASS: + if(sqstd_rex_matchcclass(node->left,*str)) { + *str++; + return str; + } + return NULL; + default: /* char */ + if(*str != node->type) return NULL; + *str++; + return str; + } + return NULL; +} + +/* public api */ +SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error) +{ + SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex)); + exp->_eol = exp->_bol = NULL; + exp->_p = pattern; + exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar); + exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode)); + exp->_nsize = 0; + exp->_matches = 0; + exp->_nsubexpr = 0; + exp->_first = sqstd_rex_newnode(exp,OP_EXPR); + exp->_error = error; + exp->_jmpbuf = sq_malloc(sizeof(jmp_buf)); + if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) { + SQInteger res = sqstd_rex_list(exp); + exp->_nodes[exp->_first].left = res; + if(*exp->_p!='\0') + sqstd_rex_error(exp,_SC("unexpected character")); +#ifdef _DEBUG + { + SQInteger nsize,i; + SQRexNode *t; + nsize = exp->_nsize; + t = &exp->_nodes[0]; + scprintf(_SC("\n")); + for(i = 0;i < nsize; i++) { + if(exp->_nodes[i].type>MAX_CHAR) + scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]); + else + scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type); + scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next); + } + scprintf(_SC("\n")); + } +#endif + exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch)); + memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch)); + } + else{ + sqstd_rex_free(exp); + return NULL; + } + return exp; +} + +void sqstd_rex_free(SQRex *exp) +{ + if(exp) { + if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode)); + if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf)); + if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch)); + sq_free(exp,sizeof(SQRex)); + } +} + +SQBool sqstd_rex_match(SQRex* exp,const SQChar* text) +{ + const SQChar* res = NULL; + exp->_bol = text; + exp->_eol = text + scstrlen(text); + exp->_currsubexp = 0; + res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL); + if(res == NULL || res != exp->_eol) + return SQFalse; + return SQTrue; +} + +SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end) +{ + const SQChar *cur = NULL; + SQInteger node = exp->_first; + if(text_begin >= text_end) return SQFalse; + exp->_bol = text_begin; + exp->_eol = text_end; + do { + cur = text_begin; + while(node != -1) { + exp->_currsubexp = 0; + cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL); + if(!cur) + break; + node = exp->_nodes[node].next; + } + *text_begin++; + } while(cur == NULL && text_begin != text_end); + + if(cur == NULL) + return SQFalse; + + --text_begin; + + if(out_begin) *out_begin = text_begin; + if(out_end) *out_end = cur; + return SQTrue; +} + +SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end) +{ + return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end); +} + +SQInteger sqstd_rex_getsubexpcount(SQRex* exp) +{ + return exp->_nsubexpr; +} + +SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp) +{ + if( n<0 || n >= exp->_nsubexpr) return SQFalse; + *subexp = exp->_matches[n]; + return SQTrue; +} + diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp index 29fbdd601..56140f6ad 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp @@ -1,336 +1,336 @@ -/* see copyright notice in squirrel.h */
-#include <new>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include <sqstdblob.h>
-#include "sqstdstream.h"
-#include "sqstdblobimpl.h"
-
-#define SETUP_STREAM(v) \
- SQStream *self = NULL; \
- if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \
- return sq_throwerror(v,_SC("invalid type tag")); \
- if(!self->IsValid()) \
- return sq_throwerror(v,_SC("the stream is invalid"));
-
-SQInteger _stream_readblob(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQUserPointer data,blobp;
- SQInteger size,res;
- sq_getinteger(v,2,&size);
- if(size > self->Len()) {
- size = self->Len();
- }
- data = sq_getscratchpad(v,size);
- res = self->Read(data,size);
- if(res <= 0)
- return sq_throwerror(v,_SC("no data left to read"));
- blobp = sqstd_createblob(v,res);
- memcpy(blobp,data,res);
- return 1;
-}
-
-#define SAFE_READN(ptr,len) { \
- if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \
- }
-SQInteger _stream_readn(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQInteger format;
- sq_getinteger(v, 2, &format);
- switch(format) {
- case 'l': {
- SQInteger i;
- SAFE_READN(&i, sizeof(i));
- sq_pushinteger(v, i);
- }
- break;
- case 'i': {
- SQInt32 i;
- SAFE_READN(&i, sizeof(i));
- sq_pushinteger(v, i);
- }
- break;
- case 's': {
- short s;
- SAFE_READN(&s, sizeof(short));
- sq_pushinteger(v, s);
- }
- break;
- case 'w': {
- unsigned short w;
- SAFE_READN(&w, sizeof(unsigned short));
- sq_pushinteger(v, w);
- }
- break;
- case 'c': {
- char c;
- SAFE_READN(&c, sizeof(char));
- sq_pushinteger(v, c);
- }
- break;
- case 'b': {
- unsigned char c;
- SAFE_READN(&c, sizeof(unsigned char));
- sq_pushinteger(v, c);
- }
- break;
- case 'f': {
- float f;
- SAFE_READN(&f, sizeof(float));
- sq_pushfloat(v, f);
- }
- break;
- case 'd': {
- double d;
- SAFE_READN(&d, sizeof(double));
- sq_pushfloat(v, (SQFloat)d);
- }
- break;
- default:
- return sq_throwerror(v, _SC("invalid format"));
- }
- return 1;
-}
-
-SQInteger _stream_writeblob(HSQUIRRELVM v)
-{
- SQUserPointer data;
- SQInteger size;
- SETUP_STREAM(v);
- if(SQ_FAILED(sqstd_getblob(v,2,&data)))
- return sq_throwerror(v,_SC("invalid parameter"));
- size = sqstd_getblobsize(v,2);
- if(self->Write(data,size) != size)
- return sq_throwerror(v,_SC("io error"));
- sq_pushinteger(v,size);
- return 1;
-}
-
-SQInteger _stream_writen(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQInteger format, ti;
- SQFloat tf;
- sq_getinteger(v, 3, &format);
- switch(format) {
- case 'l': {
- SQInteger i;
- sq_getinteger(v, 2, &ti);
- i = ti;
- self->Write(&i, sizeof(SQInteger));
- }
- break;
- case 'i': {
- SQInt32 i;
- sq_getinteger(v, 2, &ti);
- i = (SQInt32)ti;
- self->Write(&i, sizeof(SQInt32));
- }
- break;
- case 's': {
- short s;
- sq_getinteger(v, 2, &ti);
- s = (short)ti;
- self->Write(&s, sizeof(short));
- }
- break;
- case 'w': {
- unsigned short w;
- sq_getinteger(v, 2, &ti);
- w = (unsigned short)ti;
- self->Write(&w, sizeof(unsigned short));
- }
- break;
- case 'c': {
- char c;
- sq_getinteger(v, 2, &ti);
- c = (char)ti;
- self->Write(&c, sizeof(char));
- }
- break;
- case 'b': {
- unsigned char b;
- sq_getinteger(v, 2, &ti);
- b = (unsigned char)ti;
- self->Write(&b, sizeof(unsigned char));
- }
- break;
- case 'f': {
- float f;
- sq_getfloat(v, 2, &tf);
- f = (float)tf;
- self->Write(&f, sizeof(float));
- }
- break;
- case 'd': {
- double d;
- sq_getfloat(v, 2, &tf);
- d = tf;
- self->Write(&d, sizeof(double));
- }
- break;
- default:
- return sq_throwerror(v, _SC("invalid format"));
- }
- return 0;
-}
-
-SQInteger _stream_seek(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQInteger offset, origin = SQ_SEEK_SET;
- sq_getinteger(v, 2, &offset);
- if(sq_gettop(v) > 2) {
- SQInteger t;
- sq_getinteger(v, 3, &t);
- switch(t) {
- case 'b': origin = SQ_SEEK_SET; break;
- case 'c': origin = SQ_SEEK_CUR; break;
- case 'e': origin = SQ_SEEK_END; break;
- default: return sq_throwerror(v,_SC("invalid origin"));
- }
- }
- sq_pushinteger(v, self->Seek(offset, origin));
- return 1;
-}
-
-SQInteger _stream_tell(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- sq_pushinteger(v, self->Tell());
- return 1;
-}
-
-SQInteger _stream_len(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- sq_pushinteger(v, self->Len());
- return 1;
-}
-
-SQInteger _stream_flush(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- if(!self->Flush())
- sq_pushinteger(v, 1);
- else
- sq_pushnull(v);
- return 1;
-}
-
-SQInteger _stream_eos(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- if(self->EOS())
- sq_pushinteger(v, 1);
- else
- sq_pushnull(v);
- return 1;
-}
-
- SQInteger _stream__cloned(HSQUIRRELVM v)
- {
- return sq_throwerror(v,_SC("this object cannot be cloned"));
- }
-
-static SQRegFunction _stream_methods[] = {
- _DECL_STREAM_FUNC(readblob,2,_SC("xn")),
- _DECL_STREAM_FUNC(readn,2,_SC("xn")),
- _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
- _DECL_STREAM_FUNC(writen,3,_SC("xnn")),
- _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
- _DECL_STREAM_FUNC(tell,1,_SC("x")),
- _DECL_STREAM_FUNC(len,1,_SC("x")),
- _DECL_STREAM_FUNC(eos,1,_SC("x")),
- _DECL_STREAM_FUNC(flush,1,_SC("x")),
- _DECL_STREAM_FUNC(_cloned,0,NULL),
- {0,0}
-};
-
-void init_streamclass(HSQUIRRELVM v)
-{
- sq_pushregistrytable(v);
- sq_pushstring(v,_SC("std_stream"),-1);
- if(SQ_FAILED(sq_get(v,-2))) {
- sq_pushstring(v,_SC("std_stream"),-1);
- sq_newclass(v,SQFalse);
- sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);
- SQInteger i = 0;
- while(_stream_methods[i].name != 0) {
- SQRegFunction &f = _stream_methods[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_newslot(v,-3,SQFalse);
- i++;
- }
- sq_newslot(v,-3,SQFalse);
- sq_pushroottable(v);
- sq_pushstring(v,_SC("stream"),-1);
- sq_pushstring(v,_SC("std_stream"),-1);
- sq_get(v,-4);
- sq_newslot(v,-3,SQFalse);
- sq_pop(v,1);
- }
- else {
- sq_pop(v,1); //result
- }
- sq_pop(v,1);
-}
-
-SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)
-{
- if(sq_gettype(v,-1) != OT_TABLE)
- return sq_throwerror(v,_SC("table expected"));
- SQInteger top = sq_gettop(v);
- //create delegate
- init_streamclass(v);
- sq_pushregistrytable(v);
- sq_pushstring(v,reg_name,-1);
- sq_pushstring(v,_SC("std_stream"),-1);
- if(SQ_SUCCEEDED(sq_get(v,-3))) {
- sq_newclass(v,SQTrue);
- sq_settypetag(v,-1,typetag);
- SQInteger i = 0;
- while(methods[i].name != 0) {
- SQRegFunction &f = methods[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_setnativeclosurename(v,-1,f.name);
- sq_newslot(v,-3,SQFalse);
- i++;
- }
- sq_newslot(v,-3,SQFalse);
- sq_pop(v,1);
-
- i = 0;
- while(globals[i].name!=0)
- {
- SQRegFunction &f = globals[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_setnativeclosurename(v,-1,f.name);
- sq_newslot(v,-3,SQFalse);
- i++;
- }
- //register the class in the target table
- sq_pushstring(v,name,-1);
- sq_pushregistrytable(v);
- sq_pushstring(v,reg_name,-1);
- sq_get(v,-2);
- sq_remove(v,-2);
- sq_newslot(v,-3,SQFalse);
-
- sq_settop(v,top);
- return SQ_OK;
- }
- sq_settop(v,top);
- return SQ_ERROR;
-}
+/* see copyright notice in squirrel.h */ +#include <new> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <squirrel.h> +#include <sqstdio.h> +#include <sqstdblob.h> +#include "sqstdstream.h" +#include "sqstdblobimpl.h" + +#define SETUP_STREAM(v) \ + SQStream *self = NULL; \ + if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \ + return sq_throwerror(v,_SC("invalid type tag")); \ + if(!self->IsValid()) \ + return sq_throwerror(v,_SC("the stream is invalid")); + +SQInteger _stream_readblob(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQUserPointer data,blobp; + SQInteger size,res; + sq_getinteger(v,2,&size); + if(size > self->Len()) { + size = self->Len(); + } + data = sq_getscratchpad(v,size); + res = self->Read(data,size); + if(res <= 0) + return sq_throwerror(v,_SC("no data left to read")); + blobp = sqstd_createblob(v,res); + memcpy(blobp,data,res); + return 1; +} + +#define SAFE_READN(ptr,len) { \ + if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \ + } +SQInteger _stream_readn(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger format; + sq_getinteger(v, 2, &format); + switch(format) { + case 'l': { + SQInteger i; + SAFE_READN(&i, sizeof(i)); + sq_pushinteger(v, i); + } + break; + case 'i': { + SQInt32 i; + SAFE_READN(&i, sizeof(i)); + sq_pushinteger(v, i); + } + break; + case 's': { + short s; + SAFE_READN(&s, sizeof(short)); + sq_pushinteger(v, s); + } + break; + case 'w': { + unsigned short w; + SAFE_READN(&w, sizeof(unsigned short)); + sq_pushinteger(v, w); + } + break; + case 'c': { + char c; + SAFE_READN(&c, sizeof(char)); + sq_pushinteger(v, c); + } + break; + case 'b': { + unsigned char c; + SAFE_READN(&c, sizeof(unsigned char)); + sq_pushinteger(v, c); + } + break; + case 'f': { + float f; + SAFE_READN(&f, sizeof(float)); + sq_pushfloat(v, f); + } + break; + case 'd': { + double d; + SAFE_READN(&d, sizeof(double)); + sq_pushfloat(v, (SQFloat)d); + } + break; + default: + return sq_throwerror(v, _SC("invalid format")); + } + return 1; +} + +SQInteger _stream_writeblob(HSQUIRRELVM v) +{ + SQUserPointer data; + SQInteger size; + SETUP_STREAM(v); + if(SQ_FAILED(sqstd_getblob(v,2,&data))) + return sq_throwerror(v,_SC("invalid parameter")); + size = sqstd_getblobsize(v,2); + if(self->Write(data,size) != size) + return sq_throwerror(v,_SC("io error")); + sq_pushinteger(v,size); + return 1; +} + +SQInteger _stream_writen(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger format, ti; + SQFloat tf; + sq_getinteger(v, 3, &format); + switch(format) { + case 'l': { + SQInteger i; + sq_getinteger(v, 2, &ti); + i = ti; + self->Write(&i, sizeof(SQInteger)); + } + break; + case 'i': { + SQInt32 i; + sq_getinteger(v, 2, &ti); + i = (SQInt32)ti; + self->Write(&i, sizeof(SQInt32)); + } + break; + case 's': { + short s; + sq_getinteger(v, 2, &ti); + s = (short)ti; + self->Write(&s, sizeof(short)); + } + break; + case 'w': { + unsigned short w; + sq_getinteger(v, 2, &ti); + w = (unsigned short)ti; + self->Write(&w, sizeof(unsigned short)); + } + break; + case 'c': { + char c; + sq_getinteger(v, 2, &ti); + c = (char)ti; + self->Write(&c, sizeof(char)); + } + break; + case 'b': { + unsigned char b; + sq_getinteger(v, 2, &ti); + b = (unsigned char)ti; + self->Write(&b, sizeof(unsigned char)); + } + break; + case 'f': { + float f; + sq_getfloat(v, 2, &tf); + f = (float)tf; + self->Write(&f, sizeof(float)); + } + break; + case 'd': { + double d; + sq_getfloat(v, 2, &tf); + d = tf; + self->Write(&d, sizeof(double)); + } + break; + default: + return sq_throwerror(v, _SC("invalid format")); + } + return 0; +} + +SQInteger _stream_seek(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger offset, origin = SQ_SEEK_SET; + sq_getinteger(v, 2, &offset); + if(sq_gettop(v) > 2) { + SQInteger t; + sq_getinteger(v, 3, &t); + switch(t) { + case 'b': origin = SQ_SEEK_SET; break; + case 'c': origin = SQ_SEEK_CUR; break; + case 'e': origin = SQ_SEEK_END; break; + default: return sq_throwerror(v,_SC("invalid origin")); + } + } + sq_pushinteger(v, self->Seek(offset, origin)); + return 1; +} + +SQInteger _stream_tell(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + sq_pushinteger(v, self->Tell()); + return 1; +} + +SQInteger _stream_len(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + sq_pushinteger(v, self->Len()); + return 1; +} + +SQInteger _stream_flush(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + if(!self->Flush()) + sq_pushinteger(v, 1); + else + sq_pushnull(v); + return 1; +} + +SQInteger _stream_eos(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + if(self->EOS()) + sq_pushinteger(v, 1); + else + sq_pushnull(v); + return 1; +} + + SQInteger _stream__cloned(HSQUIRRELVM v) + { + return sq_throwerror(v,_SC("this object cannot be cloned")); + } + +static SQRegFunction _stream_methods[] = { + _DECL_STREAM_FUNC(readblob,2,_SC("xn")), + _DECL_STREAM_FUNC(readn,2,_SC("xn")), + _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")), + _DECL_STREAM_FUNC(writen,3,_SC("xnn")), + _DECL_STREAM_FUNC(seek,-2,_SC("xnn")), + _DECL_STREAM_FUNC(tell,1,_SC("x")), + _DECL_STREAM_FUNC(len,1,_SC("x")), + _DECL_STREAM_FUNC(eos,1,_SC("x")), + _DECL_STREAM_FUNC(flush,1,_SC("x")), + _DECL_STREAM_FUNC(_cloned,0,NULL), + {0,0} +}; + +void init_streamclass(HSQUIRRELVM v) +{ + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_stream"),-1); + if(SQ_FAILED(sq_get(v,-2))) { + sq_pushstring(v,_SC("std_stream"),-1); + sq_newclass(v,SQFalse); + sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG); + SQInteger i = 0; + while(_stream_methods[i].name != 0) { + SQRegFunction &f = _stream_methods[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_newslot(v,-3,SQFalse); + i++; + } + sq_newslot(v,-3,SQFalse); + sq_pushroottable(v); + sq_pushstring(v,_SC("stream"),-1); + sq_pushstring(v,_SC("std_stream"),-1); + sq_get(v,-4); + sq_newslot(v,-3,SQFalse); + sq_pop(v,1); + } + else { + sq_pop(v,1); //result + } + sq_pop(v,1); +} + +SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals) +{ + if(sq_gettype(v,-1) != OT_TABLE) + return sq_throwerror(v,_SC("table expected")); + SQInteger top = sq_gettop(v); + //create delegate + init_streamclass(v); + sq_pushregistrytable(v); + sq_pushstring(v,reg_name,-1); + sq_pushstring(v,_SC("std_stream"),-1); + if(SQ_SUCCEEDED(sq_get(v,-3))) { + sq_newclass(v,SQTrue); + sq_settypetag(v,-1,typetag); + SQInteger i = 0; + while(methods[i].name != 0) { + SQRegFunction &f = methods[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_setnativeclosurename(v,-1,f.name); + sq_newslot(v,-3,SQFalse); + i++; + } + sq_newslot(v,-3,SQFalse); + sq_pop(v,1); + + i = 0; + while(globals[i].name!=0) + { + SQRegFunction &f = globals[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_setnativeclosurename(v,-1,f.name); + sq_newslot(v,-3,SQFalse); + i++; + } + //register the class in the target table + sq_pushstring(v,name,-1); + sq_pushregistrytable(v); + sq_pushstring(v,reg_name,-1); + sq_get(v,-2); + sq_remove(v,-2); + sq_newslot(v,-3,SQFalse); + + sq_settop(v,top); + return SQ_OK; + } + sq_settop(v,top); + return SQ_ERROR; +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdstream.h b/squirrel_3_0_1_stable/sqstdlib/sqstdstream.h index 1595251e7..4dcc00054 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdstream.h +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdstream.h @@ -1,18 +1,18 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_STREAM_H_
-#define _SQSTD_STREAM_H_
-
-SQInteger _stream_readblob(HSQUIRRELVM v);
-SQInteger _stream_readline(HSQUIRRELVM v);
-SQInteger _stream_readn(HSQUIRRELVM v);
-SQInteger _stream_writeblob(HSQUIRRELVM v);
-SQInteger _stream_writen(HSQUIRRELVM v);
-SQInteger _stream_seek(HSQUIRRELVM v);
-SQInteger _stream_tell(HSQUIRRELVM v);
-SQInteger _stream_len(HSQUIRRELVM v);
-SQInteger _stream_eos(HSQUIRRELVM v);
-SQInteger _stream_flush(HSQUIRRELVM v);
-
-#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck}
-SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals);
-#endif /*_SQSTD_STREAM_H_*/
+/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_STREAM_H_ +#define _SQSTD_STREAM_H_ + +SQInteger _stream_readblob(HSQUIRRELVM v); +SQInteger _stream_readline(HSQUIRRELVM v); +SQInteger _stream_readn(HSQUIRRELVM v); +SQInteger _stream_writeblob(HSQUIRRELVM v); +SQInteger _stream_writen(HSQUIRRELVM v); +SQInteger _stream_seek(HSQUIRRELVM v); +SQInteger _stream_tell(HSQUIRRELVM v); +SQInteger _stream_len(HSQUIRRELVM v); +SQInteger _stream_eos(HSQUIRRELVM v); +SQInteger _stream_flush(HSQUIRRELVM v); + +#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck} +SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals); +#endif /*_SQSTD_STREAM_H_*/ diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp index aaa37dfde..2a4e2a1fd 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp @@ -1,378 +1,378 @@ -/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <sqstdstring.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <assert.h>
-
-#ifdef SQUNICODE
-#define scstrchr wcschr
-#define scsnprintf wsnprintf
-#define scatoi _wtoi
-#define scstrtok wcstok
-#else
-#define scstrchr strchr
-#define scsnprintf snprintf
-#define scatoi atoi
-#define scstrtok strtok
-#endif
-#define MAX_FORMAT_LEN 20
-#define MAX_WFORMAT_LEN 3
-#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar))
-
-static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width)
-{
- SQChar swidth[MAX_WFORMAT_LEN];
- SQInteger wc = 0;
- SQInteger start = n;
- fmt[0] = '%';
- while (scstrchr(_SC("-+ #0"), src[n])) n++;
- while (scisdigit(src[n])) {
- swidth[wc] = src[n];
- n++;
- wc++;
- if(wc>=MAX_WFORMAT_LEN)
- return sq_throwerror(v,_SC("width format too long"));
- }
- swidth[wc] = '\0';
- if(wc > 0) {
- width = scatoi(swidth);
- }
- else
- width = 0;
- if (src[n] == '.') {
- n++;
-
- wc = 0;
- while (scisdigit(src[n])) {
- swidth[wc] = src[n];
- n++;
- wc++;
- if(wc>=MAX_WFORMAT_LEN)
- return sq_throwerror(v,_SC("precision format too long"));
- }
- swidth[wc] = '\0';
- if(wc > 0) {
- width += scatoi(swidth);
- }
- }
- if (n-start > MAX_FORMAT_LEN )
- return sq_throwerror(v,_SC("format too long"));
- memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));
- fmt[(n-start)+2] = '\0';
- return n;
-}
-
-SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output)
-{
- const SQChar *format;
- SQChar *dest;
- SQChar fmt[MAX_FORMAT_LEN];
- sq_getstring(v,nformatstringidx,&format);
- SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar);
- dest = sq_getscratchpad(v,allocated);
- SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
- while(format[n] != '\0') {
- if(format[n] != '%') {
- assert(i < allocated);
- dest[i++] = format[n];
- n++;
- }
- else if(format[n+1] == '%') { //handles %%
- dest[i++] = '%';
- n += 2;
- }
- else {
- n++;
- if( nparam > sq_gettop(v) )
- return sq_throwerror(v,_SC("not enough paramters for the given format string"));
- n = validate_format(v,fmt,format,n,w);
- if(n < 0) return -1;
- SQInteger addlen = 0;
- SQInteger valtype = 0;
- const SQChar *ts;
- SQInteger ti;
- SQFloat tf;
- switch(format[n]) {
- case 's':
- if(SQ_FAILED(sq_getstring(v,nparam,&ts)))
- return sq_throwerror(v,_SC("string expected for the specified format"));
- addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
- valtype = 's';
- break;
- case 'i': case 'd': case 'o': case 'u': case 'x': case 'X':
-#ifdef _SQ64
- {
- size_t flen = scstrlen(fmt);
- SQInteger fpos = flen - 1;
- SQChar f = fmt[fpos];
- SQChar *prec = (SQChar *)_PRINT_INT_PREC;
- while(*prec != _SC('\0')) {
- fmt[fpos++] = *prec++;
- }
- fmt[fpos++] = f;
- fmt[fpos++] = _SC('\0');
- }
-#endif
- case 'c':
- if(SQ_FAILED(sq_getinteger(v,nparam,&ti)))
- return sq_throwerror(v,_SC("integer expected for the specified format"));
- addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
- valtype = 'i';
- break;
- case 'f': case 'g': case 'G': case 'e': case 'E':
- if(SQ_FAILED(sq_getfloat(v,nparam,&tf)))
- return sq_throwerror(v,_SC("float expected for the specified format"));
- addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
- valtype = 'f';
- break;
- default:
- return sq_throwerror(v,_SC("invalid format"));
- }
- n++;
- allocated += addlen + sizeof(SQChar);
- dest = sq_getscratchpad(v,allocated);
- switch(valtype) {
- case 's': i += scsprintf(&dest[i],fmt,ts); break;
- case 'i': i += scsprintf(&dest[i],fmt,ti); break;
- case 'f': i += scsprintf(&dest[i],fmt,tf); break;
- };
- nparam ++;
- }
- }
- *outlen = i;
- dest[i] = '\0';
- *output = dest;
- return SQ_OK;
-}
-
-static SQInteger _string_format(HSQUIRRELVM v)
-{
- SQChar *dest = NULL;
- SQInteger length = 0;
- if(SQ_FAILED(sqstd_format(v,2,&length,&dest)))
- return -1;
- sq_pushstring(v,dest,length);
- return 1;
-}
-
-static void __strip_l(const SQChar *str,const SQChar **start)
-{
- const SQChar *t = str;
- while(((*t) != '\0') && scisspace(*t)){ t++; }
- *start = t;
-}
-
-static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end)
-{
- if(len == 0) {
- *end = str;
- return;
- }
- const SQChar *t = &str[len-1];
- while(t != str && scisspace(*t)) { t--; }
- *end = t+1;
-}
-
-static SQInteger _string_strip(HSQUIRRELVM v)
-{
- const SQChar *str,*start,*end;
- sq_getstring(v,2,&str);
- SQInteger len = sq_getsize(v,2);
- __strip_l(str,&start);
- __strip_r(str,len,&end);
- sq_pushstring(v,start,end - start);
- return 1;
-}
-
-static SQInteger _string_lstrip(HSQUIRRELVM v)
-{
- const SQChar *str,*start;
- sq_getstring(v,2,&str);
- __strip_l(str,&start);
- sq_pushstring(v,start,-1);
- return 1;
-}
-
-static SQInteger _string_rstrip(HSQUIRRELVM v)
-{
- const SQChar *str,*end;
- sq_getstring(v,2,&str);
- SQInteger len = sq_getsize(v,2);
- __strip_r(str,len,&end);
- sq_pushstring(v,str,end - str);
- return 1;
-}
-
-static SQInteger _string_split(HSQUIRRELVM v)
-{
- const SQChar *str,*seps;
- SQChar *stemp,*tok;
- sq_getstring(v,2,&str);
- sq_getstring(v,3,&seps);
- if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string"));
- SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);
- stemp = sq_getscratchpad(v,memsize);
- memcpy(stemp,str,memsize);
- tok = scstrtok(stemp,seps);
- sq_newarray(v,0);
- while( tok != NULL ) {
- sq_pushstring(v,tok,-1);
- sq_arrayappend(v,-2);
- tok = scstrtok( NULL, seps );
- }
- return 1;
-}
-
-#define SETUP_REX(v) \
- SQRex *self = NULL; \
- sq_getinstanceup(v,1,(SQUserPointer *)&self,0);
-
-static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size)
-{
- SQRex *self = ((SQRex *)p);
- sqstd_rex_free(self);
- return 1;
-}
-
-static SQInteger _regexp_match(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str;
- sq_getstring(v,2,&str);
- if(sqstd_rex_match(self,str) == SQTrue)
- {
- sq_pushbool(v,SQTrue);
- return 1;
- }
- sq_pushbool(v,SQFalse);
- return 1;
-}
-
-static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end)
-{
- sq_newtable(v);
- sq_pushstring(v,_SC("begin"),-1);
- sq_pushinteger(v,begin - str);
- sq_rawset(v,-3);
- sq_pushstring(v,_SC("end"),-1);
- sq_pushinteger(v,end - str);
- sq_rawset(v,-3);
-}
-
-static SQInteger _regexp_search(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str,*begin,*end;
- SQInteger start = 0;
- sq_getstring(v,2,&str);
- if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
- if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
- _addrexmatch(v,str,begin,end);
- return 1;
- }
- return 0;
-}
-
-static SQInteger _regexp_capture(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str,*begin,*end;
- SQInteger start = 0;
- sq_getstring(v,2,&str);
- if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
- if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
- SQInteger n = sqstd_rex_getsubexpcount(self);
- SQRexMatch match;
- sq_newarray(v,0);
- for(SQInteger i = 0;i < n; i++) {
- sqstd_rex_getsubexp(self,i,&match);
- if(match.len > 0)
- _addrexmatch(v,str,match.begin,match.begin+match.len);
- else
- _addrexmatch(v,str,str,str); //empty match
- sq_arrayappend(v,-2);
- }
- return 1;
- }
- return 0;
-}
-
-static SQInteger _regexp_subexpcount(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- sq_pushinteger(v,sqstd_rex_getsubexpcount(self));
- return 1;
-}
-
-static SQInteger _regexp_constructor(HSQUIRRELVM v)
-{
- const SQChar *error,*pattern;
- sq_getstring(v,2,&pattern);
- SQRex *rex = sqstd_rex_compile(pattern,&error);
- if(!rex) return sq_throwerror(v,error);
- sq_setinstanceup(v,1,rex);
- sq_setreleasehook(v,1,_rexobj_releasehook);
- return 0;
-}
-
-static SQInteger _regexp__typeof(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("regexp"),-1);
- return 1;
-}
-
-#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}
-static SQRegFunction rexobj_funcs[]={
- _DECL_REX_FUNC(constructor,2,_SC(".s")),
- _DECL_REX_FUNC(search,-2,_SC("xsn")),
- _DECL_REX_FUNC(match,2,_SC("xs")),
- _DECL_REX_FUNC(capture,-2,_SC("xsn")),
- _DECL_REX_FUNC(subexpcount,1,_SC("x")),
- _DECL_REX_FUNC(_typeof,1,_SC("x")),
- {0,0}
-};
-#undef _DECL_REX_FUNC
-
-#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}
-static SQRegFunction stringlib_funcs[]={
- _DECL_FUNC(format,-2,_SC(".s")),
- _DECL_FUNC(strip,2,_SC(".s")),
- _DECL_FUNC(lstrip,2,_SC(".s")),
- _DECL_FUNC(rstrip,2,_SC(".s")),
- _DECL_FUNC(split,3,_SC(".ss")),
- {0,0}
-};
-#undef _DECL_FUNC
-
-
-SQInteger sqstd_register_stringlib(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("regexp"),-1);
- sq_newclass(v,SQFalse);
- SQInteger i = 0;
- while(rexobj_funcs[i].name != 0) {
- SQRegFunction &f = rexobj_funcs[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_setnativeclosurename(v,-1,f.name);
- sq_newslot(v,-3,SQFalse);
- i++;
- }
- sq_newslot(v,-3,SQFalse);
-
- i = 0;
- while(stringlib_funcs[i].name!=0)
- {
- sq_pushstring(v,stringlib_funcs[i].name,-1);
- sq_newclosure(v,stringlib_funcs[i].f,0);
- sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);
- sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);
- sq_newslot(v,-3,SQFalse);
- i++;
- }
- return 1;
-}
+/* see copyright notice in squirrel.h */ +#include <squirrel.h> +#include <sqstdstring.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <assert.h> + +#ifdef SQUNICODE +#define scstrchr wcschr +#define scsnprintf wsnprintf +#define scatoi _wtoi +#define scstrtok wcstok +#else +#define scstrchr strchr +#define scsnprintf snprintf +#define scatoi atoi +#define scstrtok strtok +#endif +#define MAX_FORMAT_LEN 20 +#define MAX_WFORMAT_LEN 3 +#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar)) + +static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width) +{ + SQChar swidth[MAX_WFORMAT_LEN]; + SQInteger wc = 0; + SQInteger start = n; + fmt[0] = '%'; + while (scstrchr(_SC("-+ #0"), src[n])) n++; + while (scisdigit(src[n])) { + swidth[wc] = src[n]; + n++; + wc++; + if(wc>=MAX_WFORMAT_LEN) + return sq_throwerror(v,_SC("width format too long")); + } + swidth[wc] = '\0'; + if(wc > 0) { + width = scatoi(swidth); + } + else + width = 0; + if (src[n] == '.') { + n++; + + wc = 0; + while (scisdigit(src[n])) { + swidth[wc] = src[n]; + n++; + wc++; + if(wc>=MAX_WFORMAT_LEN) + return sq_throwerror(v,_SC("precision format too long")); + } + swidth[wc] = '\0'; + if(wc > 0) { + width += scatoi(swidth); + } + } + if (n-start > MAX_FORMAT_LEN ) + return sq_throwerror(v,_SC("format too long")); + memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar)); + fmt[(n-start)+2] = '\0'; + return n; +} + +SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output) +{ + const SQChar *format; + SQChar *dest; + SQChar fmt[MAX_FORMAT_LEN]; + sq_getstring(v,nformatstringidx,&format); + SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar); + dest = sq_getscratchpad(v,allocated); + SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0; + while(format[n] != '\0') { + if(format[n] != '%') { + assert(i < allocated); + dest[i++] = format[n]; + n++; + } + else if(format[n+1] == '%') { //handles %% + dest[i++] = '%'; + n += 2; + } + else { + n++; + if( nparam > sq_gettop(v) ) + return sq_throwerror(v,_SC("not enough paramters for the given format string")); + n = validate_format(v,fmt,format,n,w); + if(n < 0) return -1; + SQInteger addlen = 0; + SQInteger valtype = 0; + const SQChar *ts; + SQInteger ti; + SQFloat tf; + switch(format[n]) { + case 's': + if(SQ_FAILED(sq_getstring(v,nparam,&ts))) + return sq_throwerror(v,_SC("string expected for the specified format")); + addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar)); + valtype = 's'; + break; + case 'i': case 'd': case 'o': case 'u': case 'x': case 'X': +#ifdef _SQ64 + { + size_t flen = scstrlen(fmt); + SQInteger fpos = flen - 1; + SQChar f = fmt[fpos]; + SQChar *prec = (SQChar *)_PRINT_INT_PREC; + while(*prec != _SC('\0')) { + fmt[fpos++] = *prec++; + } + fmt[fpos++] = f; + fmt[fpos++] = _SC('\0'); + } +#endif + case 'c': + if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) + return sq_throwerror(v,_SC("integer expected for the specified format")); + addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); + valtype = 'i'; + break; + case 'f': case 'g': case 'G': case 'e': case 'E': + if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) + return sq_throwerror(v,_SC("float expected for the specified format")); + addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); + valtype = 'f'; + break; + default: + return sq_throwerror(v,_SC("invalid format")); + } + n++; + allocated += addlen + sizeof(SQChar); + dest = sq_getscratchpad(v,allocated); + switch(valtype) { + case 's': i += scsprintf(&dest[i],fmt,ts); break; + case 'i': i += scsprintf(&dest[i],fmt,ti); break; + case 'f': i += scsprintf(&dest[i],fmt,tf); break; + }; + nparam ++; + } + } + *outlen = i; + dest[i] = '\0'; + *output = dest; + return SQ_OK; +} + +static SQInteger _string_format(HSQUIRRELVM v) +{ + SQChar *dest = NULL; + SQInteger length = 0; + if(SQ_FAILED(sqstd_format(v,2,&length,&dest))) + return -1; + sq_pushstring(v,dest,length); + return 1; +} + +static void __strip_l(const SQChar *str,const SQChar **start) +{ + const SQChar *t = str; + while(((*t) != '\0') && scisspace(*t)){ t++; } + *start = t; +} + +static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end) +{ + if(len == 0) { + *end = str; + return; + } + const SQChar *t = &str[len-1]; + while(t != str && scisspace(*t)) { t--; } + *end = t+1; +} + +static SQInteger _string_strip(HSQUIRRELVM v) +{ + const SQChar *str,*start,*end; + sq_getstring(v,2,&str); + SQInteger len = sq_getsize(v,2); + __strip_l(str,&start); + __strip_r(str,len,&end); + sq_pushstring(v,start,end - start); + return 1; +} + +static SQInteger _string_lstrip(HSQUIRRELVM v) +{ + const SQChar *str,*start; + sq_getstring(v,2,&str); + __strip_l(str,&start); + sq_pushstring(v,start,-1); + return 1; +} + +static SQInteger _string_rstrip(HSQUIRRELVM v) +{ + const SQChar *str,*end; + sq_getstring(v,2,&str); + SQInteger len = sq_getsize(v,2); + __strip_r(str,len,&end); + sq_pushstring(v,str,end - str); + return 1; +} + +static SQInteger _string_split(HSQUIRRELVM v) +{ + const SQChar *str,*seps; + SQChar *stemp,*tok; + sq_getstring(v,2,&str); + sq_getstring(v,3,&seps); + if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string")); + SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar); + stemp = sq_getscratchpad(v,memsize); + memcpy(stemp,str,memsize); + tok = scstrtok(stemp,seps); + sq_newarray(v,0); + while( tok != NULL ) { + sq_pushstring(v,tok,-1); + sq_arrayappend(v,-2); + tok = scstrtok( NULL, seps ); + } + return 1; +} + +#define SETUP_REX(v) \ + SQRex *self = NULL; \ + sq_getinstanceup(v,1,(SQUserPointer *)&self,0); + +static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size) +{ + SQRex *self = ((SQRex *)p); + sqstd_rex_free(self); + return 1; +} + +static SQInteger _regexp_match(HSQUIRRELVM v) +{ + SETUP_REX(v); + const SQChar *str; + sq_getstring(v,2,&str); + if(sqstd_rex_match(self,str) == SQTrue) + { + sq_pushbool(v,SQTrue); + return 1; + } + sq_pushbool(v,SQFalse); + return 1; +} + +static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end) +{ + sq_newtable(v); + sq_pushstring(v,_SC("begin"),-1); + sq_pushinteger(v,begin - str); + sq_rawset(v,-3); + sq_pushstring(v,_SC("end"),-1); + sq_pushinteger(v,end - str); + sq_rawset(v,-3); +} + +static SQInteger _regexp_search(HSQUIRRELVM v) +{ + SETUP_REX(v); + const SQChar *str,*begin,*end; + SQInteger start = 0; + sq_getstring(v,2,&str); + if(sq_gettop(v) > 2) sq_getinteger(v,3,&start); + if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) { + _addrexmatch(v,str,begin,end); + return 1; + } + return 0; +} + +static SQInteger _regexp_capture(HSQUIRRELVM v) +{ + SETUP_REX(v); + const SQChar *str,*begin,*end; + SQInteger start = 0; + sq_getstring(v,2,&str); + if(sq_gettop(v) > 2) sq_getinteger(v,3,&start); + if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) { + SQInteger n = sqstd_rex_getsubexpcount(self); + SQRexMatch match; + sq_newarray(v,0); + for(SQInteger i = 0;i < n; i++) { + sqstd_rex_getsubexp(self,i,&match); + if(match.len > 0) + _addrexmatch(v,str,match.begin,match.begin+match.len); + else + _addrexmatch(v,str,str,str); //empty match + sq_arrayappend(v,-2); + } + return 1; + } + return 0; +} + +static SQInteger _regexp_subexpcount(HSQUIRRELVM v) +{ + SETUP_REX(v); + sq_pushinteger(v,sqstd_rex_getsubexpcount(self)); + return 1; +} + +static SQInteger _regexp_constructor(HSQUIRRELVM v) +{ + const SQChar *error,*pattern; + sq_getstring(v,2,&pattern); + SQRex *rex = sqstd_rex_compile(pattern,&error); + if(!rex) return sq_throwerror(v,error); + sq_setinstanceup(v,1,rex); + sq_setreleasehook(v,1,_rexobj_releasehook); + return 0; +} + +static SQInteger _regexp__typeof(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("regexp"),-1); + return 1; +} + +#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask} +static SQRegFunction rexobj_funcs[]={ + _DECL_REX_FUNC(constructor,2,_SC(".s")), + _DECL_REX_FUNC(search,-2,_SC("xsn")), + _DECL_REX_FUNC(match,2,_SC("xs")), + _DECL_REX_FUNC(capture,-2,_SC("xsn")), + _DECL_REX_FUNC(subexpcount,1,_SC("x")), + _DECL_REX_FUNC(_typeof,1,_SC("x")), + {0,0} +}; +#undef _DECL_REX_FUNC + +#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask} +static SQRegFunction stringlib_funcs[]={ + _DECL_FUNC(format,-2,_SC(".s")), + _DECL_FUNC(strip,2,_SC(".s")), + _DECL_FUNC(lstrip,2,_SC(".s")), + _DECL_FUNC(rstrip,2,_SC(".s")), + _DECL_FUNC(split,3,_SC(".ss")), + {0,0} +}; +#undef _DECL_FUNC + + +SQInteger sqstd_register_stringlib(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("regexp"),-1); + sq_newclass(v,SQFalse); + SQInteger i = 0; + while(rexobj_funcs[i].name != 0) { + SQRegFunction &f = rexobj_funcs[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_setnativeclosurename(v,-1,f.name); + sq_newslot(v,-3,SQFalse); + i++; + } + sq_newslot(v,-3,SQFalse); + + i = 0; + while(stringlib_funcs[i].name!=0) + { + sq_pushstring(v,stringlib_funcs[i].name,-1); + sq_newclosure(v,stringlib_funcs[i].f,0); + sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask); + sq_setnativeclosurename(v,-1,stringlib_funcs[i].name); + sq_newslot(v,-3,SQFalse); + i++; + } + return 1; +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp index 40f78d785..309139fec 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp @@ -1,147 +1,147 @@ -/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sqstdsystem.h>
-
-#ifdef SQUNICODE
-#include <wchar.h>
-#define scgetenv _wgetenv
-#define scsystem _wsystem
-#define scasctime _wasctime
-#define scremove _wremove
-#define screname _wrename
-#else
-#define scgetenv getenv
-#define scsystem system
-#define scasctime asctime
-#define scremove remove
-#define screname rename
-#endif
-
-static SQInteger _system_getenv(HSQUIRRELVM v)
-{
- const SQChar *s;
- if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
- sq_pushstring(v,scgetenv(s),-1);
- return 1;
- }
- return 0;
-}
-
-
-static SQInteger _system_system(HSQUIRRELVM v)
-{
- const SQChar *s;
- if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
- sq_pushinteger(v,scsystem(s));
- return 1;
- }
- return sq_throwerror(v,_SC("wrong param"));
-}
-
-
-static SQInteger _system_clock(HSQUIRRELVM v)
-{
- sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC);
- return 1;
-}
-
-static SQInteger _system_time(HSQUIRRELVM v)
-{
- time_t t;
- time(&t);
- sq_pushinteger(v,*((SQInteger *)&t));
- return 1;
-}
-
-static SQInteger _system_remove(HSQUIRRELVM v)
-{
- const SQChar *s;
- sq_getstring(v,2,&s);
- if(scremove(s)==-1)
- return sq_throwerror(v,_SC("remove() failed"));
- return 0;
-}
-
-static SQInteger _system_rename(HSQUIRRELVM v)
-{
- const SQChar *oldn,*newn;
- sq_getstring(v,2,&oldn);
- sq_getstring(v,3,&newn);
- if(screname(oldn,newn)==-1)
- return sq_throwerror(v,_SC("rename() failed"));
- return 0;
-}
-
-static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val)
-{
- sq_pushstring(v,name,-1);
- sq_pushinteger(v,val);
- sq_rawset(v,-3);
-}
-
-static SQInteger _system_date(HSQUIRRELVM v)
-{
- time_t t;
- SQInteger it;
- SQInteger format = 'l';
- if(sq_gettop(v) > 1) {
- sq_getinteger(v,2,&it);
- t = it;
- if(sq_gettop(v) > 2) {
- sq_getinteger(v,3,(SQInteger*)&format);
- }
- }
- else {
- time(&t);
- }
- tm *date;
- if(format == 'u')
- date = gmtime(&t);
- else
- date = localtime(&t);
- if(!date)
- return sq_throwerror(v,_SC("crt api failure"));
- sq_newtable(v);
- _set_integer_slot(v, _SC("sec"), date->tm_sec);
- _set_integer_slot(v, _SC("min"), date->tm_min);
- _set_integer_slot(v, _SC("hour"), date->tm_hour);
- _set_integer_slot(v, _SC("day"), date->tm_mday);
- _set_integer_slot(v, _SC("month"), date->tm_mon);
- _set_integer_slot(v, _SC("year"), date->tm_year+1900);
- _set_integer_slot(v, _SC("wday"), date->tm_wday);
- _set_integer_slot(v, _SC("yday"), date->tm_yday);
- return 1;
-}
-
-
-
-#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask}
-static SQRegFunction systemlib_funcs[]={
- _DECL_FUNC(getenv,2,_SC(".s")),
- _DECL_FUNC(system,2,_SC(".s")),
- _DECL_FUNC(clock,0,NULL),
- _DECL_FUNC(time,1,NULL),
- _DECL_FUNC(date,-1,_SC(".nn")),
- _DECL_FUNC(remove,2,_SC(".s")),
- _DECL_FUNC(rename,3,_SC(".ss")),
- {0,0}
-};
-#undef _DECL_FUNC
-
-SQInteger sqstd_register_systemlib(HSQUIRRELVM v)
-{
- SQInteger i=0;
- while(systemlib_funcs[i].name!=0)
- {
- sq_pushstring(v,systemlib_funcs[i].name,-1);
- sq_newclosure(v,systemlib_funcs[i].f,0);
- sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);
- sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);
- sq_newslot(v,-3,SQFalse);
- i++;
- }
- return 1;
-}
+/* see copyright notice in squirrel.h */ +#include <squirrel.h> +#include <time.h> +#include <stdlib.h> +#include <stdio.h> +#include <sqstdsystem.h> + +#ifdef SQUNICODE +#include <wchar.h> +#define scgetenv _wgetenv +#define scsystem _wsystem +#define scasctime _wasctime +#define scremove _wremove +#define screname _wrename +#else +#define scgetenv getenv +#define scsystem system +#define scasctime asctime +#define scremove remove +#define screname rename +#endif + +static SQInteger _system_getenv(HSQUIRRELVM v) +{ + const SQChar *s; + if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ + sq_pushstring(v,scgetenv(s),-1); + return 1; + } + return 0; +} + + +static SQInteger _system_system(HSQUIRRELVM v) +{ + const SQChar *s; + if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ + sq_pushinteger(v,scsystem(s)); + return 1; + } + return sq_throwerror(v,_SC("wrong param")); +} + + +static SQInteger _system_clock(HSQUIRRELVM v) +{ + sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC); + return 1; +} + +static SQInteger _system_time(HSQUIRRELVM v) +{ + time_t t; + time(&t); + sq_pushinteger(v,*((SQInteger *)&t)); + return 1; +} + +static SQInteger _system_remove(HSQUIRRELVM v) +{ + const SQChar *s; + sq_getstring(v,2,&s); + if(scremove(s)==-1) + return sq_throwerror(v,_SC("remove() failed")); + return 0; +} + +static SQInteger _system_rename(HSQUIRRELVM v) +{ + const SQChar *oldn,*newn; + sq_getstring(v,2,&oldn); + sq_getstring(v,3,&newn); + if(screname(oldn,newn)==-1) + return sq_throwerror(v,_SC("rename() failed")); + return 0; +} + +static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val) +{ + sq_pushstring(v,name,-1); + sq_pushinteger(v,val); + sq_rawset(v,-3); +} + +static SQInteger _system_date(HSQUIRRELVM v) +{ + time_t t; + SQInteger it; + SQInteger format = 'l'; + if(sq_gettop(v) > 1) { + sq_getinteger(v,2,&it); + t = it; + if(sq_gettop(v) > 2) { + sq_getinteger(v,3,(SQInteger*)&format); + } + } + else { + time(&t); + } + tm *date; + if(format == 'u') + date = gmtime(&t); + else + date = localtime(&t); + if(!date) + return sq_throwerror(v,_SC("crt api failure")); + sq_newtable(v); + _set_integer_slot(v, _SC("sec"), date->tm_sec); + _set_integer_slot(v, _SC("min"), date->tm_min); + _set_integer_slot(v, _SC("hour"), date->tm_hour); + _set_integer_slot(v, _SC("day"), date->tm_mday); + _set_integer_slot(v, _SC("month"), date->tm_mon); + _set_integer_slot(v, _SC("year"), date->tm_year+1900); + _set_integer_slot(v, _SC("wday"), date->tm_wday); + _set_integer_slot(v, _SC("yday"), date->tm_yday); + return 1; +} + + + +#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask} +static SQRegFunction systemlib_funcs[]={ + _DECL_FUNC(getenv,2,_SC(".s")), + _DECL_FUNC(system,2,_SC(".s")), + _DECL_FUNC(clock,0,NULL), + _DECL_FUNC(time,1,NULL), + _DECL_FUNC(date,-1,_SC(".nn")), + _DECL_FUNC(remove,2,_SC(".s")), + _DECL_FUNC(rename,3,_SC(".ss")), + {0,0} +}; +#undef _DECL_FUNC + +SQInteger sqstd_register_systemlib(HSQUIRRELVM v) +{ + SQInteger i=0; + while(systemlib_funcs[i].name!=0) + { + sq_pushstring(v,systemlib_funcs[i].name,-1); + sq_newclosure(v,systemlib_funcs[i].f,0); + sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask); + sq_setnativeclosurename(v,-1,systemlib_funcs[i].name); + sq_newslot(v,-3,SQFalse); + i++; + } + return 1; +} diff --git a/squirrel_3_0_1_stable/squirrel/sqapi.cpp b/squirrel_3_0_1_stable/squirrel/sqapi.cpp index 05338ce23..4c9b4c706 100644 --- a/squirrel_3_0_1_stable/squirrel/sqapi.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqapi.cpp @@ -1,1456 +1,1456 @@ -/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "squserdata.h"
-#include "sqcompiler.h"
-#include "sqfuncstate.h"
-#include "sqclass.h"
-
-bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o)
-{
- *o = &stack_get(v,idx);
- if(type(**o) != type){
- SQObjectPtr oval = v->PrintObjVal(**o);
- v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval));
- return false;
- }
- return true;
-}
-
-#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; }
-
-#define sq_aux_paramscheck(v,count) \
-{ \
- if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\
-}
-
-
-SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)
-{
- scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type));
- return sq_throwerror(v, _ss(v)->GetScratchPad(-1));
-}
-
-HSQUIRRELVM sq_open(SQInteger initialstacksize)
-{
- SQSharedState *ss;
- SQVM *v;
- sq_new(ss, SQSharedState);
- ss->Init();
- v = (SQVM *)SQ_MALLOC(sizeof(SQVM));
- new (v) SQVM(ss);
- ss->_root_vm = v;
- if(v->Init(NULL, initialstacksize)) {
- return v;
- } else {
- sq_delete(v, SQVM);
- return NULL;
- }
- return v;
-}
-
-HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize)
-{
- SQSharedState *ss;
- SQVM *v;
- ss=_ss(friendvm);
-
- v= (SQVM *)SQ_MALLOC(sizeof(SQVM));
- new (v) SQVM(ss);
-
- if(v->Init(friendvm, initialstacksize)) {
- friendvm->Push(v);
- return v;
- } else {
- sq_delete(v, SQVM);
- return NULL;
- }
-}
-
-SQInteger sq_getvmstate(HSQUIRRELVM v)
-{
- if(v->_suspended)
- return SQ_VMSTATE_SUSPENDED;
- else {
- if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING;
- else return SQ_VMSTATE_IDLE;
- }
-}
-
-void sq_seterrorhandler(HSQUIRRELVM v)
-{
- SQObject o = stack_get(v, -1);
- if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
- v->_errorhandler = o;
- v->Pop();
- }
-}
-
-void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook)
-{
- v->_debughook_native = hook;
- v->_debughook_closure.Null();
- v->_debughook = hook?true:false;
-}
-
-void sq_setdebughook(HSQUIRRELVM v)
-{
- SQObject o = stack_get(v,-1);
- if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
- v->_debughook_closure = o;
- v->_debughook_native = NULL;
- v->_debughook = !sq_isnull(o);
- v->Pop();
- }
-}
-
-void sq_close(HSQUIRRELVM v)
-{
- SQSharedState *ss = _ss(v);
- _thread(ss->_root_vm)->Finalize();
- sq_delete(ss, SQSharedState);
-}
-
-SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)
-{
- SQObjectPtr o;
-#ifndef NO_COMPILER
- if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {
- v->Push(SQClosure::Create(_ss(v), _funcproto(o)));
- return SQ_OK;
- }
- return SQ_ERROR;
-#else
- return sq_throwerror(v,_SC("this is a no compiler build"));
-#endif
-}
-
-void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)
-{
- _ss(v)->_debuginfo = enable?true:false;
-}
-
-void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)
-{
- _ss(v)->_notifyallexceptions = enable?true:false;
-}
-
-void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)
-{
- if(!ISREFCOUNTED(type(*po))) return;
-#ifdef NO_GARBAGE_COLLECTOR
- __AddRef(po->_type,po->_unVal);
-#else
- _ss(v)->_refs_table.AddRef(*po);
-#endif
-}
-
-SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po)
-{
- if(!ISREFCOUNTED(type(*po))) return 0;
-#ifdef NO_GARBAGE_COLLECTOR
- return po->_unVal.pRefCounted->_uiRef;
-#else
- return _ss(v)->_refs_table.GetRefCount(*po);
-#endif
-}
-
-SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po)
-{
- if(!ISREFCOUNTED(type(*po))) return SQTrue;
-#ifdef NO_GARBAGE_COLLECTOR
- bool ret = (po->_unVal.pRefCounted->_uiRef <= 1) ? SQTrue : SQFalse;
- __Release(po->_type,po->_unVal);
- return ret; //the ret val doesn't work(and cannot be fixed)
-#else
- return _ss(v)->_refs_table.Release(*po);
-#endif
-}
-
-const SQChar *sq_objtostring(const HSQOBJECT *o)
-{
- if(sq_type(*o) == OT_STRING) {
- return _stringval(*o);
- }
- return NULL;
-}
-
-SQInteger sq_objtointeger(const HSQOBJECT *o)
-{
- if(sq_isnumeric(*o)) {
- return tointeger(*o);
- }
- return 0;
-}
-
-SQFloat sq_objtofloat(const HSQOBJECT *o)
-{
- if(sq_isnumeric(*o)) {
- return tofloat(*o);
- }
- return 0;
-}
-
-SQBool sq_objtobool(const HSQOBJECT *o)
-{
- if(sq_isbool(*o)) {
- return _integer(*o);
- }
- return SQFalse;
-}
-
-SQUserPointer sq_objtouserpointer(const HSQOBJECT *o)
-{
- if(sq_isuserpointer(*o)) {
- return _userpointer(*o);
- }
- return 0;
-}
-
-void sq_pushnull(HSQUIRRELVM v)
-{
- v->PushNull();
-}
-
-void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len)
-{
- if(s)
- v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len)));
- else v->PushNull();
-}
-
-void sq_pushinteger(HSQUIRRELVM v,SQInteger n)
-{
- v->Push(n);
-}
-
-void sq_pushbool(HSQUIRRELVM v,SQBool b)
-{
- v->Push(b?true:false);
-}
-
-void sq_pushfloat(HSQUIRRELVM v,SQFloat n)
-{
- v->Push(n);
-}
-
-void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p)
-{
- v->Push(p);
-}
-
-SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size)
-{
- SQUserData *ud = SQUserData::Create(_ss(v), size);
- v->Push(ud);
- return (SQUserPointer)sq_aligning(ud + 1);
-}
-
-void sq_newtable(HSQUIRRELVM v)
-{
- v->Push(SQTable::Create(_ss(v), 0));
-}
-
-void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity)
-{
- v->Push(SQTable::Create(_ss(v), initialcapacity));
-}
-
-void sq_newarray(HSQUIRRELVM v,SQInteger size)
-{
- v->Push(SQArray::Create(_ss(v), size));
-}
-
-SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)
-{
- SQClass *baseclass = NULL;
- if(hasbase) {
- SQObjectPtr &base = stack_get(v,-1);
- if(type(base) != OT_CLASS)
- return sq_throwerror(v,_SC("invalid base type"));
- baseclass = _class(base);
- }
- SQClass *newclass = SQClass::Create(_ss(v), baseclass);
- if(baseclass) v->Pop();
- v->Push(newclass);
- return SQ_OK;
-}
-
-SQBool sq_instanceof(HSQUIRRELVM v)
-{
- SQObjectPtr &inst = stack_get(v,-1);
- SQObjectPtr &cl = stack_get(v,-2);
- if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS)
- return sq_throwerror(v,_SC("invalid param type"));
- return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse;
-}
-
-SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx)
-{
- sq_aux_paramscheck(v,2);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- _array(*arr)->Append(v->GetUp(-1));
- v->Pop();
- return SQ_OK;
-}
-
-SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
-{
- sq_aux_paramscheck(v, 1);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- if(_array(*arr)->Size() > 0) {
- if(pushval != 0){ v->Push(_array(*arr)->Top()); }
- _array(*arr)->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v, _SC("empty array"));
-}
-
-SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize)
-{
- sq_aux_paramscheck(v,1);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- if(newsize >= 0) {
- _array(*arr)->Resize(newsize);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("negative size"));
-}
-
-
-SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx)
-{
- sq_aux_paramscheck(v, 1);
- SQObjectPtr *o;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,o);
- SQArray *arr = _array(*o);
- if(arr->Size() > 0) {
- SQObjectPtr t;
- SQInteger size = arr->Size();
- SQInteger n = size >> 1; size -= 1;
- for(SQInteger i = 0; i < n; i++) {
- t = arr->_values[i];
- arr->_values[i] = arr->_values[size-i];
- arr->_values[size-i] = t;
- }
- return SQ_OK;
- }
- return SQ_OK;
-}
-
-SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx)
-{
- sq_aux_paramscheck(v, 1);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- return _array(*arr)->Remove(itemidx) ? SQ_OK : sq_throwerror(v,_SC("index out of range"));
-}
-
-SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos)
-{
- sq_aux_paramscheck(v, 1);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- SQRESULT ret = _array(*arr)->Insert(destpos, v->GetUp(-1)) ? SQ_OK : sq_throwerror(v,_SC("index out of range"));
- v->Pop();
- return ret;
-}
-
-void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)
-{
- SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func,nfreevars);
- nc->_nparamscheck = 0;
- for(SQUnsignedInteger i = 0; i < nfreevars; i++) {
- nc->_outervalues[i] = v->Top();
- v->Pop();
- }
- v->Push(SQObjectPtr(nc));
-}
-
-SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars)
-{
- SQObject o = stack_get(v, idx);
- if(type(o) == OT_CLOSURE) {
- SQClosure *c = _closure(o);
- SQFunctionProto *proto = c->_function;
- *nparams = (SQUnsignedInteger)proto->_nparameters;
- *nfreevars = (SQUnsignedInteger)proto->_noutervalues;
- return SQ_OK;
- }
- else if(type(o) == OT_NATIVECLOSURE)
- {
- SQNativeClosure *c = _nativeclosure(o);
- *nparams = (SQUnsignedInteger)c->_nparamscheck;
- *nfreevars = c->_noutervalues;
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("the object is not a closure"));
-}
-
-SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name)
-{
- SQObject o = stack_get(v, idx);
- if(sq_isnativeclosure(o)) {
- SQNativeClosure *nc = _nativeclosure(o);
- nc->_name = SQString::Create(_ss(v),name);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("the object is not a nativeclosure"));
-}
-
-SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask)
-{
- SQObject o = stack_get(v, -1);
- if(!sq_isnativeclosure(o))
- return sq_throwerror(v, _SC("native closure expected"));
- SQNativeClosure *nc = _nativeclosure(o);
- nc->_nparamscheck = nparamscheck;
- if(typemask) {
- SQIntVec res;
- if(!CompileTypemask(res, typemask))
- return sq_throwerror(v, _SC("invalid typemask"));
- nc->_typecheck.copy(res);
- }
- else {
- nc->_typecheck.resize(0);
- }
- if(nparamscheck == SQ_MATCHTYPEMASKSTRING) {
- nc->_nparamscheck = nc->_typecheck.size();
- }
- return SQ_OK;
-}
-
-SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(!sq_isnativeclosure(o) &&
- !sq_isclosure(o))
- return sq_throwerror(v,_SC("the target is not a closure"));
- SQObjectPtr &env = stack_get(v,-1);
- if(!sq_istable(env) &&
- !sq_isclass(env) &&
- !sq_isinstance(env))
- return sq_throwerror(v,_SC("invalid environment"));
- SQWeakRef *w = _refcounted(env)->GetWeakRef(type(env));
- SQObjectPtr ret;
- if(sq_isclosure(o)) {
- SQClosure *c = _closure(o)->Clone();
- __ObjRelease(c->_env);
- c->_env = w;
- __ObjAddRef(c->_env);
- if(_closure(o)->_base) {
- c->_base = _closure(o)->_base;
- __ObjAddRef(c->_base);
- }
- ret = c;
- }
- else { //then must be a native closure
- SQNativeClosure *c = _nativeclosure(o)->Clone();
- __ObjRelease(c->_env);
- c->_env = w;
- __ObjAddRef(c->_env);
- ret = c;
- }
- v->Pop();
- v->Push(ret);
- return SQ_OK;
-}
-
-SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx)
-{
- SQObject &o=stack_get(v,idx);
- switch(type(o)) {
- case OT_TABLE: _table(o)->Clear(); break;
- case OT_ARRAY: _array(o)->Resize(0); break;
- default:
- return sq_throwerror(v, _SC("clear only works on table and array"));
- break;
-
- }
- return SQ_OK;
-}
-
-void sq_pushroottable(HSQUIRRELVM v)
-{
- v->Push(v->_roottable);
-}
-
-void sq_pushregistrytable(HSQUIRRELVM v)
-{
- v->Push(_ss(v)->_registry);
-}
-
-void sq_pushconsttable(HSQUIRRELVM v)
-{
- v->Push(_ss(v)->_consts);
-}
-
-SQRESULT sq_setroottable(HSQUIRRELVM v)
-{
- SQObject o = stack_get(v, -1);
- if(sq_istable(o) || sq_isnull(o)) {
- v->_roottable = o;
- v->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v, _SC("ivalid type"));
-}
-
-SQRESULT sq_setconsttable(HSQUIRRELVM v)
-{
- SQObject o = stack_get(v, -1);
- if(sq_istable(o)) {
- _ss(v)->_consts = o;
- v->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v, _SC("ivalid type, expected table"));
-}
-
-void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p)
-{
- v->_foreignptr = p;
-}
-
-SQUserPointer sq_getforeignptr(HSQUIRRELVM v)
-{
- return v->_foreignptr;
-}
-
-void sq_push(HSQUIRRELVM v,SQInteger idx)
-{
- v->Push(stack_get(v, idx));
-}
-
-SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx)
-{
- return type(stack_get(v, idx));
-}
-
-
-SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v, idx);
- SQObjectPtr res;
- if(!v->ToString(o,res)) {
- return SQ_ERROR;
- }
- v->Push(res);
- return SQ_OK;
-}
-
-void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b)
-{
- SQObjectPtr &o = stack_get(v, idx);
- *b = SQVM::IsFalse(o)?SQFalse:SQTrue;
-}
-
-SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i)
-{
- SQObjectPtr &o = stack_get(v, idx);
- if(sq_isnumeric(o)) {
- *i = tointeger(o);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f)
-{
- SQObjectPtr &o = stack_get(v, idx);
- if(sq_isnumeric(o)) {
- *f = tofloat(o);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b)
-{
- SQObjectPtr &o = stack_get(v, idx);
- if(sq_isbool(o)) {
- *b = _integer(o);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_STRING,o);
- *c = _stringval(*o);
- return SQ_OK;
-}
-
-SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_THREAD,o);
- *thread = _thread(*o);
- return SQ_OK;
-}
-
-SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v,idx);
- v->PushNull();
- if(!v->Clone(o, stack_get(v, -1))){
- v->Pop();
- return SQ_ERROR;
- }
- return SQ_OK;
-}
-
-SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v, idx);
- SQObjectType type = type(o);
- switch(type) {
- case OT_STRING: return _string(o)->_len;
- case OT_TABLE: return _table(o)->CountUsed();
- case OT_ARRAY: return _array(o)->Size();
- case OT_USERDATA: return _userdata(o)->_size;
- case OT_INSTANCE: return _instance(o)->_class->_udsize;
- case OT_CLASS: return _class(o)->_udsize;
- default:
- return sq_aux_invalidtype(v, type);
- }
-}
-
-SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_USERDATA,o);
- (*p) = _userdataval(*o);
- if(typetag) *typetag = _userdata(*o)->_typetag;
- return SQ_OK;
-}
-
-SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag)
-{
- SQObjectPtr &o = stack_get(v,idx);
- switch(type(o)) {
- case OT_USERDATA: _userdata(o)->_typetag = typetag; break;
- case OT_CLASS: _class(o)->_typetag = typetag; break;
- default: return sq_throwerror(v,_SC("invalid object type"));
- }
- return SQ_OK;
-}
-
-SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag)
-{
- switch(type(*o)) {
- case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break;
- case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break;
- case OT_CLASS: *typetag = _class(*o)->_typetag; break;
- default: return SQ_ERROR;
- }
- return SQ_OK;
-}
-
-SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(SQ_FAILED(sq_getobjtypetag(&o,typetag)))
- return sq_throwerror(v,_SC("invalid object type"));
- return SQ_OK;
-}
-
-SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);
- (*p) = _userpointer(*o);
- return SQ_OK;
-}
-
-SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
- _instance(o)->_userpointer = p;
- return SQ_OK;
-}
-
-SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class"));
- if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked"));
- _class(o)->_udsize = udsize;
- return SQ_OK;
-}
-
-
-SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
- (*p) = _instance(o)->_userpointer;
- if(typetag != 0) {
- SQClass *cl = _instance(o)->_class;
- do{
- if(cl->_typetag == typetag)
- return SQ_OK;
- cl = cl->_base;
- }while(cl != NULL);
- return sq_throwerror(v,_SC("invalid type tag"));
- }
- return SQ_OK;
-}
-
-SQInteger sq_gettop(HSQUIRRELVM v)
-{
- return (v->_top) - v->_stackbase;
-}
-
-void sq_settop(HSQUIRRELVM v, SQInteger newtop)
-{
- SQInteger top = sq_gettop(v);
- if(top > newtop)
- sq_pop(v, top - newtop);
- else
- while(top++ < newtop) sq_pushnull(v);
-}
-
-void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop)
-{
- assert(v->_top >= nelemstopop);
- v->Pop(nelemstopop);
-}
-
-void sq_poptop(HSQUIRRELVM v)
-{
- assert(v->_top >= 1);
- v->Pop();
-}
-
-
-void sq_remove(HSQUIRRELVM v, SQInteger idx)
-{
- v->Remove(idx);
-}
-
-SQInteger sq_cmp(HSQUIRRELVM v)
-{
- SQInteger res;
- v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res);
- return res;
-}
-
-SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)
-{
- sq_aux_paramscheck(v, 3);
- SQObjectPtr &self = stack_get(v, idx);
- if(type(self) == OT_TABLE || type(self) == OT_CLASS) {
- SQObjectPtr &key = v->GetUp(-2);
- if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
- v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false);
- v->Pop(2);
- }
- return SQ_OK;
-}
-
-SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
-{
- sq_aux_paramscheck(v, 2);
- SQObjectPtr *self;
- _GETSAFE_OBJ(v, idx, OT_TABLE,self);
- SQObjectPtr &key = v->GetUp(-1);
- if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
- SQObjectPtr res;
- if(!v->DeleteSlot(*self, key, res)){
- return SQ_ERROR;
- }
- if(pushval) v->GetUp(-1) = res;
- else v->Pop();
- return SQ_OK;
-}
-
-SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self = stack_get(v, idx);
- if(v->Set(self, v->GetUp(-2), v->GetUp(-1),DONT_FALL_BACK)) {
- v->Pop(2);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self = stack_get(v, idx);
- if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key"));
- switch(type(self)) {
- case OT_TABLE:
- _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));
- v->Pop(2);
- return SQ_OK;
- break;
- case OT_CLASS:
- _class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false);
- v->Pop(2);
- return SQ_OK;
- break;
- case OT_INSTANCE:
- if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) {
- v->Pop(2);
- return SQ_OK;
- }
- break;
- case OT_ARRAY:
- if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
- v->Pop(2);
- return SQ_OK;
- }
- break;
- default:
- v->Pop(2);
- return sq_throwerror(v, _SC("rawset works only on array/table/class and instance"));
- }
- v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
-}
-
-SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self = stack_get(v, idx);
- SQObjectPtr &mt = v->GetUp(-1);
- SQObjectType type = type(self);
- switch(type) {
- case OT_TABLE:
- if(type(mt) == OT_TABLE) {
- if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();}
- else if(type(mt)==OT_NULL) {
- _table(self)->SetDelegate(NULL); v->Pop(); }
- else return sq_aux_invalidtype(v,type);
- break;
- case OT_USERDATA:
- if(type(mt)==OT_TABLE) {
- _userdata(self)->SetDelegate(_table(mt)); v->Pop(); }
- else if(type(mt)==OT_NULL) {
- _userdata(self)->SetDelegate(NULL); v->Pop(); }
- else return sq_aux_invalidtype(v, type);
- break;
- default:
- return sq_aux_invalidtype(v, type);
- break;
- }
- return SQ_OK;
-}
-
-SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
-{
- sq_aux_paramscheck(v, 2);
- SQObjectPtr *self;
- _GETSAFE_OBJ(v, idx, OT_TABLE,self);
- SQObjectPtr &key = v->GetUp(-1);
- SQObjectPtr t;
- if(_table(*self)->Get(key,t)) {
- _table(*self)->Remove(key);
- }
- if(pushval != 0)
- v->GetUp(-1) = t;
- else
- v->Pop();
- return SQ_OK;
-}
-
-SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self=stack_get(v,idx);
- switch(type(self)){
- case OT_TABLE:
- case OT_USERDATA:
- if(!_delegable(self)->_delegate){
- v->PushNull();
- break;
- }
- v->Push(SQObjectPtr(_delegable(self)->_delegate));
- break;
- default: return sq_throwerror(v,_SC("wrong type")); break;
- }
- return SQ_OK;
-
-}
-
-SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self=stack_get(v,idx);
- if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,DONT_FALL_BACK))
- return SQ_OK;
- v->Pop();
- return SQ_ERROR;
-}
-
-SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self=stack_get(v,idx);
- switch(type(self)) {
- case OT_TABLE:
- if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1)))
- return SQ_OK;
- break;
- case OT_CLASS:
- if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1)))
- return SQ_OK;
- break;
- case OT_INSTANCE:
- if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1)))
- return SQ_OK;
- break;
- case OT_ARRAY:{
- SQObjectPtr& key = v->GetUp(-1);
- if(sq_isnumeric(key)){
- if(_array(self)->Get(tointeger(key),v->GetUp(-1))) {
- return SQ_OK;
- }
- }
- else {
- v->Pop();
- return sq_throwerror(v,_SC("invalid index type for an array"));
- }
- }
- break;
- default:
- v->Pop();
- return sq_throwerror(v,_SC("rawget works only on array/table/instance and class"));
- }
- v->Pop();
- return sq_throwerror(v,_SC("the index doesn't exist"));
-}
-
-SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po)
-{
- *po=stack_get(v,idx);
- return SQ_OK;
-}
-
-const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx)
-{
- SQUnsignedInteger cstksize=v->_callsstacksize;
- SQUnsignedInteger lvl=(cstksize-level)-1;
- SQInteger stackbase=v->_stackbase;
- if(lvl<cstksize){
- for(SQUnsignedInteger i=0;i<level;i++){
- SQVM::CallInfo &ci=v->_callsstack[(cstksize-i)-1];
- stackbase-=ci._prevstkbase;
- }
- SQVM::CallInfo &ci=v->_callsstack[lvl];
- if(type(ci._closure)!=OT_CLOSURE)
- return NULL;
- SQClosure *c=_closure(ci._closure);
- SQFunctionProto *func=c->_function;
- if(func->_noutervalues > (SQInteger)idx) {
- v->Push(*_outer(c->_outervalues[idx])->_valptr);
- return _stringval(func->_outervalues[idx]._name);
- }
- idx -= func->_noutervalues;
- return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1);
- }
- return NULL;
-}
-
-void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
-{
- v->Push(SQObjectPtr(obj));
-}
-
-void sq_resetobject(HSQOBJECT *po)
-{
- po->_unVal.pUserPointer=NULL;po->_type=OT_NULL;
-}
-
-SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)
-{
- v->_lasterror=SQString::Create(_ss(v),err);
- return SQ_ERROR;
-}
-
-SQRESULT sq_throwobject(HSQUIRRELVM v)
-{
- v->_lasterror = v->GetUp(-1);
- v->Pop();
- return SQ_ERROR;
-}
-
-
-void sq_reseterror(HSQUIRRELVM v)
-{
- v->_lasterror.Null();
-}
-
-void sq_getlasterror(HSQUIRRELVM v)
-{
- v->Push(v->_lasterror);
-}
-
-SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize)
-{
- if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) {
- if(v->_nmetamethodscall) {
- return sq_throwerror(v,_SC("cannot resize stack while in a metamethod"));
- }
- v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size()));
- }
- return SQ_OK;
-}
-
-SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror)
-{
- if(type(v->GetUp(-1))==OT_GENERATOR){
- v->PushNull(); //retval
- if(!v->Execute(v->GetUp(-2),0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR))
- {v->Raise_Error(v->_lasterror); return SQ_ERROR;}
- if(!retval)
- v->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("only generators can be resumed"));
-}
-
-SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror)
-{
- SQObjectPtr res;
- if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){
-
- if(!v->_suspended) {
- v->Pop(params);//pop closure and args
- }
- if(retval){
- v->Push(res); return SQ_OK;
- }
- return SQ_OK;
- }
- else {
- v->Pop(params);
- return SQ_ERROR;
- }
- if(!v->_suspended)
- v->Pop(params);
- return sq_throwerror(v,_SC("call failed"));
-}
-
-SQRESULT sq_suspendvm(HSQUIRRELVM v)
-{
- return v->Suspend();
-}
-
-SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror,SQBool throwerror)
-{
- SQObjectPtr ret;
- if(!v->_suspended)
- return sq_throwerror(v,_SC("cannot resume a vm that is not running any code"));
- SQInteger target = v->_suspended_target;
- if(wakeupret) {
- if(target != -1) {
- v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval
- }
- v->Pop();
- } else if(target != -1) { v->GetAt(v->_stackbase+v->_suspended_target).Null(); }
- SQObjectPtr dummy;
- if(!v->Execute(dummy,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : SQVM::ET_RESUME_VM)) {
- return SQ_ERROR;
- }
- if(retval)
- v->Push(ret);
- return SQ_OK;
-}
-
-void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook)
-{
- if(sq_gettop(v) >= 1){
- SQObjectPtr &ud=stack_get(v,idx);
- switch( type(ud) ) {
- case OT_USERDATA: _userdata(ud)->_hook = hook; break;
- case OT_INSTANCE: _instance(ud)->_hook = hook; break;
- case OT_CLASS: _class(ud)->_hook = hook; break;
- default: break; //shutup compiler
- }
- }
-}
-
-void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)
-{
- _ss(v)->_compilererrorhandler = f;
-}
-
-SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, -1, OT_CLOSURE,o);
- unsigned short tag = SQ_BYTECODE_STREAM_TAG;
- if(w(up,&tag,2) != 2)
- return sq_throwerror(v,_SC("io error"));
- if(!_closure(*o)->Save(v,up,w))
- return SQ_ERROR;
- return SQ_OK;
-}
-
-SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up)
-{
- SQObjectPtr closure;
-
- unsigned short tag;
- if(r(up,&tag,2) != 2)
- return sq_throwerror(v,_SC("io error"));
- if(tag != SQ_BYTECODE_STREAM_TAG)
- return sq_throwerror(v,_SC("invalid stream"));
- if(!SQClosure::Load(v,up,r,closure))
- return SQ_ERROR;
- v->Push(closure);
- return SQ_OK;
-}
-
-SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize)
-{
- return _ss(v)->GetScratchPad(minsize);
-}
-
-SQRESULT sq_resurrectunreachable(HSQUIRRELVM v)
-{
-#ifndef NO_GARBAGE_COLLECTOR
- _ss(v)->ResurrectUnreachable(v);
- return SQ_OK;
-#else
- return sq_throwerror(v,_SC("sq_resurrectunreachable requires a garbage collector build"));
-#endif
-}
-
-SQInteger sq_collectgarbage(HSQUIRRELVM v)
-{
-#ifndef NO_GARBAGE_COLLECTOR
- return _ss(v)->CollectGarbage(v);
-#else
- return -1;
-#endif
-}
-
-SQRESULT sq_getcallee(HSQUIRRELVM v)
-{
- if(v->_callsstacksize > 1)
- {
- v->Push(v->_callsstack[v->_callsstacksize - 2]._closure);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("no closure in the calls stack"));
-}
-
-const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
-{
- SQObjectPtr &self=stack_get(v,idx);
- const SQChar *name = NULL;
- switch(type(self))
- {
- case OT_CLOSURE:{
- SQClosure *clo = _closure(self);
- SQFunctionProto *fp = clo->_function;
- if(((SQUnsignedInteger)fp->_noutervalues) > nval) {
- v->Push(*(_outer(clo->_outervalues[nval])->_valptr));
- SQOuterVar &ov = fp->_outervalues[nval];
- name = _stringval(ov._name);
- }
- }
- break;
- case OT_NATIVECLOSURE:{
- SQNativeClosure *clo = _nativeclosure(self);
- if(clo->_noutervalues > nval) {
- v->Push(clo->_outervalues[nval]);
- name = _SC("@NATIVE");
- }
- }
- break;
- default: break; //shutup compiler
- }
- return name;
-}
-
-SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
-{
- SQObjectPtr &self=stack_get(v,idx);
- switch(type(self))
- {
- case OT_CLOSURE:{
- SQFunctionProto *fp = _closure(self)->_function;
- if(((SQUnsignedInteger)fp->_noutervalues) > nval){
- *(_outer(_closure(self)->_outervalues[nval])->_valptr) = stack_get(v,-1);
- }
- else return sq_throwerror(v,_SC("invalid free var index"));
- }
- break;
- case OT_NATIVECLOSURE:
- if(_nativeclosure(self)->_noutervalues > nval){
- _nativeclosure(self)->_outervalues[nval] = stack_get(v,-1);
- }
- else return sq_throwerror(v,_SC("invalid free var index"));
- break;
- default:
- return sq_aux_invalidtype(v,type(self));
- }
- v->Pop();
- return SQ_OK;
-}
-
-SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- SQObjectPtr &key = stack_get(v,-2);
- SQObjectPtr &val = stack_get(v,-1);
- SQObjectPtr attrs;
- if(type(key) == OT_NULL) {
- attrs = _class(*o)->_attributes;
- _class(*o)->_attributes = val;
- v->Pop(2);
- v->Push(attrs);
- return SQ_OK;
- }else if(_class(*o)->GetAttributes(key,attrs)) {
- _class(*o)->SetAttributes(key,val);
- v->Pop(2);
- v->Push(attrs);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("wrong index"));
-}
-
-SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- SQObjectPtr &key = stack_get(v,-1);
- SQObjectPtr attrs;
- if(type(key) == OT_NULL) {
- attrs = _class(*o)->_attributes;
- v->Pop();
- v->Push(attrs);
- return SQ_OK;
- }
- else if(_class(*o)->GetAttributes(key,attrs)) {
- v->Pop();
- v->Push(attrs);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("wrong index"));
-}
-
-SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- SQObjectPtr &key = stack_get(v,-1);
- SQTable *m = _class(*o)->_members;
- SQObjectPtr val;
- if(m->Get(key,val)) {
- handle->_static = _isfield(val) ? SQFalse : SQTrue;
- handle->_index = _member_idx(val);
- v->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("wrong index"));
-}
-
-SQRESULT _getmemberbyhandle(HSQUIRRELVM v,SQObjectPtr &self,HSQMEMBERHANDLE *handle,SQObjectPtr *&val)
-{
- switch(type(self)) {
- case OT_INSTANCE: {
- SQInstance *i = _instance(self);
- if(handle->_static) {
- SQClass *c = i->_class;
- val = &c->_methods[handle->_index].val;
- }
- else {
- val = &i->_values[handle->_index];
-
- }
- }
- break;
- case OT_CLASS: {
- SQClass *c = _class(self);
- if(handle->_static) {
- val = &c->_methods[handle->_index].val;
- }
- else {
- val = &c->_defaultvalues[handle->_index].val;
- }
- }
- break;
- default:
- return sq_throwerror(v,_SC("wrong type(expected class or instance)"));
- }
- return SQ_OK;
-}
-
-SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle)
-{
- SQObjectPtr &self = stack_get(v,idx);
- SQObjectPtr *val = NULL;
- if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) {
- return SQ_ERROR;
- }
- v->Push(_realval(*val));
- return SQ_OK;
-}
-
-SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle)
-{
- SQObjectPtr &self = stack_get(v,idx);
- SQObjectPtr &newval = stack_get(v,-1);
- SQObjectPtr *val = NULL;
- if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) {
- return SQ_ERROR;
- }
- *val = newval;
- v->Pop();
- return SQ_OK;
-}
-
-SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- if(_class(*o)->_base)
- v->Push(SQObjectPtr(_class(*o)->_base));
- else
- v->PushNull();
- return SQ_OK;
-}
-
-SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_INSTANCE,o);
- v->Push(SQObjectPtr(_instance(*o)->_class));
- return SQ_OK;
-}
-
-SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- v->Push(_class(*o)->CreateInstance());
- return SQ_OK;
-}
-
-void sq_weakref(HSQUIRRELVM v,SQInteger idx)
-{
- SQObject &o=stack_get(v,idx);
- if(ISREFCOUNTED(type(o))) {
- v->Push(_refcounted(o)->GetWeakRef(type(o)));
- return;
- }
- v->Push(o);
-}
-
-SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_WEAKREF) {
- return sq_throwerror(v,_SC("the object must be a weakref"));
- }
- v->Push(_weakref(o)->_obj);
- return SQ_OK;
-}
-
-SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t)
-{
- SQSharedState *ss = _ss(v);
- switch(t) {
- case OT_TABLE: v->Push(ss->_table_default_delegate); break;
- case OT_ARRAY: v->Push(ss->_array_default_delegate); break;
- case OT_STRING: v->Push(ss->_string_default_delegate); break;
- case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break;
- case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break;
- case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break;
- case OT_THREAD: v->Push(ss->_thread_default_delegate); break;
- case OT_CLASS: v->Push(ss->_class_default_delegate); break;
- case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break;
- case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break;
- default: return sq_throwerror(v,_SC("the type doesn't have a default delegate"));
- }
- return SQ_OK;
-}
-
-SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val;
- if(type(o) == OT_GENERATOR) {
- return sq_throwerror(v,_SC("cannot iterate a generator"));
- }
- int faketojump;
- if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump))
- return SQ_ERROR;
- if(faketojump != 666) {
- v->Push(realkey);
- v->Push(val);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-struct BufState{
- const SQChar *buf;
- SQInteger ptr;
- SQInteger size;
-};
-
-SQInteger buf_lexfeed(SQUserPointer file)
-{
- BufState *buf=(BufState*)file;
- if(buf->size<(buf->ptr+1))
- return 0;
- return buf->buf[buf->ptr++];
-}
-
-SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) {
- BufState buf;
- buf.buf = s;
- buf.size = size;
- buf.ptr = 0;
- return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror);
-}
-
-void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)
-{
- dest->Push(stack_get(src,idx));
-}
-
-void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc)
-{
- _ss(v)->_printfunc = printfunc;
- _ss(v)->_errorfunc = errfunc;
-}
-
-SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)
-{
- return _ss(v)->_printfunc;
-}
-
-SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v)
-{
- return _ss(v)->_errorfunc;
-}
-
-void *sq_malloc(SQUnsignedInteger size)
-{
- return SQ_MALLOC(size);
-}
-
-void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize)
-{
- return SQ_REALLOC(p,oldsize,newsize);
-}
-
-void sq_free(void *p,SQUnsignedInteger size)
-{
- SQ_FREE(p,size);
-}
+/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "squserdata.h" +#include "sqcompiler.h" +#include "sqfuncstate.h" +#include "sqclass.h" + +bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o) +{ + *o = &stack_get(v,idx); + if(type(**o) != type){ + SQObjectPtr oval = v->PrintObjVal(**o); + v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval)); + return false; + } + return true; +} + +#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; } + +#define sq_aux_paramscheck(v,count) \ +{ \ + if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\ +} + + +SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type) +{ + scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type)); + return sq_throwerror(v, _ss(v)->GetScratchPad(-1)); +} + +HSQUIRRELVM sq_open(SQInteger initialstacksize) +{ + SQSharedState *ss; + SQVM *v; + sq_new(ss, SQSharedState); + ss->Init(); + v = (SQVM *)SQ_MALLOC(sizeof(SQVM)); + new (v) SQVM(ss); + ss->_root_vm = v; + if(v->Init(NULL, initialstacksize)) { + return v; + } else { + sq_delete(v, SQVM); + return NULL; + } + return v; +} + +HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize) +{ + SQSharedState *ss; + SQVM *v; + ss=_ss(friendvm); + + v= (SQVM *)SQ_MALLOC(sizeof(SQVM)); + new (v) SQVM(ss); + + if(v->Init(friendvm, initialstacksize)) { + friendvm->Push(v); + return v; + } else { + sq_delete(v, SQVM); + return NULL; + } +} + +SQInteger sq_getvmstate(HSQUIRRELVM v) +{ + if(v->_suspended) + return SQ_VMSTATE_SUSPENDED; + else { + if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING; + else return SQ_VMSTATE_IDLE; + } +} + +void sq_seterrorhandler(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { + v->_errorhandler = o; + v->Pop(); + } +} + +void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook) +{ + v->_debughook_native = hook; + v->_debughook_closure.Null(); + v->_debughook = hook?true:false; +} + +void sq_setdebughook(HSQUIRRELVM v) +{ + SQObject o = stack_get(v,-1); + if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { + v->_debughook_closure = o; + v->_debughook_native = NULL; + v->_debughook = !sq_isnull(o); + v->Pop(); + } +} + +void sq_close(HSQUIRRELVM v) +{ + SQSharedState *ss = _ss(v); + _thread(ss->_root_vm)->Finalize(); + sq_delete(ss, SQSharedState); +} + +SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror) +{ + SQObjectPtr o; +#ifndef NO_COMPILER + if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) { + v->Push(SQClosure::Create(_ss(v), _funcproto(o))); + return SQ_OK; + } + return SQ_ERROR; +#else + return sq_throwerror(v,_SC("this is a no compiler build")); +#endif +} + +void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable) +{ + _ss(v)->_debuginfo = enable?true:false; +} + +void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable) +{ + _ss(v)->_notifyallexceptions = enable?true:false; +} + +void sq_addref(HSQUIRRELVM v,HSQOBJECT *po) +{ + if(!ISREFCOUNTED(type(*po))) return; +#ifdef NO_GARBAGE_COLLECTOR + __AddRef(po->_type,po->_unVal); +#else + _ss(v)->_refs_table.AddRef(*po); +#endif +} + +SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po) +{ + if(!ISREFCOUNTED(type(*po))) return 0; +#ifdef NO_GARBAGE_COLLECTOR + return po->_unVal.pRefCounted->_uiRef; +#else + return _ss(v)->_refs_table.GetRefCount(*po); +#endif +} + +SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po) +{ + if(!ISREFCOUNTED(type(*po))) return SQTrue; +#ifdef NO_GARBAGE_COLLECTOR + bool ret = (po->_unVal.pRefCounted->_uiRef <= 1) ? SQTrue : SQFalse; + __Release(po->_type,po->_unVal); + return ret; //the ret val doesn't work(and cannot be fixed) +#else + return _ss(v)->_refs_table.Release(*po); +#endif +} + +const SQChar *sq_objtostring(const HSQOBJECT *o) +{ + if(sq_type(*o) == OT_STRING) { + return _stringval(*o); + } + return NULL; +} + +SQInteger sq_objtointeger(const HSQOBJECT *o) +{ + if(sq_isnumeric(*o)) { + return tointeger(*o); + } + return 0; +} + +SQFloat sq_objtofloat(const HSQOBJECT *o) +{ + if(sq_isnumeric(*o)) { + return tofloat(*o); + } + return 0; +} + +SQBool sq_objtobool(const HSQOBJECT *o) +{ + if(sq_isbool(*o)) { + return _integer(*o); + } + return SQFalse; +} + +SQUserPointer sq_objtouserpointer(const HSQOBJECT *o) +{ + if(sq_isuserpointer(*o)) { + return _userpointer(*o); + } + return 0; +} + +void sq_pushnull(HSQUIRRELVM v) +{ + v->PushNull(); +} + +void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len) +{ + if(s) + v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len))); + else v->PushNull(); +} + +void sq_pushinteger(HSQUIRRELVM v,SQInteger n) +{ + v->Push(n); +} + +void sq_pushbool(HSQUIRRELVM v,SQBool b) +{ + v->Push(b?true:false); +} + +void sq_pushfloat(HSQUIRRELVM v,SQFloat n) +{ + v->Push(n); +} + +void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p) +{ + v->Push(p); +} + +SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size) +{ + SQUserData *ud = SQUserData::Create(_ss(v), size); + v->Push(ud); + return (SQUserPointer)sq_aligning(ud + 1); +} + +void sq_newtable(HSQUIRRELVM v) +{ + v->Push(SQTable::Create(_ss(v), 0)); +} + +void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity) +{ + v->Push(SQTable::Create(_ss(v), initialcapacity)); +} + +void sq_newarray(HSQUIRRELVM v,SQInteger size) +{ + v->Push(SQArray::Create(_ss(v), size)); +} + +SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase) +{ + SQClass *baseclass = NULL; + if(hasbase) { + SQObjectPtr &base = stack_get(v,-1); + if(type(base) != OT_CLASS) + return sq_throwerror(v,_SC("invalid base type")); + baseclass = _class(base); + } + SQClass *newclass = SQClass::Create(_ss(v), baseclass); + if(baseclass) v->Pop(); + v->Push(newclass); + return SQ_OK; +} + +SQBool sq_instanceof(HSQUIRRELVM v) +{ + SQObjectPtr &inst = stack_get(v,-1); + SQObjectPtr &cl = stack_get(v,-2); + if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS) + return sq_throwerror(v,_SC("invalid param type")); + return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse; +} + +SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx) +{ + sq_aux_paramscheck(v,2); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + _array(*arr)->Append(v->GetUp(-1)); + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + if(_array(*arr)->Size() > 0) { + if(pushval != 0){ v->Push(_array(*arr)->Top()); } + _array(*arr)->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("empty array")); +} + +SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize) +{ + sq_aux_paramscheck(v,1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + if(newsize >= 0) { + _array(*arr)->Resize(newsize); + return SQ_OK; + } + return sq_throwerror(v,_SC("negative size")); +} + + +SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *o; + _GETSAFE_OBJ(v, idx, OT_ARRAY,o); + SQArray *arr = _array(*o); + if(arr->Size() > 0) { + SQObjectPtr t; + SQInteger size = arr->Size(); + SQInteger n = size >> 1; size -= 1; + for(SQInteger i = 0; i < n; i++) { + t = arr->_values[i]; + arr->_values[i] = arr->_values[size-i]; + arr->_values[size-i] = t; + } + return SQ_OK; + } + return SQ_OK; +} + +SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + return _array(*arr)->Remove(itemidx) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); +} + +SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos) +{ + sq_aux_paramscheck(v, 1); + SQObjectPtr *arr; + _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); + SQRESULT ret = _array(*arr)->Insert(destpos, v->GetUp(-1)) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); + v->Pop(); + return ret; +} + +void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars) +{ + SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func,nfreevars); + nc->_nparamscheck = 0; + for(SQUnsignedInteger i = 0; i < nfreevars; i++) { + nc->_outervalues[i] = v->Top(); + v->Pop(); + } + v->Push(SQObjectPtr(nc)); +} + +SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars) +{ + SQObject o = stack_get(v, idx); + if(type(o) == OT_CLOSURE) { + SQClosure *c = _closure(o); + SQFunctionProto *proto = c->_function; + *nparams = (SQUnsignedInteger)proto->_nparameters; + *nfreevars = (SQUnsignedInteger)proto->_noutervalues; + return SQ_OK; + } + else if(type(o) == OT_NATIVECLOSURE) + { + SQNativeClosure *c = _nativeclosure(o); + *nparams = (SQUnsignedInteger)c->_nparamscheck; + *nfreevars = c->_noutervalues; + return SQ_OK; + } + return sq_throwerror(v,_SC("the object is not a closure")); +} + +SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name) +{ + SQObject o = stack_get(v, idx); + if(sq_isnativeclosure(o)) { + SQNativeClosure *nc = _nativeclosure(o); + nc->_name = SQString::Create(_ss(v),name); + return SQ_OK; + } + return sq_throwerror(v,_SC("the object is not a nativeclosure")); +} + +SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask) +{ + SQObject o = stack_get(v, -1); + if(!sq_isnativeclosure(o)) + return sq_throwerror(v, _SC("native closure expected")); + SQNativeClosure *nc = _nativeclosure(o); + nc->_nparamscheck = nparamscheck; + if(typemask) { + SQIntVec res; + if(!CompileTypemask(res, typemask)) + return sq_throwerror(v, _SC("invalid typemask")); + nc->_typecheck.copy(res); + } + else { + nc->_typecheck.resize(0); + } + if(nparamscheck == SQ_MATCHTYPEMASKSTRING) { + nc->_nparamscheck = nc->_typecheck.size(); + } + return SQ_OK; +} + +SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + if(!sq_isnativeclosure(o) && + !sq_isclosure(o)) + return sq_throwerror(v,_SC("the target is not a closure")); + SQObjectPtr &env = stack_get(v,-1); + if(!sq_istable(env) && + !sq_isclass(env) && + !sq_isinstance(env)) + return sq_throwerror(v,_SC("invalid environment")); + SQWeakRef *w = _refcounted(env)->GetWeakRef(type(env)); + SQObjectPtr ret; + if(sq_isclosure(o)) { + SQClosure *c = _closure(o)->Clone(); + __ObjRelease(c->_env); + c->_env = w; + __ObjAddRef(c->_env); + if(_closure(o)->_base) { + c->_base = _closure(o)->_base; + __ObjAddRef(c->_base); + } + ret = c; + } + else { //then must be a native closure + SQNativeClosure *c = _nativeclosure(o)->Clone(); + __ObjRelease(c->_env); + c->_env = w; + __ObjAddRef(c->_env); + ret = c; + } + v->Pop(); + v->Push(ret); + return SQ_OK; +} + +SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx) +{ + SQObject &o=stack_get(v,idx); + switch(type(o)) { + case OT_TABLE: _table(o)->Clear(); break; + case OT_ARRAY: _array(o)->Resize(0); break; + default: + return sq_throwerror(v, _SC("clear only works on table and array")); + break; + + } + return SQ_OK; +} + +void sq_pushroottable(HSQUIRRELVM v) +{ + v->Push(v->_roottable); +} + +void sq_pushregistrytable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_registry); +} + +void sq_pushconsttable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_consts); +} + +SQRESULT sq_setroottable(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_istable(o) || sq_isnull(o)) { + v->_roottable = o; + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("ivalid type")); +} + +SQRESULT sq_setconsttable(HSQUIRRELVM v) +{ + SQObject o = stack_get(v, -1); + if(sq_istable(o)) { + _ss(v)->_consts = o; + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v, _SC("ivalid type, expected table")); +} + +void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p) +{ + v->_foreignptr = p; +} + +SQUserPointer sq_getforeignptr(HSQUIRRELVM v) +{ + return v->_foreignptr; +} + +void sq_push(HSQUIRRELVM v,SQInteger idx) +{ + v->Push(stack_get(v, idx)); +} + +SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx) +{ + return type(stack_get(v, idx)); +} + + +SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v, idx); + SQObjectPtr res; + if(!v->ToString(o,res)) { + return SQ_ERROR; + } + v->Push(res); + return SQ_OK; +} + +void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b) +{ + SQObjectPtr &o = stack_get(v, idx); + *b = SQVM::IsFalse(o)?SQFalse:SQTrue; +} + +SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isnumeric(o)) { + *i = tointeger(o); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isnumeric(o)) { + *f = tofloat(o); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b) +{ + SQObjectPtr &o = stack_get(v, idx); + if(sq_isbool(o)) { + *b = _integer(o); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_STRING,o); + *c = _stringval(*o); + return SQ_OK; +} + +SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_THREAD,o); + *thread = _thread(*o); + return SQ_OK; +} + +SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + v->PushNull(); + if(!v->Clone(o, stack_get(v, -1))){ + v->Pop(); + return SQ_ERROR; + } + return SQ_OK; +} + +SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx) +{ + SQObjectPtr &o = stack_get(v, idx); + SQObjectType type = type(o); + switch(type) { + case OT_STRING: return _string(o)->_len; + case OT_TABLE: return _table(o)->CountUsed(); + case OT_ARRAY: return _array(o)->Size(); + case OT_USERDATA: return _userdata(o)->_size; + case OT_INSTANCE: return _instance(o)->_class->_udsize; + case OT_CLASS: return _class(o)->_udsize; + default: + return sq_aux_invalidtype(v, type); + } +} + +SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_USERDATA,o); + (*p) = _userdataval(*o); + if(typetag) *typetag = _userdata(*o)->_typetag; + return SQ_OK; +} + +SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + switch(type(o)) { + case OT_USERDATA: _userdata(o)->_typetag = typetag; break; + case OT_CLASS: _class(o)->_typetag = typetag; break; + default: return sq_throwerror(v,_SC("invalid object type")); + } + return SQ_OK; +} + +SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag) +{ + switch(type(*o)) { + case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break; + case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break; + case OT_CLASS: *typetag = _class(*o)->_typetag; break; + default: return SQ_ERROR; + } + return SQ_OK; +} + +SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + if(SQ_FAILED(sq_getobjtypetag(&o,typetag))) + return sq_throwerror(v,_SC("invalid object type")); + return SQ_OK; +} + +SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o); + (*p) = _userpointer(*o); + return SQ_OK; +} + +SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance")); + _instance(o)->_userpointer = p; + return SQ_OK; +} + +SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class")); + if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked")); + _class(o)->_udsize = udsize; + return SQ_OK; +} + + +SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance")); + (*p) = _instance(o)->_userpointer; + if(typetag != 0) { + SQClass *cl = _instance(o)->_class; + do{ + if(cl->_typetag == typetag) + return SQ_OK; + cl = cl->_base; + }while(cl != NULL); + return sq_throwerror(v,_SC("invalid type tag")); + } + return SQ_OK; +} + +SQInteger sq_gettop(HSQUIRRELVM v) +{ + return (v->_top) - v->_stackbase; +} + +void sq_settop(HSQUIRRELVM v, SQInteger newtop) +{ + SQInteger top = sq_gettop(v); + if(top > newtop) + sq_pop(v, top - newtop); + else + while(top++ < newtop) sq_pushnull(v); +} + +void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop) +{ + assert(v->_top >= nelemstopop); + v->Pop(nelemstopop); +} + +void sq_poptop(HSQUIRRELVM v) +{ + assert(v->_top >= 1); + v->Pop(); +} + + +void sq_remove(HSQUIRRELVM v, SQInteger idx) +{ + v->Remove(idx); +} + +SQInteger sq_cmp(HSQUIRRELVM v) +{ + SQInteger res; + v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res); + return res; +} + +SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic) +{ + sq_aux_paramscheck(v, 3); + SQObjectPtr &self = stack_get(v, idx); + if(type(self) == OT_TABLE || type(self) == OT_CLASS) { + SQObjectPtr &key = v->GetUp(-2); + if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); + v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false); + v->Pop(2); + } + return SQ_OK; +} + +SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 2); + SQObjectPtr *self; + _GETSAFE_OBJ(v, idx, OT_TABLE,self); + SQObjectPtr &key = v->GetUp(-1); + if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); + SQObjectPtr res; + if(!v->DeleteSlot(*self, key, res)){ + return SQ_ERROR; + } + if(pushval) v->GetUp(-1) = res; + else v->Pop(); + return SQ_OK; +} + +SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + if(v->Set(self, v->GetUp(-2), v->GetUp(-1),DONT_FALL_BACK)) { + v->Pop(2); + return SQ_OK; + } + return SQ_ERROR; +} + +SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key")); + switch(type(self)) { + case OT_TABLE: + _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1)); + v->Pop(2); + return SQ_OK; + break; + case OT_CLASS: + _class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false); + v->Pop(2); + return SQ_OK; + break; + case OT_INSTANCE: + if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) { + v->Pop(2); + return SQ_OK; + } + break; + case OT_ARRAY: + if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) { + v->Pop(2); + return SQ_OK; + } + break; + default: + v->Pop(2); + return sq_throwerror(v, _SC("rawset works only on array/table/class and instance")); + } + v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR; +} + +SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self = stack_get(v, idx); + SQObjectPtr &mt = v->GetUp(-1); + SQObjectType type = type(self); + switch(type) { + case OT_TABLE: + if(type(mt) == OT_TABLE) { + if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();} + else if(type(mt)==OT_NULL) { + _table(self)->SetDelegate(NULL); v->Pop(); } + else return sq_aux_invalidtype(v,type); + break; + case OT_USERDATA: + if(type(mt)==OT_TABLE) { + _userdata(self)->SetDelegate(_table(mt)); v->Pop(); } + else if(type(mt)==OT_NULL) { + _userdata(self)->SetDelegate(NULL); v->Pop(); } + else return sq_aux_invalidtype(v, type); + break; + default: + return sq_aux_invalidtype(v, type); + break; + } + return SQ_OK; +} + +SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) +{ + sq_aux_paramscheck(v, 2); + SQObjectPtr *self; + _GETSAFE_OBJ(v, idx, OT_TABLE,self); + SQObjectPtr &key = v->GetUp(-1); + SQObjectPtr t; + if(_table(*self)->Get(key,t)) { + _table(*self)->Remove(key); + } + if(pushval != 0) + v->GetUp(-1) = t; + else + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + switch(type(self)){ + case OT_TABLE: + case OT_USERDATA: + if(!_delegable(self)->_delegate){ + v->PushNull(); + break; + } + v->Push(SQObjectPtr(_delegable(self)->_delegate)); + break; + default: return sq_throwerror(v,_SC("wrong type")); break; + } + return SQ_OK; + +} + +SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,DONT_FALL_BACK)) + return SQ_OK; + v->Pop(); + return SQ_ERROR; +} + +SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &self=stack_get(v,idx); + switch(type(self)) { + case OT_TABLE: + if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1))) + return SQ_OK; + break; + case OT_CLASS: + if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1))) + return SQ_OK; + break; + case OT_INSTANCE: + if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1))) + return SQ_OK; + break; + case OT_ARRAY:{ + SQObjectPtr& key = v->GetUp(-1); + if(sq_isnumeric(key)){ + if(_array(self)->Get(tointeger(key),v->GetUp(-1))) { + return SQ_OK; + } + } + else { + v->Pop(); + return sq_throwerror(v,_SC("invalid index type for an array")); + } + } + break; + default: + v->Pop(); + return sq_throwerror(v,_SC("rawget works only on array/table/instance and class")); + } + v->Pop(); + return sq_throwerror(v,_SC("the index doesn't exist")); +} + +SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po) +{ + *po=stack_get(v,idx); + return SQ_OK; +} + +const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx) +{ + SQUnsignedInteger cstksize=v->_callsstacksize; + SQUnsignedInteger lvl=(cstksize-level)-1; + SQInteger stackbase=v->_stackbase; + if(lvl<cstksize){ + for(SQUnsignedInteger i=0;i<level;i++){ + SQVM::CallInfo &ci=v->_callsstack[(cstksize-i)-1]; + stackbase-=ci._prevstkbase; + } + SQVM::CallInfo &ci=v->_callsstack[lvl]; + if(type(ci._closure)!=OT_CLOSURE) + return NULL; + SQClosure *c=_closure(ci._closure); + SQFunctionProto *func=c->_function; + if(func->_noutervalues > (SQInteger)idx) { + v->Push(*_outer(c->_outervalues[idx])->_valptr); + return _stringval(func->_outervalues[idx]._name); + } + idx -= func->_noutervalues; + return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1); + } + return NULL; +} + +void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj) +{ + v->Push(SQObjectPtr(obj)); +} + +void sq_resetobject(HSQOBJECT *po) +{ + po->_unVal.pUserPointer=NULL;po->_type=OT_NULL; +} + +SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err) +{ + v->_lasterror=SQString::Create(_ss(v),err); + return SQ_ERROR; +} + +SQRESULT sq_throwobject(HSQUIRRELVM v) +{ + v->_lasterror = v->GetUp(-1); + v->Pop(); + return SQ_ERROR; +} + + +void sq_reseterror(HSQUIRRELVM v) +{ + v->_lasterror.Null(); +} + +void sq_getlasterror(HSQUIRRELVM v) +{ + v->Push(v->_lasterror); +} + +SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize) +{ + if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) { + if(v->_nmetamethodscall) { + return sq_throwerror(v,_SC("cannot resize stack while in a metamethod")); + } + v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size())); + } + return SQ_OK; +} + +SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror) +{ + if(type(v->GetUp(-1))==OT_GENERATOR){ + v->PushNull(); //retval + if(!v->Execute(v->GetUp(-2),0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR)) + {v->Raise_Error(v->_lasterror); return SQ_ERROR;} + if(!retval) + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v,_SC("only generators can be resumed")); +} + +SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror) +{ + SQObjectPtr res; + if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){ + + if(!v->_suspended) { + v->Pop(params);//pop closure and args + } + if(retval){ + v->Push(res); return SQ_OK; + } + return SQ_OK; + } + else { + v->Pop(params); + return SQ_ERROR; + } + if(!v->_suspended) + v->Pop(params); + return sq_throwerror(v,_SC("call failed")); +} + +SQRESULT sq_suspendvm(HSQUIRRELVM v) +{ + return v->Suspend(); +} + +SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror,SQBool throwerror) +{ + SQObjectPtr ret; + if(!v->_suspended) + return sq_throwerror(v,_SC("cannot resume a vm that is not running any code")); + SQInteger target = v->_suspended_target; + if(wakeupret) { + if(target != -1) { + v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval + } + v->Pop(); + } else if(target != -1) { v->GetAt(v->_stackbase+v->_suspended_target).Null(); } + SQObjectPtr dummy; + if(!v->Execute(dummy,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : SQVM::ET_RESUME_VM)) { + return SQ_ERROR; + } + if(retval) + v->Push(ret); + return SQ_OK; +} + +void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook) +{ + if(sq_gettop(v) >= 1){ + SQObjectPtr &ud=stack_get(v,idx); + switch( type(ud) ) { + case OT_USERDATA: _userdata(ud)->_hook = hook; break; + case OT_INSTANCE: _instance(ud)->_hook = hook; break; + case OT_CLASS: _class(ud)->_hook = hook; break; + default: break; //shutup compiler + } + } +} + +void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f) +{ + _ss(v)->_compilererrorhandler = f; +} + +SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, -1, OT_CLOSURE,o); + unsigned short tag = SQ_BYTECODE_STREAM_TAG; + if(w(up,&tag,2) != 2) + return sq_throwerror(v,_SC("io error")); + if(!_closure(*o)->Save(v,up,w)) + return SQ_ERROR; + return SQ_OK; +} + +SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up) +{ + SQObjectPtr closure; + + unsigned short tag; + if(r(up,&tag,2) != 2) + return sq_throwerror(v,_SC("io error")); + if(tag != SQ_BYTECODE_STREAM_TAG) + return sq_throwerror(v,_SC("invalid stream")); + if(!SQClosure::Load(v,up,r,closure)) + return SQ_ERROR; + v->Push(closure); + return SQ_OK; +} + +SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize) +{ + return _ss(v)->GetScratchPad(minsize); +} + +SQRESULT sq_resurrectunreachable(HSQUIRRELVM v) +{ +#ifndef NO_GARBAGE_COLLECTOR + _ss(v)->ResurrectUnreachable(v); + return SQ_OK; +#else + return sq_throwerror(v,_SC("sq_resurrectunreachable requires a garbage collector build")); +#endif +} + +SQInteger sq_collectgarbage(HSQUIRRELVM v) +{ +#ifndef NO_GARBAGE_COLLECTOR + return _ss(v)->CollectGarbage(v); +#else + return -1; +#endif +} + +SQRESULT sq_getcallee(HSQUIRRELVM v) +{ + if(v->_callsstacksize > 1) + { + v->Push(v->_callsstack[v->_callsstacksize - 2]._closure); + return SQ_OK; + } + return sq_throwerror(v,_SC("no closure in the calls stack")); +} + +const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) +{ + SQObjectPtr &self=stack_get(v,idx); + const SQChar *name = NULL; + switch(type(self)) + { + case OT_CLOSURE:{ + SQClosure *clo = _closure(self); + SQFunctionProto *fp = clo->_function; + if(((SQUnsignedInteger)fp->_noutervalues) > nval) { + v->Push(*(_outer(clo->_outervalues[nval])->_valptr)); + SQOuterVar &ov = fp->_outervalues[nval]; + name = _stringval(ov._name); + } + } + break; + case OT_NATIVECLOSURE:{ + SQNativeClosure *clo = _nativeclosure(self); + if(clo->_noutervalues > nval) { + v->Push(clo->_outervalues[nval]); + name = _SC("@NATIVE"); + } + } + break; + default: break; //shutup compiler + } + return name; +} + +SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) +{ + SQObjectPtr &self=stack_get(v,idx); + switch(type(self)) + { + case OT_CLOSURE:{ + SQFunctionProto *fp = _closure(self)->_function; + if(((SQUnsignedInteger)fp->_noutervalues) > nval){ + *(_outer(_closure(self)->_outervalues[nval])->_valptr) = stack_get(v,-1); + } + else return sq_throwerror(v,_SC("invalid free var index")); + } + break; + case OT_NATIVECLOSURE: + if(_nativeclosure(self)->_noutervalues > nval){ + _nativeclosure(self)->_outervalues[nval] = stack_get(v,-1); + } + else return sq_throwerror(v,_SC("invalid free var index")); + break; + default: + return sq_aux_invalidtype(v,type(self)); + } + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + SQObjectPtr &key = stack_get(v,-2); + SQObjectPtr &val = stack_get(v,-1); + SQObjectPtr attrs; + if(type(key) == OT_NULL) { + attrs = _class(*o)->_attributes; + _class(*o)->_attributes = val; + v->Pop(2); + v->Push(attrs); + return SQ_OK; + }else if(_class(*o)->GetAttributes(key,attrs)) { + _class(*o)->SetAttributes(key,val); + v->Pop(2); + v->Push(attrs); + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong index")); +} + +SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + SQObjectPtr &key = stack_get(v,-1); + SQObjectPtr attrs; + if(type(key) == OT_NULL) { + attrs = _class(*o)->_attributes; + v->Pop(); + v->Push(attrs); + return SQ_OK; + } + else if(_class(*o)->GetAttributes(key,attrs)) { + v->Pop(); + v->Push(attrs); + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong index")); +} + +SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + SQObjectPtr &key = stack_get(v,-1); + SQTable *m = _class(*o)->_members; + SQObjectPtr val; + if(m->Get(key,val)) { + handle->_static = _isfield(val) ? SQFalse : SQTrue; + handle->_index = _member_idx(val); + v->Pop(); + return SQ_OK; + } + return sq_throwerror(v,_SC("wrong index")); +} + +SQRESULT _getmemberbyhandle(HSQUIRRELVM v,SQObjectPtr &self,HSQMEMBERHANDLE *handle,SQObjectPtr *&val) +{ + switch(type(self)) { + case OT_INSTANCE: { + SQInstance *i = _instance(self); + if(handle->_static) { + SQClass *c = i->_class; + val = &c->_methods[handle->_index].val; + } + else { + val = &i->_values[handle->_index]; + + } + } + break; + case OT_CLASS: { + SQClass *c = _class(self); + if(handle->_static) { + val = &c->_methods[handle->_index].val; + } + else { + val = &c->_defaultvalues[handle->_index].val; + } + } + break; + default: + return sq_throwerror(v,_SC("wrong type(expected class or instance)")); + } + return SQ_OK; +} + +SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle) +{ + SQObjectPtr &self = stack_get(v,idx); + SQObjectPtr *val = NULL; + if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) { + return SQ_ERROR; + } + v->Push(_realval(*val)); + return SQ_OK; +} + +SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle) +{ + SQObjectPtr &self = stack_get(v,idx); + SQObjectPtr &newval = stack_get(v,-1); + SQObjectPtr *val = NULL; + if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) { + return SQ_ERROR; + } + *val = newval; + v->Pop(); + return SQ_OK; +} + +SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + if(_class(*o)->_base) + v->Push(SQObjectPtr(_class(*o)->_base)); + else + v->PushNull(); + return SQ_OK; +} + +SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_INSTANCE,o); + v->Push(SQObjectPtr(_instance(*o)->_class)); + return SQ_OK; +} + +SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr *o = NULL; + _GETSAFE_OBJ(v, idx, OT_CLASS,o); + v->Push(_class(*o)->CreateInstance()); + return SQ_OK; +} + +void sq_weakref(HSQUIRRELVM v,SQInteger idx) +{ + SQObject &o=stack_get(v,idx); + if(ISREFCOUNTED(type(o))) { + v->Push(_refcounted(o)->GetWeakRef(type(o))); + return; + } + v->Push(o); +} + +SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr &o = stack_get(v,idx); + if(type(o) != OT_WEAKREF) { + return sq_throwerror(v,_SC("the object must be a weakref")); + } + v->Push(_weakref(o)->_obj); + return SQ_OK; +} + +SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t) +{ + SQSharedState *ss = _ss(v); + switch(t) { + case OT_TABLE: v->Push(ss->_table_default_delegate); break; + case OT_ARRAY: v->Push(ss->_array_default_delegate); break; + case OT_STRING: v->Push(ss->_string_default_delegate); break; + case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break; + case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break; + case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break; + case OT_THREAD: v->Push(ss->_thread_default_delegate); break; + case OT_CLASS: v->Push(ss->_class_default_delegate); break; + case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break; + case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break; + default: return sq_throwerror(v,_SC("the type doesn't have a default delegate")); + } + return SQ_OK; +} + +SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx) +{ + SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val; + if(type(o) == OT_GENERATOR) { + return sq_throwerror(v,_SC("cannot iterate a generator")); + } + int faketojump; + if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump)) + return SQ_ERROR; + if(faketojump != 666) { + v->Push(realkey); + v->Push(val); + return SQ_OK; + } + return SQ_ERROR; +} + +struct BufState{ + const SQChar *buf; + SQInteger ptr; + SQInteger size; +}; + +SQInteger buf_lexfeed(SQUserPointer file) +{ + BufState *buf=(BufState*)file; + if(buf->size<(buf->ptr+1)) + return 0; + return buf->buf[buf->ptr++]; +} + +SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) { + BufState buf; + buf.buf = s; + buf.size = size; + buf.ptr = 0; + return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror); +} + +void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx) +{ + dest->Push(stack_get(src,idx)); +} + +void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc) +{ + _ss(v)->_printfunc = printfunc; + _ss(v)->_errorfunc = errfunc; +} + +SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v) +{ + return _ss(v)->_printfunc; +} + +SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v) +{ + return _ss(v)->_errorfunc; +} + +void *sq_malloc(SQUnsignedInteger size) +{ + return SQ_MALLOC(size); +} + +void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize) +{ + return SQ_REALLOC(p,oldsize,newsize); +} + +void sq_free(void *p,SQUnsignedInteger size) +{ + SQ_FREE(p,size); +} diff --git a/squirrel_3_0_1_stable/squirrel/sqarray.h b/squirrel_3_0_1_stable/squirrel/sqarray.h index c3a57abcc..e9b746657 100644 --- a/squirrel_3_0_1_stable/squirrel/sqarray.h +++ b/squirrel_3_0_1_stable/squirrel/sqarray.h @@ -1,94 +1,94 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQARRAY_H_
-#define _SQARRAY_H_
-
-struct SQArray : public CHAINABLE_OBJ
-{
-private:
- SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
- ~SQArray()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
-public:
- static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){
- SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));
- new (newarray) SQArray(ss,nInitialSize);
- return newarray;
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- SQObjectType GetType() {return OT_ARRAY;}
-#endif
- void Finalize(){
- _values.resize(0);
- }
- bool Get(const SQInteger nidx,SQObjectPtr &val)
- {
- if(nidx>=0 && nidx<(SQInteger)_values.size()){
- SQObjectPtr &o = _values[nidx];
- val = _realval(o);
- return true;
- }
- else return false;
- }
- bool Set(const SQInteger nidx,const SQObjectPtr &val)
- {
- if(nidx>=0 && nidx<(SQInteger)_values.size()){
- _values[nidx]=val;
- return true;
- }
- else return false;
- }
- SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
- {
- SQUnsignedInteger idx=TranslateIndex(refpos);
- while(idx<_values.size()){
- //first found
- outkey=(SQInteger)idx;
- SQObjectPtr &o = _values[idx];
- outval = _realval(o);
- //return idx for the next iteration
- return ++idx;
- }
- //nothing to iterate anymore
- return -1;
- }
- SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),0); anew->_values.copy(_values); return anew; }
- SQInteger Size() const {return _values.size();}
- void Resize(SQInteger size)
- {
- SQObjectPtr _null;
- Resize(size,_null);
- }
- void Resize(SQInteger size,SQObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); }
- void Reserve(SQInteger size) { _values.reserve(size); }
- void Append(const SQObject &o){_values.push_back(o);}
- void Extend(const SQArray *a);
- SQObjectPtr &Top(){return _values.top();}
- void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
- bool Insert(SQInteger idx,const SQObject &val){
- if(idx < 0 || idx > (SQInteger)_values.size())
- return false;
- _values.insert(idx,val);
- return true;
- }
- void ShrinkIfNeeded() {
- if(_values.size() <= _values.capacity()>>2) //shrink the array
- _values.shrinktofit();
- }
- bool Remove(SQInteger idx){
- if(idx < 0 || idx >= (SQInteger)_values.size())
- return false;
- _values.remove(idx);
- ShrinkIfNeeded();
- return true;
- }
- void Release()
- {
- sq_delete(this,SQArray);
- }
-
- SQObjectPtrVec _values;
-};
-#endif //_SQARRAY_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQARRAY_H_ +#define _SQARRAY_H_ + +struct SQArray : public CHAINABLE_OBJ +{ +private: + SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} + ~SQArray() + { + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); + } +public: + static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){ + SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray)); + new (newarray) SQArray(ss,nInitialSize); + return newarray; + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + SQObjectType GetType() {return OT_ARRAY;} +#endif + void Finalize(){ + _values.resize(0); + } + bool Get(const SQInteger nidx,SQObjectPtr &val) + { + if(nidx>=0 && nidx<(SQInteger)_values.size()){ + SQObjectPtr &o = _values[nidx]; + val = _realval(o); + return true; + } + else return false; + } + bool Set(const SQInteger nidx,const SQObjectPtr &val) + { + if(nidx>=0 && nidx<(SQInteger)_values.size()){ + _values[nidx]=val; + return true; + } + else return false; + } + SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval) + { + SQUnsignedInteger idx=TranslateIndex(refpos); + while(idx<_values.size()){ + //first found + outkey=(SQInteger)idx; + SQObjectPtr &o = _values[idx]; + outval = _realval(o); + //return idx for the next iteration + return ++idx; + } + //nothing to iterate anymore + return -1; + } + SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),0); anew->_values.copy(_values); return anew; } + SQInteger Size() const {return _values.size();} + void Resize(SQInteger size) + { + SQObjectPtr _null; + Resize(size,_null); + } + void Resize(SQInteger size,SQObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); } + void Reserve(SQInteger size) { _values.reserve(size); } + void Append(const SQObject &o){_values.push_back(o);} + void Extend(const SQArray *a); + SQObjectPtr &Top(){return _values.top();} + void Pop(){_values.pop_back(); ShrinkIfNeeded(); } + bool Insert(SQInteger idx,const SQObject &val){ + if(idx < 0 || idx > (SQInteger)_values.size()) + return false; + _values.insert(idx,val); + return true; + } + void ShrinkIfNeeded() { + if(_values.size() <= _values.capacity()>>2) //shrink the array + _values.shrinktofit(); + } + bool Remove(SQInteger idx){ + if(idx < 0 || idx >= (SQInteger)_values.size()) + return false; + _values.remove(idx); + ShrinkIfNeeded(); + return true; + } + void Release() + { + sq_delete(this,SQArray); + } + + SQObjectPtrVec _values; +}; +#endif //_SQARRAY_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqbaselib.cpp b/squirrel_3_0_1_stable/squirrel/sqbaselib.cpp index 1e9ae1445..c11c4d9bd 100644 --- a/squirrel_3_0_1_stable/squirrel/sqbaselib.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqbaselib.cpp @@ -1,1110 +1,1110 @@ -/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqclass.h"
-#include <stdlib.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-bool str2num(const SQChar *s,SQObjectPtr &res)
-{
- SQChar *end;
- if(scstrstr(s,_SC("."))){
- SQFloat r = SQFloat(scstrtod(s,&end));
- if(s == end) return false;
- res = r;
- return true;
- }
- else{
- SQInteger r = SQInteger(scstrtol(s,&end,10));
- if(s == end) return false;
- res = r;
- return true;
- }
-}
-
-static SQInteger base_dummy(HSQUIRRELVM v)
-{
- return 0;
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-static SQInteger base_collectgarbage(HSQUIRRELVM v)
-{
- sq_pushinteger(v, sq_collectgarbage(v));
- return 1;
-}
-static SQInteger base_resurectureachable(HSQUIRRELVM v)
-{
- sq_resurrectunreachable(v);
- return 1;
-}
-#endif
-
-static SQInteger base_getroottable(HSQUIRRELVM v)
-{
- v->Push(v->_roottable);
- return 1;
-}
-
-static SQInteger base_getconsttable(HSQUIRRELVM v)
-{
- v->Push(_ss(v)->_consts);
- return 1;
-}
-
-
-static SQInteger base_setroottable(HSQUIRRELVM v)
-{
- SQObjectPtr o = v->_roottable;
- if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR;
- v->Push(o);
- return 1;
-}
-
-static SQInteger base_setconsttable(HSQUIRRELVM v)
-{
- SQObjectPtr o = _ss(v)->_consts;
- if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR;
- v->Push(o);
- return 1;
-}
-
-static SQInteger base_seterrorhandler(HSQUIRRELVM v)
-{
- sq_seterrorhandler(v);
- return 0;
-}
-
-static SQInteger base_setdebughook(HSQUIRRELVM v)
-{
- sq_setdebughook(v);
- return 0;
-}
-
-static SQInteger base_enabledebuginfo(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,2);
-
- sq_enabledebuginfo(v,SQVM::IsFalse(o)?SQFalse:SQTrue);
- return 0;
-}
-
-static SQInteger __getcallstackinfos(HSQUIRRELVM v,SQInteger level)
-{
- SQStackInfos si;
- SQInteger seq = 0;
- const SQChar *name = NULL;
-
- if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si)))
- {
- const SQChar *fn = _SC("unknown");
- const SQChar *src = _SC("unknown");
- if(si.funcname)fn = si.funcname;
- if(si.source)src = si.source;
- sq_newtable(v);
- sq_pushstring(v, _SC("func"), -1);
- sq_pushstring(v, fn, -1);
- sq_newslot(v, -3, SQFalse);
- sq_pushstring(v, _SC("src"), -1);
- sq_pushstring(v, src, -1);
- sq_newslot(v, -3, SQFalse);
- sq_pushstring(v, _SC("line"), -1);
- sq_pushinteger(v, si.line);
- sq_newslot(v, -3, SQFalse);
- sq_pushstring(v, _SC("locals"), -1);
- sq_newtable(v);
- seq=0;
- while ((name = sq_getlocal(v, level, seq))) {
- sq_pushstring(v, name, -1);
- sq_push(v, -2);
- sq_newslot(v, -4, SQFalse);
- sq_pop(v, 1);
- seq++;
- }
- sq_newslot(v, -3, SQFalse);
- return 1;
- }
-
- return 0;
-}
-static SQInteger base_getstackinfos(HSQUIRRELVM v)
-{
- SQInteger level;
- sq_getinteger(v, -1, &level);
- return __getcallstackinfos(v,level);
-}
-
-static SQInteger base_assert(HSQUIRRELVM v)
-{
- if(SQVM::IsFalse(stack_get(v,2))){
- return sq_throwerror(v,_SC("assertion failed"));
- }
- return 0;
-}
-
-static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o)
-{
- SQInteger top = sq_gettop(v);
- sidx=0;
- eidx=0;
- o=stack_get(v,1);
- SQObjectPtr &start=stack_get(v,2);
- if(type(start)!=OT_NULL && sq_isnumeric(start)){
- sidx=tointeger(start);
- }
- if(top>2){
- SQObjectPtr &end=stack_get(v,3);
- if(sq_isnumeric(end)){
- eidx=tointeger(end);
- }
- }
- else {
- eidx = sq_getsize(v,1);
- }
- return 1;
-}
-
-static SQInteger base_print(HSQUIRRELVM v)
-{
- const SQChar *str;
- sq_tostring(v,2);
- sq_getstring(v,-1,&str);
- if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str);
- return 0;
-}
-
-static SQInteger base_error(HSQUIRRELVM v)
-{
- const SQChar *str;
- sq_tostring(v,2);
- sq_getstring(v,-1,&str);
- if(_ss(v)->_errorfunc) _ss(v)->_errorfunc(v,_SC("%s"),str);
- return 0;
-}
-
-static SQInteger base_compilestring(HSQUIRRELVM v)
-{
- SQInteger nargs=sq_gettop(v);
- const SQChar *src=NULL,*name=_SC("unnamedbuffer");
- SQInteger size;
- sq_getstring(v,2,&src);
- size=sq_getsize(v,2);
- if(nargs>2){
- sq_getstring(v,3,&name);
- }
- if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse)))
- return 1;
- else
- return SQ_ERROR;
-}
-
-static SQInteger base_newthread(HSQUIRRELVM v)
-{
- SQObjectPtr &func = stack_get(v,2);
- SQInteger stksize = (_closure(func)->_function->_stacksize << 1) +2;
- HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);
- sq_move(newv,v,-2);
- return 1;
-}
-
-static SQInteger base_suspend(HSQUIRRELVM v)
-{
- return sq_suspendvm(v);
-}
-
-static SQInteger base_array(HSQUIRRELVM v)
-{
- SQArray *a;
- SQObject &size = stack_get(v,2);
- if(sq_gettop(v) > 2) {
- a = SQArray::Create(_ss(v),0);
- a->Resize(tointeger(size),stack_get(v,3));
- }
- else {
- a = SQArray::Create(_ss(v),tointeger(size));
- }
- v->Push(a);
- return 1;
-}
-
-static SQInteger base_type(HSQUIRRELVM v)
-{
- SQObjectPtr &o = stack_get(v,2);
- v->Push(SQString::Create(_ss(v),GetTypeName(o),-1));
- return 1;
-}
-
-static SQInteger base_callee(HSQUIRRELVM v)
-{
- if(v->_callsstacksize > 1)
- {
- v->Push(v->_callsstack[v->_callsstacksize - 2]._closure);
- return 1;
- }
- return sq_throwerror(v,_SC("no closure in the calls stack"));
-}
-
-static SQRegFunction base_funcs[]={
- //generic
- {_SC("seterrorhandler"),base_seterrorhandler,2, NULL},
- {_SC("setdebughook"),base_setdebughook,2, NULL},
- {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL},
- {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},
- {_SC("getroottable"),base_getroottable,1, NULL},
- {_SC("setroottable"),base_setroottable,2, NULL},
- {_SC("getconsttable"),base_getconsttable,1, NULL},
- {_SC("setconsttable"),base_setconsttable,2, NULL},
- {_SC("assert"),base_assert,2, NULL},
- {_SC("print"),base_print,2, NULL},
- {_SC("error"),base_error,2, NULL},
- {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},
- {_SC("newthread"),base_newthread,2, _SC(".c")},
- {_SC("suspend"),base_suspend,-1, NULL},
- {_SC("array"),base_array,-2, _SC(".n")},
- {_SC("type"),base_type,2, NULL},
- {_SC("callee"),base_callee,0,NULL},
- {_SC("dummy"),base_dummy,0,NULL},
-#ifndef NO_GARBAGE_COLLECTOR
- {_SC("collectgarbage"),base_collectgarbage,0, NULL},
- {_SC("resurrectunreachable"),base_resurectureachable,0, NULL},
-#endif
- {0,0}
-};
-
-void sq_base_register(HSQUIRRELVM v)
-{
- SQInteger i=0;
- sq_pushroottable(v);
- while(base_funcs[i].name!=0) {
- sq_pushstring(v,base_funcs[i].name,-1);
- sq_newclosure(v,base_funcs[i].f,0);
- sq_setnativeclosurename(v,-1,base_funcs[i].name);
- sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask);
- sq_newslot(v,-3, SQFalse);
- i++;
- }
-
- sq_pushstring(v,_SC("_versionnumber_"),-1);
- sq_pushinteger(v,SQUIRREL_VERSION_NUMBER);
- sq_newslot(v,-3, SQFalse);
- sq_pushstring(v,_SC("_version_"),-1);
- sq_pushstring(v,SQUIRREL_VERSION,-1);
- sq_newslot(v,-3, SQFalse);
- sq_pushstring(v,_SC("_charsize_"),-1);
- sq_pushinteger(v,sizeof(SQChar));
- sq_newslot(v,-3, SQFalse);
- sq_pushstring(v,_SC("_intsize_"),-1);
- sq_pushinteger(v,sizeof(SQInteger));
- sq_newslot(v,-3, SQFalse);
- sq_pushstring(v,_SC("_floatsize_"),-1);
- sq_pushinteger(v,sizeof(SQFloat));
- sq_newslot(v,-3, SQFalse);
- sq_pop(v,1);
-}
-
-static SQInteger default_delegate_len(HSQUIRRELVM v)
-{
- v->Push(SQInteger(sq_getsize(v,1)));
- return 1;
-}
-
-static SQInteger default_delegate_tofloat(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,1);
- switch(type(o)){
- case OT_STRING:{
- SQObjectPtr res;
- if(str2num(_stringval(o),res)){
- v->Push(SQObjectPtr(tofloat(res)));
- break;
- }}
- return sq_throwerror(v, _SC("cannot convert the string"));
- break;
- case OT_INTEGER:case OT_FLOAT:
- v->Push(SQObjectPtr(tofloat(o)));
- break;
- case OT_BOOL:
- v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0)));
- break;
- default:
- v->PushNull();
- break;
- }
- return 1;
-}
-
-static SQInteger default_delegate_tointeger(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,1);
- switch(type(o)){
- case OT_STRING:{
- SQObjectPtr res;
- if(str2num(_stringval(o),res)){
- v->Push(SQObjectPtr(tointeger(res)));
- break;
- }}
- return sq_throwerror(v, _SC("cannot convert the string"));
- break;
- case OT_INTEGER:case OT_FLOAT:
- v->Push(SQObjectPtr(tointeger(o)));
- break;
- case OT_BOOL:
- v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0));
- break;
- default:
- v->PushNull();
- break;
- }
- return 1;
-}
-
-static SQInteger default_delegate_tostring(HSQUIRRELVM v)
-{
- sq_tostring(v,1);
- return 1;
-}
-
-static SQInteger obj_delegate_weakref(HSQUIRRELVM v)
-{
- sq_weakref(v,1);
- return 1;
-}
-
-static SQInteger obj_clear(HSQUIRRELVM v)
-{
- return sq_clear(v,-1);
-}
-
-
-static SQInteger number_delegate_tochar(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- SQChar c = (SQChar)tointeger(o);
- v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1));
- return 1;
-}
-
-
-
-/////////////////////////////////////////////////////////////////
-//TABLE DEFAULT DELEGATE
-
-static SQInteger table_rawdelete(HSQUIRRELVM v)
-{
- if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue)))
- return SQ_ERROR;
- return 1;
-}
-
-
-static SQInteger container_rawexists(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_rawget(v,-2))) {
- sq_pushbool(v,SQTrue);
- return 1;
- }
- sq_pushbool(v,SQFalse);
- return 1;
-}
-
-static SQInteger container_rawset(HSQUIRRELVM v)
-{
- return sq_rawset(v,-3);
-}
-
-
-static SQInteger container_rawget(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR;
-}
-
-static SQInteger table_setdelegate(HSQUIRRELVM v)
-{
- if(SQ_FAILED(sq_setdelegate(v,-2)))
- return SQ_ERROR;
- sq_push(v,-1); // -1 because sq_setdelegate pops 1
- return 1;
-}
-
-static SQInteger table_getdelegate(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_getdelegate(v,-1))?1:SQ_ERROR;
-}
-
-SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
- {_SC("len"),default_delegate_len,1, _SC("t")},
- {_SC("rawget"),container_rawget,2, _SC("t")},
- {_SC("rawset"),container_rawset,3, _SC("t")},
- {_SC("rawdelete"),table_rawdelete,2, _SC("t")},
- {_SC("rawin"),container_rawexists,2, _SC("t")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("clear"),obj_clear,1, _SC(".")},
- {_SC("setdelegate"),table_setdelegate,2, _SC(".t|o")},
- {_SC("getdelegate"),table_getdelegate,1, _SC(".")},
- {0,0}
-};
-
-//ARRAY DEFAULT DELEGATE///////////////////////////////////////
-
-static SQInteger array_append(HSQUIRRELVM v)
-{
- return sq_arrayappend(v,-2);
-}
-
-static SQInteger array_extend(HSQUIRRELVM v)
-{
- _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));
- return 0;
-}
-
-static SQInteger array_reverse(HSQUIRRELVM v)
-{
- return sq_arrayreverse(v,-1);
-}
-
-static SQInteger array_pop(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;
-}
-
-static SQInteger array_top(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- if(_array(o)->Size()>0){
- v->Push(_array(o)->Top());
- return 1;
- }
- else return sq_throwerror(v,_SC("top() on a empty array"));
-}
-
-static SQInteger array_insert(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- SQObject &idx=stack_get(v,2);
- SQObject &val=stack_get(v,3);
- if(!_array(o)->Insert(tointeger(idx),val))
- return sq_throwerror(v,_SC("index out of range"));
- return 0;
-}
-
-static SQInteger array_remove(HSQUIRRELVM v)
-{
- SQObject &o = stack_get(v, 1);
- SQObject &idx = stack_get(v, 2);
- if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type"));
- SQObjectPtr val;
- if(_array(o)->Get(tointeger(idx), val)) {
- _array(o)->Remove(tointeger(idx));
- v->Push(val);
- return 1;
- }
- return sq_throwerror(v, _SC("idx out of range"));
-}
-
-static SQInteger array_resize(HSQUIRRELVM v)
-{
- SQObject &o = stack_get(v, 1);
- SQObject &nsize = stack_get(v, 2);
- SQObjectPtr fill;
- if(sq_isnumeric(nsize)) {
- if(sq_gettop(v) > 2)
- fill = stack_get(v, 3);
- _array(o)->Resize(tointeger(nsize),fill);
- return 0;
- }
- return sq_throwerror(v, _SC("size must be a number"));
-}
-
-static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) {
- SQObjectPtr temp;
- SQInteger size = src->Size();
- for(SQInteger n = 0; n < size; n++) {
- src->Get(n,temp);
- v->Push(src);
- v->Push(temp);
- if(SQ_FAILED(sq_call(v,2,SQTrue,SQFalse))) {
- return SQ_ERROR;
- }
- dest->Set(n,v->GetUp(-1));
- v->Pop();
- }
- return 0;
-}
-
-static SQInteger array_map(HSQUIRRELVM v)
-{
- SQObject &o = stack_get(v,1);
- SQInteger size = _array(o)->Size();
- SQObjectPtr ret = SQArray::Create(_ss(v),size);
- if(SQ_FAILED(__map_array(_array(ret),_array(o),v)))
- return SQ_ERROR;
- v->Push(ret);
- return 1;
-}
-
-static SQInteger array_apply(HSQUIRRELVM v)
-{
- SQObject &o = stack_get(v,1);
- if(SQ_FAILED(__map_array(_array(o),_array(o),v)))
- return SQ_ERROR;
- return 0;
-}
-
-static SQInteger array_reduce(HSQUIRRELVM v)
-{
- SQObject &o = stack_get(v,1);
- SQArray *a = _array(o);
- SQInteger size = a->Size();
- if(size == 0) {
- return 0;
- }
- SQObjectPtr res;
- a->Get(0,res);
- if(size > 1) {
- SQObjectPtr other;
- for(SQInteger n = 1; n < size; n++) {
- a->Get(n,other);
- v->Push(o);
- v->Push(res);
- v->Push(other);
- if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) {
- return SQ_ERROR;
- }
- res = v->GetUp(-1);
- v->Pop();
- }
- }
- v->Push(res);
- return 1;
-}
-
-static SQInteger array_filter(HSQUIRRELVM v)
-{
- SQObject &o = stack_get(v,1);
- SQArray *a = _array(o);
- SQObjectPtr ret = SQArray::Create(_ss(v),0);
- SQInteger size = a->Size();
- SQObjectPtr val;
- for(SQInteger n = 0; n < size; n++) {
- a->Get(n,val);
- v->Push(o);
- v->Push(n);
- v->Push(val);
- if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) {
- return SQ_ERROR;
- }
- if(!SQVM::IsFalse(v->GetUp(-1))) {
- _array(ret)->Append(val);
- }
- v->Pop();
- }
- v->Push(ret);
- return 1;
-}
-
-static SQInteger array_find(HSQUIRRELVM v)
-{
- SQObject &o = stack_get(v,1);
- SQObjectPtr &val = stack_get(v,2);
- SQArray *a = _array(o);
- SQInteger size = a->Size();
- SQObjectPtr temp;
- for(SQInteger n = 0; n < size; n++) {
- bool res = false;
- a->Get(n,temp);
- if(SQVM::IsEqual(temp,val,res) && res) {
- v->Push(n);
- return 1;
- }
- }
- return 0;
-}
-
-//QSORT ala Sedgewick
-bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
-{
- if(func < 0) {
- if(!v->ObjCmp(a,b,ret)) return false;
- }
- else {
- SQInteger top = sq_gettop(v);
- sq_push(v, func);
- sq_pushroottable(v);
- v->Push(a);
- v->Push(b);
- if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {
- if(!sq_isstring( v->_lasterror))
- v->Raise_Error(_SC("compare func failed"));
- return false;
- }
- sq_getinteger(v, -1, &ret);
- sq_settop(v, top);
- return true;
- }
- return true;
-}
-//QSORT ala Sedgewick
-bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func)
-{
- SQInteger i, j;
- SQArray *a=_array(arr);
- SQObjectPtr pivot,t;
- if( l < r ){
- pivot = a->_values[l];
- i = l; j = r+1;
- while(1){
- SQInteger ret;
- do {
- ++i;
- if(i > r) break;
- if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret))
- return false;
- } while( ret <= 0);
- do {
- --j;
- if ( j < 0 ) {
- v->Raise_Error( _SC("Invalid qsort, probably compare function defect") );
- return false;
- }
- if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret))
- return false;
- }
- while( ret > 0 );
- if( i >= j ) break;
- t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t;
- }
- t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t;
- if(!_qsort( v, arr, l, j-1,func)) return false;
- if(!_qsort( v, arr, j+1, r,func)) return false;
- }
- return true;
-}
-
-static SQInteger array_sort(HSQUIRRELVM v)
-{
- SQInteger func = -1;
- SQObjectPtr &o = stack_get(v,1);
- //SQObject &funcobj = stack_get(v,2);
- if(_array(o)->Size() > 1) {
- if(sq_gettop(v) == 2 /*&& type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE*/) func = 2;
- if(!_qsort(v, o, 0, _array(o)->Size()-1, func))
- return SQ_ERROR;
-
- }
- return 0;
-}
-static SQInteger array_slice(HSQUIRRELVM v)
-{
- SQInteger sidx,eidx;
- SQObjectPtr o;
- if(get_slice_params(v,sidx,eidx,o)==-1)return -1;
- SQInteger alen = _array(o)->Size();
- if(sidx < 0)sidx = alen + sidx;
- if(eidx < 0)eidx = alen + eidx;
- if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes"));
- if(eidx > alen)return sq_throwerror(v,_SC("slice out of range"));
- SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);
- SQObjectPtr t;
- SQInteger count=0;
- for(SQInteger i=sidx;i<eidx;i++){
- _array(o)->Get(i,t);
- arr->Set(count++,t);
- }
- v->Push(arr);
- return 1;
-
-}
-
-SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
- {_SC("len"),default_delegate_len,1, _SC("a")},
- {_SC("append"),array_append,2, _SC("a")},
- {_SC("extend"),array_extend,2, _SC("aa")},
- {_SC("push"),array_append,2, _SC("a")},
- {_SC("pop"),array_pop,1, _SC("a")},
- {_SC("top"),array_top,1, _SC("a")},
- {_SC("insert"),array_insert,3, _SC("an")},
- {_SC("remove"),array_remove,2, _SC("an")},
- {_SC("resize"),array_resize,-2, _SC("an")},
- {_SC("reverse"),array_reverse,1, _SC("a")},
- {_SC("sort"),array_sort,-1, _SC("ac")},
- {_SC("slice"),array_slice,-1, _SC("ann")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("clear"),obj_clear,1, _SC(".")},
- {_SC("map"),array_map,2, _SC("ac")},
- {_SC("apply"),array_apply,2, _SC("ac")},
- {_SC("reduce"),array_reduce,2, _SC("ac")},
- {_SC("filter"),array_filter,2, _SC("ac")},
- {_SC("find"),array_find,2, _SC("a.")},
- {0,0}
-};
-
-//STRING DEFAULT DELEGATE//////////////////////////
-static SQInteger string_slice(HSQUIRRELVM v)
-{
- SQInteger sidx,eidx;
- SQObjectPtr o;
- if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;
- SQInteger slen = _string(o)->_len;
- if(sidx < 0)sidx = slen + sidx;
- if(eidx < 0)eidx = slen + eidx;
- if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes"));
- if(eidx > slen) return sq_throwerror(v,_SC("slice out of range"));
- v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));
- return 1;
-}
-
-static SQInteger string_find(HSQUIRRELVM v)
-{
- SQInteger top,start_idx=0;
- const SQChar *str,*substr,*ret;
- if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){
- if(top>2)sq_getinteger(v,3,&start_idx);
- if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){
- ret=scstrstr(&str[start_idx],substr);
- if(ret){
- sq_pushinteger(v,(SQInteger)(ret-str));
- return 1;
- }
- }
- return 0;
- }
- return sq_throwerror(v,_SC("invalid param"));
-}
-
-#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \
-{ \
- SQObject str=stack_get(v,1); \
- SQInteger len=_string(str)->_len; \
- const SQChar *sThis=_stringval(str); \
- SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \
- for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \
- v->Push(SQString::Create(_ss(v),sNew,len)); \
- return 1; \
-}
-
-
-STRING_TOFUNCZ(tolower)
-STRING_TOFUNCZ(toupper)
-
-SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
- {_SC("len"),default_delegate_len,1, _SC("s")},
- {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")},
- {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("slice"),string_slice,-1, _SC(" s n n")},
- {_SC("find"),string_find,-2, _SC("s s n ")},
- {_SC("tolower"),string_tolower,1, _SC("s")},
- {_SC("toupper"),string_toupper,1, _SC("s")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {0,0}
-};
-
-//INTEGER DEFAULT DELEGATE//////////////////////////
-SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
- {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},
- {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {0,0}
-};
-
-//CLOSURE DEFAULT DELEGATE//////////////////////////
-static SQInteger closure_pcall(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR;
-}
-
-static SQInteger closure_call(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR;
-}
-
-static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror)
-{
- SQArray *aparams=_array(stack_get(v,2));
- SQInteger nparams=aparams->Size();
- v->Push(stack_get(v,1));
- for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]);
- return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR;
-}
-
-static SQInteger closure_acall(HSQUIRRELVM v)
-{
- return _closure_acall(v,SQTrue);
-}
-
-static SQInteger closure_pacall(HSQUIRRELVM v)
-{
- return _closure_acall(v,SQFalse);
-}
-
-static SQInteger closure_bindenv(HSQUIRRELVM v)
-{
- if(SQ_FAILED(sq_bindenv(v,1)))
- return SQ_ERROR;
- return 1;
-}
-
-static SQInteger closure_getinfos(HSQUIRRELVM v) {
- SQObject o = stack_get(v,1);
- SQTable *res = SQTable::Create(_ss(v),4);
- if(type(o) == OT_CLOSURE) {
- SQFunctionProto *f = _closure(o)->_function;
- SQInteger nparams = f->_nparameters + (f->_varparams?1:0);
- SQObjectPtr params = SQArray::Create(_ss(v),nparams);
- for(SQInteger n = 0; n<f->_nparameters; n++) {
- _array(params)->Set((SQInteger)n,f->_parameters[n]);
- }
- if(f->_varparams) {
- _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1));
- }
- res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false);
- res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name);
- res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename);
- res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params);
- res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams);
- }
- else { //OT_NATIVECLOSURE
- SQNativeClosure *nc = _nativeclosure(o);
- res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true);
- res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name);
- res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck);
- SQObjectPtr typecheck;
- if(nc->_typecheck.size() > 0) {
- typecheck =
- SQArray::Create(_ss(v), nc->_typecheck.size());
- for(SQUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) {
- _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]);
- }
- }
- res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck);
- }
- v->Push(res);
- return 1;
-}
-
-
-SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
- {_SC("call"),closure_call,-1, _SC("c")},
- {_SC("pcall"),closure_pcall,-1, _SC("c")},
- {_SC("acall"),closure_acall,2, _SC("ca")},
- {_SC("pacall"),closure_pacall,2, _SC("ca")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")},
- {_SC("getinfos"),closure_getinfos,1, _SC("c")},
- {0,0}
-};
-
-//GENERATOR DEFAULT DELEGATE
-static SQInteger generator_getstatus(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- switch(_generator(o)->_state){
- case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break;
- case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break;
- case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break;
- }
- return 1;
-}
-
-SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
- {_SC("getstatus"),generator_getstatus,1, _SC("g")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0}
-};
-
-//THREAD DEFAULT DELEGATE
-static SQInteger thread_call(HSQUIRRELVM v)
-{
- SQObjectPtr o = stack_get(v,1);
- if(type(o) == OT_THREAD) {
- SQInteger nparams = sq_gettop(v);
- _thread(o)->Push(_thread(o)->_roottable);
- for(SQInteger i = 2; i<(nparams+1); i++)
- sq_move(_thread(o),v,i);
- if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) {
- sq_move(v,_thread(o),-1);
- sq_pop(_thread(o),1);
- return 1;
- }
- v->_lasterror = _thread(o)->_lasterror;
- return SQ_ERROR;
- }
- return sq_throwerror(v,_SC("wrong parameter"));
-}
-
-static SQInteger thread_wakeup(HSQUIRRELVM v)
-{
- SQObjectPtr o = stack_get(v,1);
- if(type(o) == OT_THREAD) {
- SQVM *thread = _thread(o);
- SQInteger state = sq_getvmstate(thread);
- if(state != SQ_VMSTATE_SUSPENDED) {
- switch(state) {
- case SQ_VMSTATE_IDLE:
- return sq_throwerror(v,_SC("cannot wakeup a idle thread"));
- break;
- case SQ_VMSTATE_RUNNING:
- return sq_throwerror(v,_SC("cannot wakeup a running thread"));
- break;
- }
- }
-
- SQInteger wakeupret = sq_gettop(v)>1?1:0;
- if(wakeupret) {
- sq_move(thread,v,2);
- }
- if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) {
- sq_move(v,thread,-1);
- sq_pop(thread,1); //pop retval
- if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
- sq_settop(thread,1); //pop roottable
- }
- return 1;
- }
- sq_settop(thread,1);
- v->_lasterror = thread->_lasterror;
- return SQ_ERROR;
- }
- return sq_throwerror(v,_SC("wrong parameter"));
-}
-
-static SQInteger thread_getstatus(HSQUIRRELVM v)
-{
- SQObjectPtr &o = stack_get(v,1);
- switch(sq_getvmstate(_thread(o))) {
- case SQ_VMSTATE_IDLE:
- sq_pushstring(v,_SC("idle"),-1);
- break;
- case SQ_VMSTATE_RUNNING:
- sq_pushstring(v,_SC("running"),-1);
- break;
- case SQ_VMSTATE_SUSPENDED:
- sq_pushstring(v,_SC("suspended"),-1);
- break;
- default:
- return sq_throwerror(v,_SC("internal VM error"));
- }
- return 1;
-}
-
-static SQInteger thread_getstackinfos(HSQUIRRELVM v)
-{
- SQObjectPtr o = stack_get(v,1);
- if(type(o) == OT_THREAD) {
- SQVM *thread = _thread(o);
- SQInteger threadtop = sq_gettop(thread);
- SQInteger level;
- sq_getinteger(v,-1,&level);
- SQRESULT res = __getcallstackinfos(thread,level);
- if(SQ_FAILED(res))
- {
- sq_settop(thread,threadtop);
- if(type(thread->_lasterror) == OT_STRING) {
- sq_throwerror(v,_stringval(thread->_lasterror));
- }
- else {
- sq_throwerror(v,_SC("unknown error"));
- }
- }
- if(res > 0) {
- //some result
- sq_move(v,thread,-1);
- sq_settop(thread,threadtop);
- return 1;
- }
- //no result
- sq_settop(thread,threadtop);
- return 0;
-
- }
- return sq_throwerror(v,_SC("wrong parameter"));
-}
-
-SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
- {_SC("call"), thread_call, -1, _SC("v")},
- {_SC("wakeup"), thread_wakeup, -1, _SC("v")},
- {_SC("getstatus"), thread_getstatus, 1, _SC("v")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("getstackinfos"),thread_getstackinfos,2, _SC("vn")},
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0},
-};
-
-static SQInteger class_getattributes(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_getattributes(v,-2))?1:SQ_ERROR;
-}
-
-static SQInteger class_setattributes(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_setattributes(v,-3))?1:SQ_ERROR;
-}
-
-static SQInteger class_instance(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_createinstance(v,-1))?1:SQ_ERROR;
-}
-
-static SQInteger class_getbase(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_getbase(v,-1))?1:SQ_ERROR;
-}
-
-SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {
- {_SC("getattributes"), class_getattributes, 2, _SC("y.")},
- {_SC("setattributes"), class_setattributes, 3, _SC("y..")},
- {_SC("rawget"),container_rawget,2, _SC("y")},
- {_SC("rawset"),container_rawset,3, _SC("y")},
- {_SC("rawin"),container_rawexists,2, _SC("y")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("instance"),class_instance,1, _SC("y")},
- {_SC("getbase"),class_getbase,1, _SC("y")},
- {0,0}
-};
-
-static SQInteger instance_getclass(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_getclass(v,1)))
- return 1;
- return SQ_ERROR;
-}
-
-SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
- {_SC("getclass"), instance_getclass, 1, _SC("x")},
- {_SC("rawget"),container_rawget,2, _SC("x")},
- {_SC("rawset"),container_rawset,3, _SC("x")},
- {_SC("rawin"),container_rawexists,2, _SC("x")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0}
-};
-
-static SQInteger weakref_ref(HSQUIRRELVM v)
-{
- if(SQ_FAILED(sq_getweakrefval(v,1)))
- return SQ_ERROR;
- return 1;
-}
-
-SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {
- {_SC("ref"),weakref_ref,1, _SC("r")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0}
-};
-
+/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqclass.h" +#include <stdlib.h> +#include <stdarg.h> +#include <ctype.h> + +bool str2num(const SQChar *s,SQObjectPtr &res) +{ + SQChar *end; + if(scstrstr(s,_SC("."))){ + SQFloat r = SQFloat(scstrtod(s,&end)); + if(s == end) return false; + res = r; + return true; + } + else{ + SQInteger r = SQInteger(scstrtol(s,&end,10)); + if(s == end) return false; + res = r; + return true; + } +} + +static SQInteger base_dummy(HSQUIRRELVM v) +{ + return 0; +} + +#ifndef NO_GARBAGE_COLLECTOR +static SQInteger base_collectgarbage(HSQUIRRELVM v) +{ + sq_pushinteger(v, sq_collectgarbage(v)); + return 1; +} +static SQInteger base_resurectureachable(HSQUIRRELVM v) +{ + sq_resurrectunreachable(v); + return 1; +} +#endif + +static SQInteger base_getroottable(HSQUIRRELVM v) +{ + v->Push(v->_roottable); + return 1; +} + +static SQInteger base_getconsttable(HSQUIRRELVM v) +{ + v->Push(_ss(v)->_consts); + return 1; +} + + +static SQInteger base_setroottable(HSQUIRRELVM v) +{ + SQObjectPtr o = v->_roottable; + if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR; + v->Push(o); + return 1; +} + +static SQInteger base_setconsttable(HSQUIRRELVM v) +{ + SQObjectPtr o = _ss(v)->_consts; + if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR; + v->Push(o); + return 1; +} + +static SQInteger base_seterrorhandler(HSQUIRRELVM v) +{ + sq_seterrorhandler(v); + return 0; +} + +static SQInteger base_setdebughook(HSQUIRRELVM v) +{ + sq_setdebughook(v); + return 0; +} + +static SQInteger base_enabledebuginfo(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,2); + + sq_enabledebuginfo(v,SQVM::IsFalse(o)?SQFalse:SQTrue); + return 0; +} + +static SQInteger __getcallstackinfos(HSQUIRRELVM v,SQInteger level) +{ + SQStackInfos si; + SQInteger seq = 0; + const SQChar *name = NULL; + + if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si))) + { + const SQChar *fn = _SC("unknown"); + const SQChar *src = _SC("unknown"); + if(si.funcname)fn = si.funcname; + if(si.source)src = si.source; + sq_newtable(v); + sq_pushstring(v, _SC("func"), -1); + sq_pushstring(v, fn, -1); + sq_newslot(v, -3, SQFalse); + sq_pushstring(v, _SC("src"), -1); + sq_pushstring(v, src, -1); + sq_newslot(v, -3, SQFalse); + sq_pushstring(v, _SC("line"), -1); + sq_pushinteger(v, si.line); + sq_newslot(v, -3, SQFalse); + sq_pushstring(v, _SC("locals"), -1); + sq_newtable(v); + seq=0; + while ((name = sq_getlocal(v, level, seq))) { + sq_pushstring(v, name, -1); + sq_push(v, -2); + sq_newslot(v, -4, SQFalse); + sq_pop(v, 1); + seq++; + } + sq_newslot(v, -3, SQFalse); + return 1; + } + + return 0; +} +static SQInteger base_getstackinfos(HSQUIRRELVM v) +{ + SQInteger level; + sq_getinteger(v, -1, &level); + return __getcallstackinfos(v,level); +} + +static SQInteger base_assert(HSQUIRRELVM v) +{ + if(SQVM::IsFalse(stack_get(v,2))){ + return sq_throwerror(v,_SC("assertion failed")); + } + return 0; +} + +static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o) +{ + SQInteger top = sq_gettop(v); + sidx=0; + eidx=0; + o=stack_get(v,1); + SQObjectPtr &start=stack_get(v,2); + if(type(start)!=OT_NULL && sq_isnumeric(start)){ + sidx=tointeger(start); + } + if(top>2){ + SQObjectPtr &end=stack_get(v,3); + if(sq_isnumeric(end)){ + eidx=tointeger(end); + } + } + else { + eidx = sq_getsize(v,1); + } + return 1; +} + +static SQInteger base_print(HSQUIRRELVM v) +{ + const SQChar *str; + sq_tostring(v,2); + sq_getstring(v,-1,&str); + if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str); + return 0; +} + +static SQInteger base_error(HSQUIRRELVM v) +{ + const SQChar *str; + sq_tostring(v,2); + sq_getstring(v,-1,&str); + if(_ss(v)->_errorfunc) _ss(v)->_errorfunc(v,_SC("%s"),str); + return 0; +} + +static SQInteger base_compilestring(HSQUIRRELVM v) +{ + SQInteger nargs=sq_gettop(v); + const SQChar *src=NULL,*name=_SC("unnamedbuffer"); + SQInteger size; + sq_getstring(v,2,&src); + size=sq_getsize(v,2); + if(nargs>2){ + sq_getstring(v,3,&name); + } + if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse))) + return 1; + else + return SQ_ERROR; +} + +static SQInteger base_newthread(HSQUIRRELVM v) +{ + SQObjectPtr &func = stack_get(v,2); + SQInteger stksize = (_closure(func)->_function->_stacksize << 1) +2; + HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize); + sq_move(newv,v,-2); + return 1; +} + +static SQInteger base_suspend(HSQUIRRELVM v) +{ + return sq_suspendvm(v); +} + +static SQInteger base_array(HSQUIRRELVM v) +{ + SQArray *a; + SQObject &size = stack_get(v,2); + if(sq_gettop(v) > 2) { + a = SQArray::Create(_ss(v),0); + a->Resize(tointeger(size),stack_get(v,3)); + } + else { + a = SQArray::Create(_ss(v),tointeger(size)); + } + v->Push(a); + return 1; +} + +static SQInteger base_type(HSQUIRRELVM v) +{ + SQObjectPtr &o = stack_get(v,2); + v->Push(SQString::Create(_ss(v),GetTypeName(o),-1)); + return 1; +} + +static SQInteger base_callee(HSQUIRRELVM v) +{ + if(v->_callsstacksize > 1) + { + v->Push(v->_callsstack[v->_callsstacksize - 2]._closure); + return 1; + } + return sq_throwerror(v,_SC("no closure in the calls stack")); +} + +static SQRegFunction base_funcs[]={ + //generic + {_SC("seterrorhandler"),base_seterrorhandler,2, NULL}, + {_SC("setdebughook"),base_setdebughook,2, NULL}, + {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL}, + {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")}, + {_SC("getroottable"),base_getroottable,1, NULL}, + {_SC("setroottable"),base_setroottable,2, NULL}, + {_SC("getconsttable"),base_getconsttable,1, NULL}, + {_SC("setconsttable"),base_setconsttable,2, NULL}, + {_SC("assert"),base_assert,2, NULL}, + {_SC("print"),base_print,2, NULL}, + {_SC("error"),base_error,2, NULL}, + {_SC("compilestring"),base_compilestring,-2, _SC(".ss")}, + {_SC("newthread"),base_newthread,2, _SC(".c")}, + {_SC("suspend"),base_suspend,-1, NULL}, + {_SC("array"),base_array,-2, _SC(".n")}, + {_SC("type"),base_type,2, NULL}, + {_SC("callee"),base_callee,0,NULL}, + {_SC("dummy"),base_dummy,0,NULL}, +#ifndef NO_GARBAGE_COLLECTOR + {_SC("collectgarbage"),base_collectgarbage,0, NULL}, + {_SC("resurrectunreachable"),base_resurectureachable,0, NULL}, +#endif + {0,0} +}; + +void sq_base_register(HSQUIRRELVM v) +{ + SQInteger i=0; + sq_pushroottable(v); + while(base_funcs[i].name!=0) { + sq_pushstring(v,base_funcs[i].name,-1); + sq_newclosure(v,base_funcs[i].f,0); + sq_setnativeclosurename(v,-1,base_funcs[i].name); + sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask); + sq_newslot(v,-3, SQFalse); + i++; + } + + sq_pushstring(v,_SC("_versionnumber_"),-1); + sq_pushinteger(v,SQUIRREL_VERSION_NUMBER); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_version_"),-1); + sq_pushstring(v,SQUIRREL_VERSION,-1); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_charsize_"),-1); + sq_pushinteger(v,sizeof(SQChar)); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_intsize_"),-1); + sq_pushinteger(v,sizeof(SQInteger)); + sq_newslot(v,-3, SQFalse); + sq_pushstring(v,_SC("_floatsize_"),-1); + sq_pushinteger(v,sizeof(SQFloat)); + sq_newslot(v,-3, SQFalse); + sq_pop(v,1); +} + +static SQInteger default_delegate_len(HSQUIRRELVM v) +{ + v->Push(SQInteger(sq_getsize(v,1))); + return 1; +} + +static SQInteger default_delegate_tofloat(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,1); + switch(type(o)){ + case OT_STRING:{ + SQObjectPtr res; + if(str2num(_stringval(o),res)){ + v->Push(SQObjectPtr(tofloat(res))); + break; + }} + return sq_throwerror(v, _SC("cannot convert the string")); + break; + case OT_INTEGER:case OT_FLOAT: + v->Push(SQObjectPtr(tofloat(o))); + break; + case OT_BOOL: + v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0))); + break; + default: + v->PushNull(); + break; + } + return 1; +} + +static SQInteger default_delegate_tointeger(HSQUIRRELVM v) +{ + SQObjectPtr &o=stack_get(v,1); + switch(type(o)){ + case OT_STRING:{ + SQObjectPtr res; + if(str2num(_stringval(o),res)){ + v->Push(SQObjectPtr(tointeger(res))); + break; + }} + return sq_throwerror(v, _SC("cannot convert the string")); + break; + case OT_INTEGER:case OT_FLOAT: + v->Push(SQObjectPtr(tointeger(o))); + break; + case OT_BOOL: + v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0)); + break; + default: + v->PushNull(); + break; + } + return 1; +} + +static SQInteger default_delegate_tostring(HSQUIRRELVM v) +{ + sq_tostring(v,1); + return 1; +} + +static SQInteger obj_delegate_weakref(HSQUIRRELVM v) +{ + sq_weakref(v,1); + return 1; +} + +static SQInteger obj_clear(HSQUIRRELVM v) +{ + return sq_clear(v,-1); +} + + +static SQInteger number_delegate_tochar(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + SQChar c = (SQChar)tointeger(o); + v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1)); + return 1; +} + + + +///////////////////////////////////////////////////////////////// +//TABLE DEFAULT DELEGATE + +static SQInteger table_rawdelete(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue))) + return SQ_ERROR; + return 1; +} + + +static SQInteger container_rawexists(HSQUIRRELVM v) +{ + if(SQ_SUCCEEDED(sq_rawget(v,-2))) { + sq_pushbool(v,SQTrue); + return 1; + } + sq_pushbool(v,SQFalse); + return 1; +} + +static SQInteger container_rawset(HSQUIRRELVM v) +{ + return sq_rawset(v,-3); +} + + +static SQInteger container_rawget(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR; +} + +static SQInteger table_setdelegate(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_setdelegate(v,-2))) + return SQ_ERROR; + sq_push(v,-1); // -1 because sq_setdelegate pops 1 + return 1; +} + +static SQInteger table_getdelegate(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_getdelegate(v,-1))?1:SQ_ERROR; +} + +SQRegFunction SQSharedState::_table_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("t")}, + {_SC("rawget"),container_rawget,2, _SC("t")}, + {_SC("rawset"),container_rawset,3, _SC("t")}, + {_SC("rawdelete"),table_rawdelete,2, _SC("t")}, + {_SC("rawin"),container_rawexists,2, _SC("t")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("clear"),obj_clear,1, _SC(".")}, + {_SC("setdelegate"),table_setdelegate,2, _SC(".t|o")}, + {_SC("getdelegate"),table_getdelegate,1, _SC(".")}, + {0,0} +}; + +//ARRAY DEFAULT DELEGATE/////////////////////////////////////// + +static SQInteger array_append(HSQUIRRELVM v) +{ + return sq_arrayappend(v,-2); +} + +static SQInteger array_extend(HSQUIRRELVM v) +{ + _array(stack_get(v,1))->Extend(_array(stack_get(v,2))); + return 0; +} + +static SQInteger array_reverse(HSQUIRRELVM v) +{ + return sq_arrayreverse(v,-1); +} + +static SQInteger array_pop(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR; +} + +static SQInteger array_top(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + if(_array(o)->Size()>0){ + v->Push(_array(o)->Top()); + return 1; + } + else return sq_throwerror(v,_SC("top() on a empty array")); +} + +static SQInteger array_insert(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + SQObject &idx=stack_get(v,2); + SQObject &val=stack_get(v,3); + if(!_array(o)->Insert(tointeger(idx),val)) + return sq_throwerror(v,_SC("index out of range")); + return 0; +} + +static SQInteger array_remove(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v, 1); + SQObject &idx = stack_get(v, 2); + if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type")); + SQObjectPtr val; + if(_array(o)->Get(tointeger(idx), val)) { + _array(o)->Remove(tointeger(idx)); + v->Push(val); + return 1; + } + return sq_throwerror(v, _SC("idx out of range")); +} + +static SQInteger array_resize(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v, 1); + SQObject &nsize = stack_get(v, 2); + SQObjectPtr fill; + if(sq_isnumeric(nsize)) { + if(sq_gettop(v) > 2) + fill = stack_get(v, 3); + _array(o)->Resize(tointeger(nsize),fill); + return 0; + } + return sq_throwerror(v, _SC("size must be a number")); +} + +static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) { + SQObjectPtr temp; + SQInteger size = src->Size(); + for(SQInteger n = 0; n < size; n++) { + src->Get(n,temp); + v->Push(src); + v->Push(temp); + if(SQ_FAILED(sq_call(v,2,SQTrue,SQFalse))) { + return SQ_ERROR; + } + dest->Set(n,v->GetUp(-1)); + v->Pop(); + } + return 0; +} + +static SQInteger array_map(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQInteger size = _array(o)->Size(); + SQObjectPtr ret = SQArray::Create(_ss(v),size); + if(SQ_FAILED(__map_array(_array(ret),_array(o),v))) + return SQ_ERROR; + v->Push(ret); + return 1; +} + +static SQInteger array_apply(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + if(SQ_FAILED(__map_array(_array(o),_array(o),v))) + return SQ_ERROR; + return 0; +} + +static SQInteger array_reduce(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQArray *a = _array(o); + SQInteger size = a->Size(); + if(size == 0) { + return 0; + } + SQObjectPtr res; + a->Get(0,res); + if(size > 1) { + SQObjectPtr other; + for(SQInteger n = 1; n < size; n++) { + a->Get(n,other); + v->Push(o); + v->Push(res); + v->Push(other); + if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { + return SQ_ERROR; + } + res = v->GetUp(-1); + v->Pop(); + } + } + v->Push(res); + return 1; +} + +static SQInteger array_filter(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQArray *a = _array(o); + SQObjectPtr ret = SQArray::Create(_ss(v),0); + SQInteger size = a->Size(); + SQObjectPtr val; + for(SQInteger n = 0; n < size; n++) { + a->Get(n,val); + v->Push(o); + v->Push(n); + v->Push(val); + if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { + return SQ_ERROR; + } + if(!SQVM::IsFalse(v->GetUp(-1))) { + _array(ret)->Append(val); + } + v->Pop(); + } + v->Push(ret); + return 1; +} + +static SQInteger array_find(HSQUIRRELVM v) +{ + SQObject &o = stack_get(v,1); + SQObjectPtr &val = stack_get(v,2); + SQArray *a = _array(o); + SQInteger size = a->Size(); + SQObjectPtr temp; + for(SQInteger n = 0; n < size; n++) { + bool res = false; + a->Get(n,temp); + if(SQVM::IsEqual(temp,val,res) && res) { + v->Push(n); + return 1; + } + } + return 0; +} + +//QSORT ala Sedgewick +bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret) +{ + if(func < 0) { + if(!v->ObjCmp(a,b,ret)) return false; + } + else { + SQInteger top = sq_gettop(v); + sq_push(v, func); + sq_pushroottable(v); + v->Push(a); + v->Push(b); + if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) { + if(!sq_isstring( v->_lasterror)) + v->Raise_Error(_SC("compare func failed")); + return false; + } + sq_getinteger(v, -1, &ret); + sq_settop(v, top); + return true; + } + return true; +} +//QSORT ala Sedgewick +bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func) +{ + SQInteger i, j; + SQArray *a=_array(arr); + SQObjectPtr pivot,t; + if( l < r ){ + pivot = a->_values[l]; + i = l; j = r+1; + while(1){ + SQInteger ret; + do { + ++i; + if(i > r) break; + if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret)) + return false; + } while( ret <= 0); + do { + --j; + if ( j < 0 ) { + v->Raise_Error( _SC("Invalid qsort, probably compare function defect") ); + return false; + } + if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret)) + return false; + } + while( ret > 0 ); + if( i >= j ) break; + t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t; + } + t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t; + if(!_qsort( v, arr, l, j-1,func)) return false; + if(!_qsort( v, arr, j+1, r,func)) return false; + } + return true; +} + +static SQInteger array_sort(HSQUIRRELVM v) +{ + SQInteger func = -1; + SQObjectPtr &o = stack_get(v,1); + //SQObject &funcobj = stack_get(v,2); + if(_array(o)->Size() > 1) { + if(sq_gettop(v) == 2 /*&& type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE*/) func = 2; + if(!_qsort(v, o, 0, _array(o)->Size()-1, func)) + return SQ_ERROR; + + } + return 0; +} +static SQInteger array_slice(HSQUIRRELVM v) +{ + SQInteger sidx,eidx; + SQObjectPtr o; + if(get_slice_params(v,sidx,eidx,o)==-1)return -1; + SQInteger alen = _array(o)->Size(); + if(sidx < 0)sidx = alen + sidx; + if(eidx < 0)eidx = alen + eidx; + if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes")); + if(eidx > alen)return sq_throwerror(v,_SC("slice out of range")); + SQArray *arr=SQArray::Create(_ss(v),eidx-sidx); + SQObjectPtr t; + SQInteger count=0; + for(SQInteger i=sidx;i<eidx;i++){ + _array(o)->Get(i,t); + arr->Set(count++,t); + } + v->Push(arr); + return 1; + +} + +SQRegFunction SQSharedState::_array_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("a")}, + {_SC("append"),array_append,2, _SC("a")}, + {_SC("extend"),array_extend,2, _SC("aa")}, + {_SC("push"),array_append,2, _SC("a")}, + {_SC("pop"),array_pop,1, _SC("a")}, + {_SC("top"),array_top,1, _SC("a")}, + {_SC("insert"),array_insert,3, _SC("an")}, + {_SC("remove"),array_remove,2, _SC("an")}, + {_SC("resize"),array_resize,-2, _SC("an")}, + {_SC("reverse"),array_reverse,1, _SC("a")}, + {_SC("sort"),array_sort,-1, _SC("ac")}, + {_SC("slice"),array_slice,-1, _SC("ann")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("clear"),obj_clear,1, _SC(".")}, + {_SC("map"),array_map,2, _SC("ac")}, + {_SC("apply"),array_apply,2, _SC("ac")}, + {_SC("reduce"),array_reduce,2, _SC("ac")}, + {_SC("filter"),array_filter,2, _SC("ac")}, + {_SC("find"),array_find,2, _SC("a.")}, + {0,0} +}; + +//STRING DEFAULT DELEGATE////////////////////////// +static SQInteger string_slice(HSQUIRRELVM v) +{ + SQInteger sidx,eidx; + SQObjectPtr o; + if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1; + SQInteger slen = _string(o)->_len; + if(sidx < 0)sidx = slen + sidx; + if(eidx < 0)eidx = slen + eidx; + if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); + if(eidx > slen) return sq_throwerror(v,_SC("slice out of range")); + v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx)); + return 1; +} + +static SQInteger string_find(HSQUIRRELVM v) +{ + SQInteger top,start_idx=0; + const SQChar *str,*substr,*ret; + if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){ + if(top>2)sq_getinteger(v,3,&start_idx); + if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){ + ret=scstrstr(&str[start_idx],substr); + if(ret){ + sq_pushinteger(v,(SQInteger)(ret-str)); + return 1; + } + } + return 0; + } + return sq_throwerror(v,_SC("invalid param")); +} + +#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \ +{ \ + SQObject str=stack_get(v,1); \ + SQInteger len=_string(str)->_len; \ + const SQChar *sThis=_stringval(str); \ + SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \ + for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \ + v->Push(SQString::Create(_ss(v),sNew,len)); \ + return 1; \ +} + + +STRING_TOFUNCZ(tolower) +STRING_TOFUNCZ(toupper) + +SQRegFunction SQSharedState::_string_default_delegate_funcz[]={ + {_SC("len"),default_delegate_len,1, _SC("s")}, + {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")}, + {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")}, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("slice"),string_slice,-1, _SC(" s n n")}, + {_SC("find"),string_find,-2, _SC("s s n ")}, + {_SC("tolower"),string_tolower,1, _SC("s")}, + {_SC("toupper"),string_toupper,1, _SC("s")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {0,0} +}; + +//INTEGER DEFAULT DELEGATE////////////////////////// +SQRegFunction SQSharedState::_number_default_delegate_funcz[]={ + {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")}, + {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")}, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {0,0} +}; + +//CLOSURE DEFAULT DELEGATE////////////////////////// +static SQInteger closure_pcall(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR; +} + +static SQInteger closure_call(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR; +} + +static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror) +{ + SQArray *aparams=_array(stack_get(v,2)); + SQInteger nparams=aparams->Size(); + v->Push(stack_get(v,1)); + for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]); + return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR; +} + +static SQInteger closure_acall(HSQUIRRELVM v) +{ + return _closure_acall(v,SQTrue); +} + +static SQInteger closure_pacall(HSQUIRRELVM v) +{ + return _closure_acall(v,SQFalse); +} + +static SQInteger closure_bindenv(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_bindenv(v,1))) + return SQ_ERROR; + return 1; +} + +static SQInteger closure_getinfos(HSQUIRRELVM v) { + SQObject o = stack_get(v,1); + SQTable *res = SQTable::Create(_ss(v),4); + if(type(o) == OT_CLOSURE) { + SQFunctionProto *f = _closure(o)->_function; + SQInteger nparams = f->_nparameters + (f->_varparams?1:0); + SQObjectPtr params = SQArray::Create(_ss(v),nparams); + for(SQInteger n = 0; n<f->_nparameters; n++) { + _array(params)->Set((SQInteger)n,f->_parameters[n]); + } + if(f->_varparams) { + _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1)); + } + res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false); + res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name); + res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename); + res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params); + res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams); + } + else { //OT_NATIVECLOSURE + SQNativeClosure *nc = _nativeclosure(o); + res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true); + res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name); + res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck); + SQObjectPtr typecheck; + if(nc->_typecheck.size() > 0) { + typecheck = + SQArray::Create(_ss(v), nc->_typecheck.size()); + for(SQUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) { + _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]); + } + } + res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck); + } + v->Push(res); + return 1; +} + + +SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={ + {_SC("call"),closure_call,-1, _SC("c")}, + {_SC("pcall"),closure_pcall,-1, _SC("c")}, + {_SC("acall"),closure_acall,2, _SC("ca")}, + {_SC("pacall"),closure_pacall,2, _SC("ca")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")}, + {_SC("getinfos"),closure_getinfos,1, _SC("c")}, + {0,0} +}; + +//GENERATOR DEFAULT DELEGATE +static SQInteger generator_getstatus(HSQUIRRELVM v) +{ + SQObject &o=stack_get(v,1); + switch(_generator(o)->_state){ + case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break; + case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break; + case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break; + } + return 1; +} + +SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={ + {_SC("getstatus"),generator_getstatus,1, _SC("g")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {0,0} +}; + +//THREAD DEFAULT DELEGATE +static SQInteger thread_call(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(type(o) == OT_THREAD) { + SQInteger nparams = sq_gettop(v); + _thread(o)->Push(_thread(o)->_roottable); + for(SQInteger i = 2; i<(nparams+1); i++) + sq_move(_thread(o),v,i); + if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) { + sq_move(v,_thread(o),-1); + sq_pop(_thread(o),1); + return 1; + } + v->_lasterror = _thread(o)->_lasterror; + return SQ_ERROR; + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +static SQInteger thread_wakeup(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(type(o) == OT_THREAD) { + SQVM *thread = _thread(o); + SQInteger state = sq_getvmstate(thread); + if(state != SQ_VMSTATE_SUSPENDED) { + switch(state) { + case SQ_VMSTATE_IDLE: + return sq_throwerror(v,_SC("cannot wakeup a idle thread")); + break; + case SQ_VMSTATE_RUNNING: + return sq_throwerror(v,_SC("cannot wakeup a running thread")); + break; + } + } + + SQInteger wakeupret = sq_gettop(v)>1?1:0; + if(wakeupret) { + sq_move(thread,v,2); + } + if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) { + sq_move(v,thread,-1); + sq_pop(thread,1); //pop retval + if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { + sq_settop(thread,1); //pop roottable + } + return 1; + } + sq_settop(thread,1); + v->_lasterror = thread->_lasterror; + return SQ_ERROR; + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +static SQInteger thread_getstatus(HSQUIRRELVM v) +{ + SQObjectPtr &o = stack_get(v,1); + switch(sq_getvmstate(_thread(o))) { + case SQ_VMSTATE_IDLE: + sq_pushstring(v,_SC("idle"),-1); + break; + case SQ_VMSTATE_RUNNING: + sq_pushstring(v,_SC("running"),-1); + break; + case SQ_VMSTATE_SUSPENDED: + sq_pushstring(v,_SC("suspended"),-1); + break; + default: + return sq_throwerror(v,_SC("internal VM error")); + } + return 1; +} + +static SQInteger thread_getstackinfos(HSQUIRRELVM v) +{ + SQObjectPtr o = stack_get(v,1); + if(type(o) == OT_THREAD) { + SQVM *thread = _thread(o); + SQInteger threadtop = sq_gettop(thread); + SQInteger level; + sq_getinteger(v,-1,&level); + SQRESULT res = __getcallstackinfos(thread,level); + if(SQ_FAILED(res)) + { + sq_settop(thread,threadtop); + if(type(thread->_lasterror) == OT_STRING) { + sq_throwerror(v,_stringval(thread->_lasterror)); + } + else { + sq_throwerror(v,_SC("unknown error")); + } + } + if(res > 0) { + //some result + sq_move(v,thread,-1); + sq_settop(thread,threadtop); + return 1; + } + //no result + sq_settop(thread,threadtop); + return 0; + + } + return sq_throwerror(v,_SC("wrong parameter")); +} + +SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = { + {_SC("call"), thread_call, -1, _SC("v")}, + {_SC("wakeup"), thread_wakeup, -1, _SC("v")}, + {_SC("getstatus"), thread_getstatus, 1, _SC("v")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("getstackinfos"),thread_getstackinfos,2, _SC("vn")}, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {0,0}, +}; + +static SQInteger class_getattributes(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_getattributes(v,-2))?1:SQ_ERROR; +} + +static SQInteger class_setattributes(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_setattributes(v,-3))?1:SQ_ERROR; +} + +static SQInteger class_instance(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_createinstance(v,-1))?1:SQ_ERROR; +} + +static SQInteger class_getbase(HSQUIRRELVM v) +{ + return SQ_SUCCEEDED(sq_getbase(v,-1))?1:SQ_ERROR; +} + +SQRegFunction SQSharedState::_class_default_delegate_funcz[] = { + {_SC("getattributes"), class_getattributes, 2, _SC("y.")}, + {_SC("setattributes"), class_setattributes, 3, _SC("y..")}, + {_SC("rawget"),container_rawget,2, _SC("y")}, + {_SC("rawset"),container_rawset,3, _SC("y")}, + {_SC("rawin"),container_rawexists,2, _SC("y")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {_SC("instance"),class_instance,1, _SC("y")}, + {_SC("getbase"),class_getbase,1, _SC("y")}, + {0,0} +}; + +static SQInteger instance_getclass(HSQUIRRELVM v) +{ + if(SQ_SUCCEEDED(sq_getclass(v,1))) + return 1; + return SQ_ERROR; +} + +SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = { + {_SC("getclass"), instance_getclass, 1, _SC("x")}, + {_SC("rawget"),container_rawget,2, _SC("x")}, + {_SC("rawset"),container_rawset,3, _SC("x")}, + {_SC("rawin"),container_rawexists,2, _SC("x")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {0,0} +}; + +static SQInteger weakref_ref(HSQUIRRELVM v) +{ + if(SQ_FAILED(sq_getweakrefval(v,1))) + return SQ_ERROR; + return 1; +} + +SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = { + {_SC("ref"),weakref_ref,1, _SC("r")}, + {_SC("weakref"),obj_delegate_weakref,1, NULL }, + {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, + {0,0} +}; + diff --git a/squirrel_3_0_1_stable/squirrel/sqclass.cpp b/squirrel_3_0_1_stable/squirrel/sqclass.cpp index 1f26cc92f..dcee77d70 100644 --- a/squirrel_3_0_1_stable/squirrel/sqclass.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqclass.cpp @@ -1,213 +1,213 @@ -/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqtable.h"
-#include "sqclass.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-
-
-
-SQClass::SQClass(SQSharedState *ss,SQClass *base)
-{
- _base = base;
- _typetag = 0;
- _hook = NULL;
- _udsize = 0;
- _locked = false;
- _constructoridx = -1;
- if(_base) {
- _constructoridx = _base->_constructoridx;
- _udsize = _base->_udsize;
- _defaultvalues.copy(base->_defaultvalues);
- _methods.copy(base->_methods);
- _COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST);
- __ObjAddRef(_base);
- }
- _members = base?base->_members->Clone() : SQTable::Create(ss,0);
- __ObjAddRef(_members);
-
- INIT_CHAIN();
- ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
-}
-
-void SQClass::Finalize() {
- _attributes.Null();
- _defaultvalues.resize(0);
- _methods.resize(0);
- _NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST);
- __ObjRelease(_members);
- if(_base) {
- __ObjRelease(_base);
- }
-}
-
-SQClass::~SQClass()
-{
- REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
- Finalize();
-}
-
-bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
-{
- SQObjectPtr temp;
- bool belongs_to_static_table = type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic;
- if(_locked && !belongs_to_static_table)
- return false; //the class already has an instance so cannot be modified
- if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value
- {
- _defaultvalues[_member_idx(temp)].val = val;
- return true;
- }
- if(belongs_to_static_table) {
- SQInteger mmidx;
- if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) &&
- (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
- _metamethods[mmidx] = val;
- }
- else {
- SQObjectPtr theval = val;
- if(_base && type(val) == OT_CLOSURE) {
- theval = _closure(val)->Clone();
- _closure(theval)->_base = _base;
- __ObjAddRef(_base); //ref for the closure
- }
- if(type(temp) == OT_NULL) {
- bool isconstructor;
- SQVM::IsEqual(ss->_constructoridx, key, isconstructor);
- if(isconstructor) {
- _constructoridx = (SQInteger)_methods.size();
- }
- SQClassMember m;
- m.val = theval;
- _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
- _methods.push_back(m);
- }
- else {
- _methods[_member_idx(temp)].val = theval;
- }
- }
- return true;
- }
- SQClassMember m;
- m.val = val;
- _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
- _defaultvalues.push_back(m);
- return true;
-}
-
-SQInstance *SQClass::CreateInstance()
-{
- if(!_locked) Lock();
- return SQInstance::Create(_opt_ss(this),this);
-}
-
-SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
- SQObjectPtr oval;
- SQInteger idx = _members->Next(false,refpos,outkey,oval);
- if(idx != -1) {
- if(_ismethod(oval)) {
- outval = _methods[_member_idx(oval)].val;
- }
- else {
- SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
- outval = _realval(o);
- }
- }
- return idx;
-}
-
-bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
-{
- SQObjectPtr idx;
- if(_members->Get(key,idx)) {
- if(_isfield(idx))
- _defaultvalues[_member_idx(idx)].attrs = val;
- else
- _methods[_member_idx(idx)].attrs = val;
- return true;
- }
- return false;
-}
-
-bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
-{
- SQObjectPtr idx;
- if(_members->Get(key,idx)) {
- outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
- return true;
- }
- return false;
-}
-
-///////////////////////////////////////////////////////////////////////
-void SQInstance::Init(SQSharedState *ss)
-{
- _userpointer = NULL;
- _hook = NULL;
- __ObjAddRef(_class);
- _delegate = _class->_members;
- INIT_CHAIN();
- ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
-}
-
-SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)
-{
- _memsize = memsize;
- _class = c;
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- for(SQUnsignedInteger n = 0; n < nvalues; n++) {
- new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
- }
- Init(ss);
-}
-
-SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)
-{
- _memsize = memsize;
- _class = i->_class;
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- for(SQUnsignedInteger n = 0; n < nvalues; n++) {
- new (&_values[n]) SQObjectPtr(i->_values[n]);
- }
- Init(ss);
-}
-
-void SQInstance::Finalize()
-{
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- __ObjRelease(_class);
- _NULL_SQOBJECT_VECTOR(_values,nvalues);
- //for(SQUnsignedInteger i = 0; i < nvalues; i++) {
-// _values[i].Null();
-// }
-}
-
-SQInstance::~SQInstance()
-{
- REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
- if(_class){ Finalize(); } //if _class is null it was already finalized by the GC
-}
-
-bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res)
-{
- if(type(_class->_metamethods[mm]) != OT_NULL) {
- res = _class->_metamethods[mm];
- return true;
- }
- return false;
-}
-
-bool SQInstance::InstanceOf(SQClass *trg)
-{
- SQClass *parent = _class;
- while(parent != NULL) {
- if(parent == trg)
- return true;
- parent = parent->_base;
- }
- return false;
-}
+/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqtable.h" +#include "sqclass.h" +#include "sqfuncproto.h" +#include "sqclosure.h" + + + +SQClass::SQClass(SQSharedState *ss,SQClass *base) +{ + _base = base; + _typetag = 0; + _hook = NULL; + _udsize = 0; + _locked = false; + _constructoridx = -1; + if(_base) { + _constructoridx = _base->_constructoridx; + _udsize = _base->_udsize; + _defaultvalues.copy(base->_defaultvalues); + _methods.copy(base->_methods); + _COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST); + __ObjAddRef(_base); + } + _members = base?base->_members->Clone() : SQTable::Create(ss,0); + __ObjAddRef(_members); + + INIT_CHAIN(); + ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); +} + +void SQClass::Finalize() { + _attributes.Null(); + _defaultvalues.resize(0); + _methods.resize(0); + _NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST); + __ObjRelease(_members); + if(_base) { + __ObjRelease(_base); + } +} + +SQClass::~SQClass() +{ + REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); + Finalize(); +} + +bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) +{ + SQObjectPtr temp; + bool belongs_to_static_table = type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic; + if(_locked && !belongs_to_static_table) + return false; //the class already has an instance so cannot be modified + if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value + { + _defaultvalues[_member_idx(temp)].val = val; + return true; + } + if(belongs_to_static_table) { + SQInteger mmidx; + if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) && + (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) { + _metamethods[mmidx] = val; + } + else { + SQObjectPtr theval = val; + if(_base && type(val) == OT_CLOSURE) { + theval = _closure(val)->Clone(); + _closure(theval)->_base = _base; + __ObjAddRef(_base); //ref for the closure + } + if(type(temp) == OT_NULL) { + bool isconstructor; + SQVM::IsEqual(ss->_constructoridx, key, isconstructor); + if(isconstructor) { + _constructoridx = (SQInteger)_methods.size(); + } + SQClassMember m; + m.val = theval; + _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size()))); + _methods.push_back(m); + } + else { + _methods[_member_idx(temp)].val = theval; + } + } + return true; + } + SQClassMember m; + m.val = val; + _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size()))); + _defaultvalues.push_back(m); + return true; +} + +SQInstance *SQClass::CreateInstance() +{ + if(!_locked) Lock(); + return SQInstance::Create(_opt_ss(this),this); +} + +SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) +{ + SQObjectPtr oval; + SQInteger idx = _members->Next(false,refpos,outkey,oval); + if(idx != -1) { + if(_ismethod(oval)) { + outval = _methods[_member_idx(oval)].val; + } + else { + SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val; + outval = _realval(o); + } + } + return idx; +} + +bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val) +{ + SQObjectPtr idx; + if(_members->Get(key,idx)) { + if(_isfield(idx)) + _defaultvalues[_member_idx(idx)].attrs = val; + else + _methods[_member_idx(idx)].attrs = val; + return true; + } + return false; +} + +bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval) +{ + SQObjectPtr idx; + if(_members->Get(key,idx)) { + outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs); + return true; + } + return false; +} + +/////////////////////////////////////////////////////////////////////// +void SQInstance::Init(SQSharedState *ss) +{ + _userpointer = NULL; + _hook = NULL; + __ObjAddRef(_class); + _delegate = _class->_members; + INIT_CHAIN(); + ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); +} + +SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize) +{ + _memsize = memsize; + _class = c; + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger n = 0; n < nvalues; n++) { + new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val); + } + Init(ss); +} + +SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize) +{ + _memsize = memsize; + _class = i->_class; + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger n = 0; n < nvalues; n++) { + new (&_values[n]) SQObjectPtr(i->_values[n]); + } + Init(ss); +} + +void SQInstance::Finalize() +{ + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + __ObjRelease(_class); + _NULL_SQOBJECT_VECTOR(_values,nvalues); + //for(SQUnsignedInteger i = 0; i < nvalues; i++) { +// _values[i].Null(); +// } +} + +SQInstance::~SQInstance() +{ + REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); + if(_class){ Finalize(); } //if _class is null it was already finalized by the GC +} + +bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) +{ + if(type(_class->_metamethods[mm]) != OT_NULL) { + res = _class->_metamethods[mm]; + return true; + } + return false; +} + +bool SQInstance::InstanceOf(SQClass *trg) +{ + SQClass *parent = _class; + while(parent != NULL) { + if(parent == trg) + return true; + parent = parent->_base; + } + return false; +} diff --git a/squirrel_3_0_1_stable/squirrel/sqclass.h b/squirrel_3_0_1_stable/squirrel/sqclass.h index 996a3df70..5c1fe2d20 100644 --- a/squirrel_3_0_1_stable/squirrel/sqclass.h +++ b/squirrel_3_0_1_stable/squirrel/sqclass.h @@ -1,158 +1,158 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQCLASS_H_
-#define _SQCLASS_H_
-
-struct SQInstance;
-
-struct SQClassMember {
- SQObjectPtr val;
- SQObjectPtr attrs;
-};
-
-typedef sqvector<SQClassMember> SQClassMemberVec;
-
-#define MEMBER_TYPE_METHOD 0x01000000
-#define MEMBER_TYPE_FIELD 0x02000000
-
-#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)
-#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)
-#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i))
-#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i))
-#define _member_type(o) (_integer(o)&0xFF000000)
-#define _member_idx(o) (_integer(o)&0x00FFFFFF)
-
-struct SQClass : public CHAINABLE_OBJ
-{
- SQClass(SQSharedState *ss,SQClass *base);
-public:
- static SQClass* Create(SQSharedState *ss,SQClass *base) {
- SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
- new (newclass) SQClass(ss, base);
- return newclass;
- }
- ~SQClass();
- bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);
- bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
- if(_members->Get(key,val)) {
- if(_isfield(val)) {
- SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;
- val = _realval(o);
- }
- else {
- val = _methods[_member_idx(val)].val;
- }
- return true;
- }
- return false;
- }
- bool GetConstructor(SQObjectPtr &ctor)
- {
- if(_constructoridx != -1) {
- ctor = _methods[_constructoridx].val;
- return true;
- }
- return false;
- }
- bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
- bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
- void Lock() { _locked = true; if(_base) _base->Lock(); }
- void Release() {
- if (_hook) { _hook(_typetag,0);}
- sq_delete(this, SQClass);
- }
- void Finalize();
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable ** );
- SQObjectType GetType() {return OT_CLASS;}
-#endif
- SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
- SQInstance *CreateInstance();
- SQTable *_members;
- SQClass *_base;
- SQClassMemberVec _defaultvalues;
- SQClassMemberVec _methods;
- SQObjectPtr _metamethods[MT_LAST];
- SQObjectPtr _attributes;
- SQUserPointer _typetag;
- SQRELEASEHOOK _hook;
- bool _locked;
- SQInteger _constructoridx;
- SQInteger _udsize;
-};
-
-#define calcinstancesize(_theclass_) \
- (_theclass_->_udsize + sq_aligning(sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0))))
-
-struct SQInstance : public SQDelegable
-{
- void Init(SQSharedState *ss);
- SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);
- SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);
-public:
- static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {
-
- SQInteger size = calcinstancesize(theclass);
- SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
- new (newinst) SQInstance(ss, theclass,size);
- if(theclass->_udsize) {
- newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
- }
- return newinst;
- }
- SQInstance *Clone(SQSharedState *ss)
- {
- SQInteger size = calcinstancesize(_class);
- SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
- new (newinst) SQInstance(ss, this,size);
- if(_class->_udsize) {
- newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
- }
- return newinst;
- }
- ~SQInstance();
- bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
- if(_class->_members->Get(key,val)) {
- if(_isfield(val)) {
- SQObjectPtr &o = _values[_member_idx(val)];
- val = _realval(o);
- }
- else {
- val = _class->_methods[_member_idx(val)].val;
- }
- return true;
- }
- return false;
- }
- bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {
- SQObjectPtr idx;
- if(_class->_members->Get(key,idx) && _isfield(idx)) {
- _values[_member_idx(idx)] = val;
- return true;
- }
- return false;
- }
- void Release() {
- _uiRef++;
- if (_hook) { _hook(_userpointer,0);}
- _uiRef--;
- if(_uiRef > 0) return;
- SQInteger size = _memsize;
- this->~SQInstance();
- SQ_FREE(this, size);
- }
- void Finalize();
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable ** );
- SQObjectType GetType() {return OT_INSTANCE;}
-#endif
- bool InstanceOf(SQClass *trg);
- bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
-
- SQClass *_class;
- SQUserPointer _userpointer;
- SQRELEASEHOOK _hook;
- SQInteger _memsize;
- SQObjectPtr _values[1];
-};
-
-#endif //_SQCLASS_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQCLASS_H_ +#define _SQCLASS_H_ + +struct SQInstance; + +struct SQClassMember { + SQObjectPtr val; + SQObjectPtr attrs; +}; + +typedef sqvector<SQClassMember> SQClassMemberVec; + +#define MEMBER_TYPE_METHOD 0x01000000 +#define MEMBER_TYPE_FIELD 0x02000000 + +#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD) +#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD) +#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i)) +#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i)) +#define _member_type(o) (_integer(o)&0xFF000000) +#define _member_idx(o) (_integer(o)&0x00FFFFFF) + +struct SQClass : public CHAINABLE_OBJ +{ + SQClass(SQSharedState *ss,SQClass *base); +public: + static SQClass* Create(SQSharedState *ss,SQClass *base) { + SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass)); + new (newclass) SQClass(ss, base); + return newclass; + } + ~SQClass(); + bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic); + bool Get(const SQObjectPtr &key,SQObjectPtr &val) { + if(_members->Get(key,val)) { + if(_isfield(val)) { + SQObjectPtr &o = _defaultvalues[_member_idx(val)].val; + val = _realval(o); + } + else { + val = _methods[_member_idx(val)].val; + } + return true; + } + return false; + } + bool GetConstructor(SQObjectPtr &ctor) + { + if(_constructoridx != -1) { + ctor = _methods[_constructoridx].val; + return true; + } + return false; + } + bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val); + bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval); + void Lock() { _locked = true; if(_base) _base->Lock(); } + void Release() { + if (_hook) { _hook(_typetag,0);} + sq_delete(this, SQClass); + } + void Finalize(); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable ** ); + SQObjectType GetType() {return OT_CLASS;} +#endif + SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); + SQInstance *CreateInstance(); + SQTable *_members; + SQClass *_base; + SQClassMemberVec _defaultvalues; + SQClassMemberVec _methods; + SQObjectPtr _metamethods[MT_LAST]; + SQObjectPtr _attributes; + SQUserPointer _typetag; + SQRELEASEHOOK _hook; + bool _locked; + SQInteger _constructoridx; + SQInteger _udsize; +}; + +#define calcinstancesize(_theclass_) \ + (_theclass_->_udsize + sq_aligning(sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))) + +struct SQInstance : public SQDelegable +{ + void Init(SQSharedState *ss); + SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize); + SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize); +public: + static SQInstance* Create(SQSharedState *ss,SQClass *theclass) { + + SQInteger size = calcinstancesize(theclass); + SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); + new (newinst) SQInstance(ss, theclass,size); + if(theclass->_udsize) { + newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize); + } + return newinst; + } + SQInstance *Clone(SQSharedState *ss) + { + SQInteger size = calcinstancesize(_class); + SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); + new (newinst) SQInstance(ss, this,size); + if(_class->_udsize) { + newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize); + } + return newinst; + } + ~SQInstance(); + bool Get(const SQObjectPtr &key,SQObjectPtr &val) { + if(_class->_members->Get(key,val)) { + if(_isfield(val)) { + SQObjectPtr &o = _values[_member_idx(val)]; + val = _realval(o); + } + else { + val = _class->_methods[_member_idx(val)].val; + } + return true; + } + return false; + } + bool Set(const SQObjectPtr &key,const SQObjectPtr &val) { + SQObjectPtr idx; + if(_class->_members->Get(key,idx) && _isfield(idx)) { + _values[_member_idx(idx)] = val; + return true; + } + return false; + } + void Release() { + _uiRef++; + if (_hook) { _hook(_userpointer,0);} + _uiRef--; + if(_uiRef > 0) return; + SQInteger size = _memsize; + this->~SQInstance(); + SQ_FREE(this, size); + } + void Finalize(); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable ** ); + SQObjectType GetType() {return OT_INSTANCE;} +#endif + bool InstanceOf(SQClass *trg); + bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); + + SQClass *_class; + SQUserPointer _userpointer; + SQRELEASEHOOK _hook; + SQInteger _memsize; + SQObjectPtr _values[1]; +}; + +#endif //_SQCLASS_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqclosure.h b/squirrel_3_0_1_stable/squirrel/sqclosure.h index 07b3efcfe..353eb5041 100644 --- a/squirrel_3_0_1_stable/squirrel/sqclosure.h +++ b/squirrel_3_0_1_stable/squirrel/sqclosure.h @@ -1,193 +1,193 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQCLOSURE_H_
-#define _SQCLOSURE_H_
-
-
-#define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(SQObjectPtr)) + (func->_ndefaultparams*sizeof(SQObjectPtr)))
-
-struct SQFunctionProto;
-struct SQClass;
-struct SQClosure : public CHAINABLE_OBJ
-{
-private:
- SQClosure(SQSharedState *ss,SQFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}
-public:
- static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){
- SQInteger size = _CALC_CLOSURE_SIZE(func);
- SQClosure *nc=(SQClosure*)SQ_MALLOC(size);
- new (nc) SQClosure(ss,func);
- nc->_outervalues = (SQObjectPtr *)(nc + 1);
- nc->_defaultparams = &nc->_outervalues[func->_noutervalues];
- _CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues);
- _CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams);
- return nc;
- }
- void Release(){
- SQFunctionProto *f = _function;
- SQInteger size = _CALC_CLOSURE_SIZE(f);
- _DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues);
- _DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams);
- __ObjRelease(_function);
- this->~SQClosure();
- sq_vm_free(this,size);
- }
-
- SQClosure *Clone()
- {
- SQFunctionProto *f = _function;
- SQClosure * ret = SQClosure::Create(_opt_ss(this),f);
- ret->_env = _env;
- if(ret->_env) __ObjAddRef(ret->_env);
- _COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues);
- _COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams);
- return ret;
- }
- ~SQClosure();
-
- bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
- static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){
- SQFunctionProto *f = _function;
- _NULL_SQOBJECT_VECTOR(_outervalues,f->_noutervalues);
- _NULL_SQOBJECT_VECTOR(_defaultparams,f->_ndefaultparams);
- }
- SQObjectType GetType() {return OT_CLOSURE;}
-#endif
- SQWeakRef *_env;
- SQClass *_base;
- SQFunctionProto *_function;
- SQObjectPtr *_outervalues;
- SQObjectPtr *_defaultparams;
-};
-
-//////////////////////////////////////////////
-struct SQOuter : public CHAINABLE_OBJ
-{
-
-private:
- SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); }
-
-public:
- static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer)
- {
- SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter));
- new (nc) SQOuter(ss, outer);
- return nc;
- }
- ~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); }
-
- void Release()
- {
- this->~SQOuter();
- sq_vm_free(this,sizeof(SQOuter));
- }
-
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize() { _value.Null(); }
- SQObjectType GetType() {return OT_OUTER;}
-#endif
-
- SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */
- SQInteger _idx; /* idx in stack array, for relocation */
- SQObjectPtr _value; /* value of outer after stack frame is closed */
- SQOuter *_next; /* pointer to next outer when frame is open */
-};
-
-//////////////////////////////////////////////
-struct SQGenerator : public CHAINABLE_OBJ
-{
- enum SQGeneratorState{eRunning,eSuspended,eDead};
-private:
- SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
-public:
- static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
- SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
- new (nc) SQGenerator(ss,closure);
- return nc;
- }
- ~SQGenerator()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
- void Kill(){
- _state=eDead;
- _stack.resize(0);
- _closure.Null();}
- void Release(){
- sq_delete(this,SQGenerator);
- }
-
- bool Yield(SQVM *v,SQInteger target);
- bool Resume(SQVM *v,SQObjectPtr &dest);
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){_stack.resize(0);_closure.Null();}
- SQObjectType GetType() {return OT_GENERATOR;}
-#endif
- SQObjectPtr _closure;
- SQObjectPtrVec _stack;
- SQVM::CallInfo _ci;
- ExceptionsTraps _etraps;
- SQGeneratorState _state;
-};
-
-#define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr)))
-
-struct SQNativeClosure : public CHAINABLE_OBJ
-{
-private:
- SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}
-public:
- static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters)
- {
- SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters);
- SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size);
- new (nc) SQNativeClosure(ss,func);
- nc->_outervalues = (SQObjectPtr *)(nc + 1);
- nc->_noutervalues = nouters;
- _CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues);
- return nc;
- }
- SQNativeClosure *Clone()
- {
- SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function,_noutervalues);
- ret->_env = _env;
- if(ret->_env) __ObjAddRef(ret->_env);
- ret->_name = _name;
- _COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues);
- ret->_typecheck.copy(_typecheck);
- ret->_nparamscheck = _nparamscheck;
- return ret;
- }
- ~SQNativeClosure()
- {
- __ObjRelease(_env);
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
- void Release(){
- SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues);
- _DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues);
- this->~SQNativeClosure();
- sq_free(this,size);
- }
-
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize() { _NULL_SQOBJECT_VECTOR(_outervalues,_noutervalues); }
- SQObjectType GetType() {return OT_NATIVECLOSURE;}
-#endif
- SQInteger _nparamscheck;
- SQIntVec _typecheck;
- SQObjectPtr *_outervalues;
- SQUnsignedInteger _noutervalues;
- SQWeakRef *_env;
- SQFUNCTION _function;
- SQObjectPtr _name;
-};
-
-
-
-#endif //_SQCLOSURE_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQCLOSURE_H_ +#define _SQCLOSURE_H_ + + +#define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(SQObjectPtr)) + (func->_ndefaultparams*sizeof(SQObjectPtr))) + +struct SQFunctionProto; +struct SQClass; +struct SQClosure : public CHAINABLE_OBJ +{ +private: + SQClosure(SQSharedState *ss,SQFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;} +public: + static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){ + SQInteger size = _CALC_CLOSURE_SIZE(func); + SQClosure *nc=(SQClosure*)SQ_MALLOC(size); + new (nc) SQClosure(ss,func); + nc->_outervalues = (SQObjectPtr *)(nc + 1); + nc->_defaultparams = &nc->_outervalues[func->_noutervalues]; + _CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues); + _CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams); + return nc; + } + void Release(){ + SQFunctionProto *f = _function; + SQInteger size = _CALC_CLOSURE_SIZE(f); + _DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues); + _DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams); + __ObjRelease(_function); + this->~SQClosure(); + sq_vm_free(this,size); + } + + SQClosure *Clone() + { + SQFunctionProto *f = _function; + SQClosure * ret = SQClosure::Create(_opt_ss(this),f); + ret->_env = _env; + if(ret->_env) __ObjAddRef(ret->_env); + _COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues); + _COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams); + return ret; + } + ~SQClosure(); + + bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); + static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){ + SQFunctionProto *f = _function; + _NULL_SQOBJECT_VECTOR(_outervalues,f->_noutervalues); + _NULL_SQOBJECT_VECTOR(_defaultparams,f->_ndefaultparams); + } + SQObjectType GetType() {return OT_CLOSURE;} +#endif + SQWeakRef *_env; + SQClass *_base; + SQFunctionProto *_function; + SQObjectPtr *_outervalues; + SQObjectPtr *_defaultparams; +}; + +////////////////////////////////////////////// +struct SQOuter : public CHAINABLE_OBJ +{ + +private: + SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); } + +public: + static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer) + { + SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter)); + new (nc) SQOuter(ss, outer); + return nc; + } + ~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); } + + void Release() + { + this->~SQOuter(); + sq_vm_free(this,sizeof(SQOuter)); + } + +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize() { _value.Null(); } + SQObjectType GetType() {return OT_OUTER;} +#endif + + SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */ + SQInteger _idx; /* idx in stack array, for relocation */ + SQObjectPtr _value; /* value of outer after stack frame is closed */ + SQOuter *_next; /* pointer to next outer when frame is open */ +}; + +////////////////////////////////////////////// +struct SQGenerator : public CHAINABLE_OBJ +{ + enum SQGeneratorState{eRunning,eSuspended,eDead}; +private: + SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} +public: + static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){ + SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator)); + new (nc) SQGenerator(ss,closure); + return nc; + } + ~SQGenerator() + { + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); + } + void Kill(){ + _state=eDead; + _stack.resize(0); + _closure.Null();} + void Release(){ + sq_delete(this,SQGenerator); + } + + bool Yield(SQVM *v,SQInteger target); + bool Resume(SQVM *v,SQObjectPtr &dest); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){_stack.resize(0);_closure.Null();} + SQObjectType GetType() {return OT_GENERATOR;} +#endif + SQObjectPtr _closure; + SQObjectPtrVec _stack; + SQVM::CallInfo _ci; + ExceptionsTraps _etraps; + SQGeneratorState _state; +}; + +#define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr))) + +struct SQNativeClosure : public CHAINABLE_OBJ +{ +private: + SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;} +public: + static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters) + { + SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters); + SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size); + new (nc) SQNativeClosure(ss,func); + nc->_outervalues = (SQObjectPtr *)(nc + 1); + nc->_noutervalues = nouters; + _CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues); + return nc; + } + SQNativeClosure *Clone() + { + SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function,_noutervalues); + ret->_env = _env; + if(ret->_env) __ObjAddRef(ret->_env); + ret->_name = _name; + _COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues); + ret->_typecheck.copy(_typecheck); + ret->_nparamscheck = _nparamscheck; + return ret; + } + ~SQNativeClosure() + { + __ObjRelease(_env); + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); + } + void Release(){ + SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues); + _DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues); + this->~SQNativeClosure(); + sq_free(this,size); + } + +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize() { _NULL_SQOBJECT_VECTOR(_outervalues,_noutervalues); } + SQObjectType GetType() {return OT_NATIVECLOSURE;} +#endif + SQInteger _nparamscheck; + SQIntVec _typecheck; + SQObjectPtr *_outervalues; + SQUnsignedInteger _noutervalues; + SQWeakRef *_env; + SQFUNCTION _function; + SQObjectPtr _name; +}; + + + +#endif //_SQCLOSURE_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqcompiler.cpp b/squirrel_3_0_1_stable/squirrel/sqcompiler.cpp index e8c1496c9..d2f161642 100644 --- a/squirrel_3_0_1_stable/squirrel/sqcompiler.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqcompiler.cpp @@ -1,1504 +1,1504 @@ -/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#ifndef NO_COMPILER
-#include <stdarg.h>
-#include <setjmp.h>
-#include "sqopcodes.h"
-#include "sqstring.h"
-#include "sqfuncproto.h"
-#include "sqcompiler.h"
-#include "sqfuncstate.h"
-#include "sqlexer.h"
-#include "sqvm.h"
-#include "sqtable.h"
-
-#define EXPR 1
-#define OBJECT 2
-#define BASE 3
-#define LOCAL 4
-#define OUTER 5
-
-struct SQExpState {
- SQInteger etype; /* expr. type; one of EXPR, OBJECT, BASE, OUTER or LOCAL */
- SQInteger epos; /* expr. location on stack; -1 for OBJECT and BASE */
- bool donot_get; /* signal not to deref the next value */
-};
-
-struct SQScope {
- SQInteger outers;
- SQInteger stacksize;
-};
-
-#define BEGIN_SCOPE() SQScope __oldscope__ = _scope; \
- _scope.outers = _fs->_outers; \
- _scope.stacksize = _fs->GetStackSize();
-
-#define RESOLVE_OUTERS() if(_fs->GetStackSize() != _scope.stacksize) { \
- if(_fs->CountOuters(_scope.stacksize)) { \
- _fs->AddInstruction(_OP_CLOSE,0,_scope.stacksize); \
- } \
- }
-
-#define END_SCOPE_NO_CLOSE() { if(_fs->GetStackSize() != _scope.stacksize) { \
- _fs->SetStackSize(_scope.stacksize); \
- } \
- _scope = __oldscope__; \
- }
-
-#define END_SCOPE() { SQInteger oldouters = _fs->_outers;\
- if(_fs->GetStackSize() != _scope.stacksize) { \
- _fs->SetStackSize(_scope.stacksize); \
- if(oldouters != _fs->_outers) { \
- _fs->AddInstruction(_OP_CLOSE,0,_scope.stacksize); \
- } \
- } \
- _scope = __oldscope__; \
- }
-
-#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \
- SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \
- _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0);
-
-#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \
- __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \
- if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \
- if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \
- _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();}
-
-class SQCompiler
-{
-public:
- SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo)
- {
- _vm=v;
- _lex.Init(_ss(v), rg, up,ThrowError,this);
- _sourcename = SQString::Create(_ss(v), sourcename);
- _lineinfo = lineinfo;_raiseerror = raiseerror;
- _scope.outers = 0;
- _scope.stacksize = 0;
- compilererror = NULL;
- }
- static void ThrowError(void *ud, const SQChar *s) {
- SQCompiler *c = (SQCompiler *)ud;
- c->Error(s);
- }
- void Error(const SQChar *s, ...)
- {
- static SQChar temp[256];
- va_list vl;
- va_start(vl, s);
- scvsprintf(temp, s, vl);
- va_end(vl);
- compilererror = temp;
- longjmp(_errorjmp,1);
- }
- void Lex(){ _token = _lex.Lex();}
- SQObject Expect(SQInteger tok)
- {
-
- if(_token != tok) {
- if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) {
- //do nothing
- }
- else {
- const SQChar *etypename;
- if(tok > 255) {
- switch(tok)
- {
- case TK_IDENTIFIER:
- etypename = _SC("IDENTIFIER");
- break;
- case TK_STRING_LITERAL:
- etypename = _SC("STRING_LITERAL");
- break;
- case TK_INTEGER:
- etypename = _SC("INTEGER");
- break;
- case TK_FLOAT:
- etypename = _SC("FLOAT");
- break;
- default:
- etypename = _lex.Tok2Str(tok);
- }
- Error(_SC("expected '%s'"), etypename);
- }
- Error(_SC("expected '%c'"), tok);
- }
- }
- SQObjectPtr ret;
- switch(tok)
- {
- case TK_IDENTIFIER:
- ret = _fs->CreateString(_lex._svalue);
- break;
- case TK_STRING_LITERAL:
- ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
- break;
- case TK_INTEGER:
- ret = SQObjectPtr(_lex._nvalue);
- break;
- case TK_FLOAT:
- ret = SQObjectPtr(_lex._fvalue);
- break;
- }
- Lex();
- return ret;
- }
- bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); }
- void OptionalSemicolon()
- {
- if(_token == _SC(';')) { Lex(); return; }
- if(!IsEndOfStatement()) {
- Error(_SC("end of statement expected (; or lf)"));
- }
- }
- void MoveIfCurrentTargetIsLocal() {
- SQInteger trg = _fs->TopTarget();
- if(_fs->IsLocal(trg)) {
- trg = _fs->PopTarget(); //no pops the target and move it
- _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg);
- }
- }
- bool Compile(SQObjectPtr &o)
- {
- _debugline = 1;
- _debugop = 0;
-
- SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);
- funcstate._name = SQString::Create(_ss(_vm), _SC("main"));
- _fs = &funcstate;
- _fs->AddParameter(_fs->CreateString(_SC("this")));
- _fs->AddParameter(_fs->CreateString(_SC("vargv")));
- _fs->_varparams = true;
- _fs->_sourcename = _sourcename;
- SQInteger stacksize = _fs->GetStackSize();
- if(setjmp(_errorjmp) == 0) {
- Lex();
- while(_token > 0){
- Statement();
- if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon();
- }
- _fs->SetStackSize(stacksize);
- _fs->AddLineInfos(_lex._currentline, _lineinfo, true);
- _fs->AddInstruction(_OP_RETURN, 0xFF);
- _fs->SetStackSize(0);
- o =_fs->BuildProto();
-#ifdef _DEBUG_DUMP
- _fs->Dump(_funcproto(o));
-#endif
- }
- else {
- if(_raiseerror && _ss(_vm)->_compilererrorhandler) {
- _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"),
- _lex._currentline, _lex._currentcolumn);
- }
- _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1);
- return false;
- }
- return true;
- }
- void Statements()
- {
- while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) {
- Statement();
- if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon();
- }
- }
- void Statement(bool closeframe = true)
- {
- _fs->AddLineInfos(_lex._currentline, _lineinfo);
- switch(_token){
- case _SC(';'): Lex(); break;
- case TK_IF: IfStatement(); break;
- case TK_WHILE: WhileStatement(); break;
- case TK_DO: DoWhileStatement(); break;
- case TK_FOR: ForStatement(); break;
- case TK_FOREACH: ForEachStatement(); break;
- case TK_SWITCH: SwitchStatement(); break;
- case TK_LOCAL: LocalDeclStatement(); break;
- case TK_RETURN:
- case TK_YIELD: {
- SQOpcode op;
- if(_token == TK_RETURN) {
- op = _OP_RETURN;
- }
- else {
- op = _OP_YIELD;
- _fs->_bgenerator = true;
- }
- Lex();
- if(!IsEndOfStatement()) {
- SQInteger retexp = _fs->GetCurrentPos()+1;
- CommaExpr();
- if(op == _OP_RETURN && _fs->_traps > 0)
- _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0);
- _fs->_returnexp = retexp;
- _fs->AddInstruction(op, 1, _fs->PopTarget(),_fs->GetStackSize());
- }
- else{
- if(op == _OP_RETURN && _fs->_traps > 0)
- _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0);
- _fs->_returnexp = -1;
- _fs->AddInstruction(op, 0xFF,0,_fs->GetStackSize());
- }
- break;}
- case TK_BREAK:
- if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block"));
- if(_fs->_breaktargets.top() > 0){
- _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0);
- }
- RESOLVE_OUTERS();
- _fs->AddInstruction(_OP_JMP, 0, -1234);
- _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos());
- Lex();
- break;
- case TK_CONTINUE:
- if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block"));
- if(_fs->_continuetargets.top() > 0) {
- _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0);
- }
- RESOLVE_OUTERS();
- _fs->AddInstruction(_OP_JMP, 0, -1234);
- _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos());
- Lex();
- break;
- case TK_FUNCTION:
- FunctionStatement();
- break;
- case TK_CLASS:
- ClassStatement();
- break;
- case TK_ENUM:
- EnumStatement();
- break;
- case _SC('{'):{
- BEGIN_SCOPE();
- Lex();
- Statements();
- Expect(_SC('}'));
- if(closeframe) {
- END_SCOPE();
- }
- else {
- END_SCOPE_NO_CLOSE();
- }
- }
- break;
- case TK_TRY:
- TryCatchStatement();
- break;
- case TK_THROW:
- Lex();
- CommaExpr();
- _fs->AddInstruction(_OP_THROW, _fs->PopTarget());
- break;
- case TK_CONST:
- {
- Lex();
- SQObject id = Expect(TK_IDENTIFIER);
- Expect('=');
- SQObject val = ExpectScalar();
- OptionalSemicolon();
- SQTable *enums = _table(_ss(_vm)->_consts);
- SQObjectPtr strongid = id;
- enums->NewSlot(strongid,SQObjectPtr(val));
- strongid.Null();
- }
- break;
- default:
- CommaExpr();
- _fs->DiscardTarget();
- //_fs->PopTarget();
- break;
- }
- _fs->SnoozeOpt();
- }
- void EmitDerefOp(SQOpcode op)
- {
- SQInteger val = _fs->PopTarget();
- SQInteger key = _fs->PopTarget();
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(op,_fs->PushTarget(),src,key,val);
- }
- void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0)
- {
- SQInteger p2 = _fs->PopTarget(); //src in OP_GET
- SQInteger p1 = _fs->PopTarget(); //key in OP_GET
- _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3);
- }
- void EmitCompoundArith(SQInteger tok, SQInteger etype, SQInteger pos)
- {
- /* Generate code depending on the expression type */
- switch(etype) {
- case LOCAL:{
- SQInteger p2 = _fs->PopTarget(); //src in OP_GET
- SQInteger p1 = _fs->PopTarget(); //key in OP_GET
- _fs->PushTarget(p1);
- //EmitCompArithLocal(tok, p1, p1, p2);
- _fs->AddInstruction(ChooseArithOpByToken(tok),p1, p2, p1, 0);
- }
- break;
- case OBJECT:
- case BASE:
- {
- SQInteger val = _fs->PopTarget();
- SQInteger key = _fs->PopTarget();
- SQInteger src = _fs->PopTarget();
- /* _OP_COMPARITH mixes dest obj and source val in the arg1 */
- _fs->AddInstruction(_OP_COMPARITH, _fs->PushTarget(), (src<<16)|val, key, ChooseCompArithCharByToken(tok));
- }
- break;
- case OUTER:
- {
- SQInteger val = _fs->TopTarget();
- SQInteger tmp = _fs->PushTarget();
- _fs->AddInstruction(_OP_GETOUTER, tmp, pos);
- _fs->AddInstruction(ChooseArithOpByToken(tok), tmp, val, tmp, 0);
- _fs->AddInstruction(_OP_SETOUTER, tmp, pos, tmp);
- }
- break;
- }
- }
- void CommaExpr()
- {
- for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr());
- }
- void Expression()
- {
- SQExpState es = _es;
- _es.etype = EXPR;
- _es.epos = -1;
- _es.donot_get = false;
- LogicalOrExp();
- switch(_token) {
- case _SC('='):
- case TK_NEWSLOT:
- case TK_MINUSEQ:
- case TK_PLUSEQ:
- case TK_MULEQ:
- case TK_DIVEQ:
- case TK_MODEQ:{
- SQInteger op = _token;
- SQInteger ds = _es.etype;
- SQInteger pos = _es.epos;
- if(ds == EXPR) Error(_SC("can't assign expression"));
- Lex(); Expression();
-
- switch(op){
- case TK_NEWSLOT:
- if(ds == OBJECT || ds == BASE)
- EmitDerefOp(_OP_NEWSLOT);
- else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
- Error(_SC("can't 'create' a local slot"));
- break;
- case _SC('='): //ASSIGN
- switch(ds) {
- case LOCAL:
- {
- SQInteger src = _fs->PopTarget();
- SQInteger dst = _fs->TopTarget();
- _fs->AddInstruction(_OP_MOVE, dst, src);
- }
- break;
- case OBJECT:
- case BASE:
- EmitDerefOp(_OP_SET);
- break;
- case OUTER:
- {
- SQInteger src = _fs->PopTarget();
- SQInteger dst = _fs->PushTarget();
- _fs->AddInstruction(_OP_SETOUTER, dst, pos, src);
- }
- }
- break;
- case TK_MINUSEQ:
- case TK_PLUSEQ:
- case TK_MULEQ:
- case TK_DIVEQ:
- case TK_MODEQ:
- EmitCompoundArith(op, ds, pos);
- break;
- }
- }
- break;
- case _SC('?'): {
- Lex();
- _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
- SQInteger jzpos = _fs->GetCurrentPos();
- SQInteger trg = _fs->PushTarget();
- Expression();
- SQInteger first_exp = _fs->PopTarget();
- if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
- SQInteger endfirstexp = _fs->GetCurrentPos();
- _fs->AddInstruction(_OP_JMP, 0, 0);
- Expect(_SC(':'));
- SQInteger jmppos = _fs->GetCurrentPos();
- Expression();
- SQInteger second_exp = _fs->PopTarget();
- if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
- _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
- _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1);
- _fs->SnoozeOpt();
- }
- break;
- }
- _es = es;
- }
- template<typename T> void BIN_EXP(SQOpcode op, T f,SQInteger op3 = 0)
- {
- Lex(); (this->*f)();
- SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget();
- _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3);
- }
- void LogicalOrExp()
- {
- LogicalAndExp();
- for(;;) if(_token == TK_OR) {
- SQInteger first_exp = _fs->PopTarget();
- SQInteger trg = _fs->PushTarget();
- _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0);
- SQInteger jpos = _fs->GetCurrentPos();
- if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
- Lex(); LogicalOrExp();
- _fs->SnoozeOpt();
- SQInteger second_exp = _fs->PopTarget();
- if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
- _fs->SnoozeOpt();
- _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
- break;
- }else return;
- }
- void LogicalAndExp()
- {
- BitwiseOrExp();
- for(;;) switch(_token) {
- case TK_AND: {
- SQInteger first_exp = _fs->PopTarget();
- SQInteger trg = _fs->PushTarget();
- _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0);
- SQInteger jpos = _fs->GetCurrentPos();
- if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
- Lex(); LogicalAndExp();
- _fs->SnoozeOpt();
- SQInteger second_exp = _fs->PopTarget();
- if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
- _fs->SnoozeOpt();
- _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
- break;
- }
- case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::BitwiseOrExp); break;
- case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::BitwiseOrExp); break;
- default:
- return;
- }
- }
- void BitwiseOrExp()
- {
- BitwiseXorExp();
- for(;;) if(_token == _SC('|'))
- {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR);
- }else return;
- }
- void BitwiseXorExp()
- {
- BitwiseAndExp();
- for(;;) if(_token == _SC('^'))
- {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR);
- }else return;
- }
- void BitwiseAndExp()
- {
- EqExp();
- for(;;) if(_token == _SC('&'))
- {BIN_EXP(_OP_BITW, &SQCompiler::EqExp,BW_AND);
- }else return;
- }
- void EqExp()
- {
- CompExp();
- for(;;) switch(_token) {
- case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::CompExp); break;
- case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::CompExp); break;
- case TK_3WAYSCMP: BIN_EXP(_OP_CMP, &SQCompiler::CompExp,CMP_3W); break;
- default: return;
- }
- }
- void CompExp()
- {
- ShiftExp();
- for(;;) switch(_token) {
- case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break;
- case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break;
- case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break;
- case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break;
- default: return;
- }
- }
- void ShiftExp()
- {
- PlusExp();
- for(;;) switch(_token) {
- case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break;
- case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break;
- case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break;
- default: return;
- }
- }
- SQOpcode ChooseArithOpByToken(SQInteger tok)
- {
- switch(tok) {
- case TK_PLUSEQ: case '+': return _OP_ADD;
- case TK_MINUSEQ: case '-': return _OP_SUB;
- case TK_MULEQ: case '*': return _OP_MUL;
- case TK_DIVEQ: case '/': return _OP_DIV;
- case TK_MODEQ: case '%': return _OP_MOD;
- default: assert(0);
- }
- return _OP_ADD;
- }
- SQInteger ChooseCompArithCharByToken(SQInteger tok)
- {
- SQInteger oper;
- switch(tok){
- case TK_MINUSEQ: oper = '-'; break;
- case TK_PLUSEQ: oper = '+'; break;
- case TK_MULEQ: oper = '*'; break;
- case TK_DIVEQ: oper = '/'; break;
- case TK_MODEQ: oper = '%'; break;
- default: oper = 0; //shut up compiler
- assert(0); break;
- };
- return oper;
- }
- void PlusExp()
- {
- MultExp();
- for(;;) switch(_token) {
- case _SC('+'): case _SC('-'):
- BIN_EXP(ChooseArithOpByToken(_token), &SQCompiler::MultExp); break;
- default: return;
- }
- }
-
- void MultExp()
- {
- PrefixedExpr();
- for(;;) switch(_token) {
- case _SC('*'): case _SC('/'): case _SC('%'):
- BIN_EXP(ChooseArithOpByToken(_token), &SQCompiler::PrefixedExpr); break;
- default: return;
- }
- }
- //if 'pos' != -1 the previous variable is a local variable
- void PrefixedExpr()
- {
- SQInteger pos = Factor();
- for(;;) {
- switch(_token) {
- case _SC('.'):
- pos = -1;
- Lex();
-
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
- if(_es.etype==BASE) {
- Emit2ArgsOP(_OP_GET);
- pos = _fs->TopTarget();
- _es.etype = EXPR;
- _es.epos = pos;
- }
- else {
- if(NeedGet()) {
- Emit2ArgsOP(_OP_GET);
- }
- _es.etype = OBJECT;
- }
- break;
- case _SC('['):
- if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration"));
- Lex(); Expression(); Expect(_SC(']'));
- pos = -1;
- if(_es.etype==BASE) {
- Emit2ArgsOP(_OP_GET);
- pos = _fs->TopTarget();
- _es.etype = EXPR;
- _es.epos = pos;
- }
- else {
- if(NeedGet()) {
- Emit2ArgsOP(_OP_GET);
- }
- _es.etype = OBJECT;
- }
- break;
- case TK_MINUSMINUS:
- case TK_PLUSPLUS:
- {
- if(IsEndOfStatement()) return;
- SQInteger diff = (_token==TK_MINUSMINUS) ? -1 : 1;
- Lex();
- switch(_es.etype)
- {
- case EXPR: Error(_SC("can't '++' or '--' an expression")); break;
- case OBJECT:
- case BASE:
- Emit2ArgsOP(_OP_PINC, diff);
- break;
- case LOCAL: {
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, diff);
- }
- break;
- case OUTER: {
- SQInteger tmp1 = _fs->PushTarget();
- SQInteger tmp2 = _fs->PushTarget();
- _fs->AddInstruction(_OP_GETOUTER, tmp2, _es.epos);
- _fs->AddInstruction(_OP_PINCL, tmp1, tmp2, 0, diff);
- _fs->AddInstruction(_OP_SETOUTER, tmp2, _es.epos, tmp2);
- _fs->PopTarget();
- }
- }
- }
- return;
- break;
- case _SC('('):
- switch(_es.etype) {
- case OBJECT: {
- SQInteger key = _fs->PopTarget(); /* location of the key */
- SQInteger table = _fs->PopTarget(); /* location of the object */
- SQInteger closure = _fs->PushTarget(); /* location for the closure */
- SQInteger ttarget = _fs->PushTarget(); /* location for 'this' pointer */
- _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget);
- }
- break;
- case BASE:
- //Emit2ArgsOP(_OP_GET);
- _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
- break;
- case OUTER:
- _fs->AddInstruction(_OP_GETOUTER, _fs->PushTarget(), _es.epos);
- _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
- break;
- default:
- _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
- }
- _es.etype = EXPR;
- Lex();
- FunctionCallArgs();
- break;
- default: return;
- }
- }
- }
- SQInteger Factor()
- {
- _es.etype = EXPR;
- switch(_token)
- {
- case TK_STRING_LITERAL:
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1)));
- Lex();
- break;
- case TK_BASE:
- Lex();
- _fs->AddInstruction(_OP_GETBASE, _fs->PushTarget());
- _es.etype = BASE;
- _es.epos = _fs->TopTarget();
- return (_es.epos);
- break;
- case TK_IDENTIFIER:
- case TK_CONSTRUCTOR:
- case TK_THIS:{
- SQObject id;
- SQObject constant;
-
- switch(_token) {
- case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break;
- case TK_THIS: id = _fs->CreateString(_SC("this")); break;
- case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break;
- }
-
- SQInteger pos = -1;
- Lex();
- if((pos = _fs->GetLocalVariable(id)) != -1) {
- /* Handle a local variable (includes 'this') */
- _fs->PushTarget(pos);
- _es.etype = LOCAL;
- _es.epos = pos;
- }
-
- else if((pos = _fs->GetOuterVariable(id)) != -1) {
- /* Handle a free var */
- if(NeedGet()) {
- _es.epos = _fs->PushTarget();
- _fs->AddInstruction(_OP_GETOUTER, _es.epos, pos);
- /* _es.etype = EXPR; already default value */
- }
- else {
- _es.etype = OUTER;
- _es.epos = pos;
- }
- }
-
- else if(_fs->IsConstant(id, constant)) {
- /* Handle named constant */
- SQObjectPtr constval;
- SQObject constid;
- if(type(constant) == OT_TABLE) {
- Expect('.');
- constid = Expect(TK_IDENTIFIER);
- if(!_table(constant)->Get(constid, constval)) {
- constval.Null();
- Error(_SC("invalid constant [%s.%s]"), _stringval(id), _stringval(constid));
- }
- }
- else {
- constval = constant;
- }
- _es.epos = _fs->PushTarget();
-
- /* generate direct or literal function depending on size */
- SQObjectType ctype = type(constval);
- switch(ctype) {
- case OT_INTEGER: EmitLoadConstInt(_integer(constval),_es.epos); break;
- case OT_FLOAT: EmitLoadConstFloat(_float(constval),_es.epos); break;
- default: _fs->AddInstruction(_OP_LOAD,_es.epos,_fs->GetConstant(constval)); break;
- }
- _es.etype = EXPR;
- }
- else {
- /* Handle a non-local variable, aka a field. Push the 'this' pointer on
- * the virtual stack (always found in offset 0, so no instruction needs to
- * be generated), and push the key next. Generate an _OP_LOAD instruction
- * for the latter. If we are not using the variable as a dref expr, generate
- * the _OP_GET instruction.
- */
- _fs->PushTarget(0);
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- if(NeedGet()) {
- Emit2ArgsOP(_OP_GET);
- }
- _es.etype = OBJECT;
- }
- return _es.epos;
- }
- break;
- case TK_DOUBLE_COLON: // "::"
- _fs->AddInstruction(_OP_LOADROOT, _fs->PushTarget());
- _es.etype = OBJECT;
- _token = _SC('.'); /* hack: drop into PrefixExpr, case '.'*/
- _es.epos = -1;
- return _es.epos;
- break;
- case TK_NULL:
- _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
- Lex();
- break;
- case TK_INTEGER: EmitLoadConstInt(_lex._nvalue,-1); Lex(); break;
- case TK_FLOAT: EmitLoadConstFloat(_lex._fvalue,-1); Lex(); break;
- case TK_TRUE: case TK_FALSE:
- _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0);
- Lex();
- break;
- case _SC('['): {
- _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,0,NOT_ARRAY);
- SQInteger apos = _fs->GetCurrentPos(),key = 0;
- Lex();
- while(_token != _SC(']')) {
- Expression();
- if(_token == _SC(',')) Lex();
- SQInteger val = _fs->PopTarget();
- SQInteger array = _fs->TopTarget();
- _fs->AddInstruction(_OP_APPENDARRAY, array, val, AAT_STACK);
- key++;
- }
- _fs->SetIntructionParam(apos, 1, key);
- Lex();
- }
- break;
- case _SC('{'):
- _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE);
- Lex();ParseTableOrClass(_SC(','),_SC('}'));
- break;
- case TK_FUNCTION: FunctionExp(_token);break;
- case _SC('@'): FunctionExp(_token,true);break;
- case TK_CLASS: Lex(); ClassExp();break;
- case _SC('-'):
- Lex();
- switch(_token) {
- case TK_INTEGER: EmitLoadConstInt(-_lex._nvalue,-1); Lex(); break;
- case TK_FLOAT: EmitLoadConstFloat(-_lex._fvalue,-1); Lex(); break;
- default: UnaryOP(_OP_NEG);
- }
- break;
- case _SC('!'): Lex(); UnaryOP(_OP_NOT); break;
- case _SC('~'):
- Lex();
- if(_token == TK_INTEGER) { EmitLoadConstInt(~_lex._nvalue,-1); Lex(); break; }
- UnaryOP(_OP_BWNOT);
- break;
- case TK_TYPEOF : Lex() ;UnaryOP(_OP_TYPEOF); break;
- case TK_RESUME : Lex(); UnaryOP(_OP_RESUME); break;
- case TK_CLONE : Lex(); UnaryOP(_OP_CLONE); break;
- case TK_MINUSMINUS :
- case TK_PLUSPLUS :PrefixIncDec(_token); break;
- case TK_DELETE : DeleteExpr(); break;
- case _SC('('): Lex(); CommaExpr(); Expect(_SC(')'));
- break;
- default: Error(_SC("expression expected"));
- }
- return -1;
- }
- void EmitLoadConstInt(SQInteger value,SQInteger target)
- {
- if(target < 0) {
- target = _fs->PushTarget();
- }
- if((value & (~((SQInteger)0xFFFFFFFF))) == 0) { //does it fit in 32 bits?
- _fs->AddInstruction(_OP_LOADINT, target,value);
- }
- else {
- _fs->AddInstruction(_OP_LOAD, target, _fs->GetNumericConstant(value));
- }
- }
- void EmitLoadConstFloat(SQFloat value,SQInteger target)
- {
- if(target < 0) {
- target = _fs->PushTarget();
- }
- if(sizeof(SQFloat) == sizeof(SQInt32)) {
- _fs->AddInstruction(_OP_LOADFLOAT, target,*((SQInt32 *)&value));
- }
- else {
- _fs->AddInstruction(_OP_LOAD, target, _fs->GetNumericConstant(value));
- }
- }
- void UnaryOP(SQOpcode op)
- {
- PrefixedExpr();
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(op, _fs->PushTarget(), src);
- }
- bool NeedGet()
- {
- switch(_token) {
- case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_MODEQ: case TK_MULEQ:
- case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: case TK_PLUSPLUS: case TK_MINUSMINUS:
- return false;
- }
- return (!_es.donot_get || ( _es.donot_get && (_token == _SC('.') || _token == _SC('['))));
- }
- void FunctionCallArgs()
- {
- SQInteger nargs = 1;//this
- while(_token != _SC(')')) {
- Expression();
- MoveIfCurrentTargetIsLocal();
- nargs++;
- if(_token == _SC(',')){
- Lex();
- if(_token == ')') Error(_SC("expression expected, found ')'"));
- }
- }
- Lex();
- for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget();
- SQInteger stackbase = _fs->PopTarget();
- SQInteger closure = _fs->PopTarget();
- _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs);
- }
- void ParseTableOrClass(SQInteger separator,SQInteger terminator)
- {
- SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0;
- while(_token != terminator) {
- bool hasattrs = false;
- bool isstatic = false;
- //check if is an attribute
- if(separator == ';') {
- if(_token == TK_ATTR_OPEN) {
- _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); Lex();
- ParseTableOrClass(',',TK_ATTR_CLOSE);
- hasattrs = true;
- }
- if(_token == TK_STATIC) {
- isstatic = true;
- Lex();
- }
- }
- switch(_token) {
- case TK_FUNCTION:
- case TK_CONSTRUCTOR:{
- SQInteger tk = _token;
- Lex();
- SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));
- Expect(_SC('('));
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- CreateFunction(id);
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
- }
- break;
- case _SC('['):
- Lex(); CommaExpr(); Expect(_SC(']'));
- Expect(_SC('=')); Expression();
- break;
- case TK_STRING_LITERAL: //JSON
- if(separator == ',') { //only works for tables
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_STRING_LITERAL)));
- Expect(_SC(':')); Expression();
- break;
- }
- default :
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
- Expect(_SC('=')); Expression();
- }
- if(_token == separator) Lex();//optional comma/semicolon
- nkeys++;
- SQInteger val = _fs->PopTarget();
- SQInteger key = _fs->PopTarget();
- SQInteger attrs = hasattrs ? _fs->PopTarget():-1;
- assert((hasattrs && (attrs == key-1)) || !hasattrs);
- unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0);
- SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE
- if(separator == _SC(',')) { //hack recognizes a table from the separator
- _fs->AddInstruction(_OP_NEWSLOT, 0xFF, table, key, val);
- }
- else {
- _fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val); //this for classes only as it invokes _newmember
- }
- }
- if(separator == _SC(',')) //hack recognizes a table from the separator
- _fs->SetIntructionParam(tpos, 1, nkeys);
- Lex();
- }
- void LocalDeclStatement()
- {
- SQObject varname;
- Lex();
- if( _token == TK_FUNCTION) {
- Lex();
- varname = Expect(TK_IDENTIFIER);
- Expect(_SC('('));
- CreateFunction(varname,false);
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
- _fs->PopTarget();
- _fs->PushLocalVariable(varname);
- return;
- }
-
- do {
- varname = Expect(TK_IDENTIFIER);
- if(_token == _SC('=')) {
- Lex(); Expression();
- SQInteger src = _fs->PopTarget();
- SQInteger dest = _fs->PushTarget();
- if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src);
- }
- else{
- _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
- }
- _fs->PopTarget();
- _fs->PushLocalVariable(varname);
- if(_token == _SC(',')) Lex(); else break;
- } while(1);
- }
- void IfStatement()
- {
- SQInteger jmppos;
- bool haselse = false;
- Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
- _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
- SQInteger jnepos = _fs->GetCurrentPos();
- BEGIN_SCOPE();
-
- Statement();
- //
- if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon();
-
- END_SCOPE();
- SQInteger endifblock = _fs->GetCurrentPos();
- if(_token == TK_ELSE){
- haselse = true;
- BEGIN_SCOPE();
- _fs->AddInstruction(_OP_JMP);
- jmppos = _fs->GetCurrentPos();
- Lex();
- Statement(); OptionalSemicolon();
- END_SCOPE();
- _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
- }
- _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0));
- }
- void WhileStatement()
- {
- SQInteger jzpos, jmppos;
- jmppos = _fs->GetCurrentPos();
- Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
-
- BEGIN_BREAKBLE_BLOCK();
- _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
- jzpos = _fs->GetCurrentPos();
- BEGIN_SCOPE();
-
- Statement();
-
- END_SCOPE();
- _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
- _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
-
- END_BREAKBLE_BLOCK(jmppos);
- }
- void DoWhileStatement()
- {
- Lex();
- SQInteger jmptrg = _fs->GetCurrentPos();
- BEGIN_BREAKBLE_BLOCK()
- BEGIN_SCOPE();
- Statement();
- END_SCOPE();
- Expect(TK_WHILE);
- SQInteger continuetrg = _fs->GetCurrentPos();
- Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
- _fs->AddInstruction(_OP_JZ, _fs->PopTarget(), 1);
- _fs->AddInstruction(_OP_JMP, 0, jmptrg - _fs->GetCurrentPos() - 1);
- END_BREAKBLE_BLOCK(continuetrg);
- }
- void ForStatement()
- {
- Lex();
- BEGIN_SCOPE();
- Expect(_SC('('));
- if(_token == TK_LOCAL) LocalDeclStatement();
- else if(_token != _SC(';')){
- CommaExpr();
- _fs->PopTarget();
- }
- Expect(_SC(';'));
- _fs->SnoozeOpt();
- SQInteger jmppos = _fs->GetCurrentPos();
- SQInteger jzpos = -1;
- if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); }
- Expect(_SC(';'));
- _fs->SnoozeOpt();
- SQInteger expstart = _fs->GetCurrentPos() + 1;
- if(_token != _SC(')')) {
- CommaExpr();
- _fs->PopTarget();
- }
- Expect(_SC(')'));
- _fs->SnoozeOpt();
- SQInteger expend = _fs->GetCurrentPos();
- SQInteger expsize = (expend - expstart) + 1;
- SQInstructionVec exp;
- if(expsize > 0) {
- for(SQInteger i = 0; i < expsize; i++)
- exp.push_back(_fs->GetInstruction(expstart + i));
- _fs->PopInstructions(expsize);
- }
- BEGIN_BREAKBLE_BLOCK()
- Statement();
- SQInteger continuetrg = _fs->GetCurrentPos();
- if(expsize > 0) {
- for(SQInteger i = 0; i < expsize; i++)
- _fs->AddInstruction(exp[i]);
- }
- _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0);
- if(jzpos> 0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
- END_SCOPE();
-
- END_BREAKBLE_BLOCK(continuetrg);
- }
- void ForEachStatement()
- {
- SQObject idxname, valname;
- Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER);
- if(_token == _SC(',')) {
- idxname = valname;
- Lex(); valname = Expect(TK_IDENTIFIER);
- }
- else{
- idxname = _fs->CreateString(_SC("@INDEX@"));
- }
- Expect(TK_IN);
-
- //save the stack size
- BEGIN_SCOPE();
- //put the table in the stack(evaluate the table expression)
- Expression(); Expect(_SC(')'));
- SQInteger container = _fs->TopTarget();
- //push the index local var
- SQInteger indexpos = _fs->PushLocalVariable(idxname);
- _fs->AddInstruction(_OP_LOADNULLS, indexpos,1);
- //push the value local var
- SQInteger valuepos = _fs->PushLocalVariable(valname);
- _fs->AddInstruction(_OP_LOADNULLS, valuepos,1);
- //push reference index
- SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible
- _fs->AddInstruction(_OP_LOADNULLS, itrpos,1);
- SQInteger jmppos = _fs->GetCurrentPos();
- _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos);
- SQInteger foreachpos = _fs->GetCurrentPos();
- _fs->AddInstruction(_OP_POSTFOREACH, container, 0, indexpos);
- //generate the statement code
- BEGIN_BREAKBLE_BLOCK()
- Statement();
- _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
- _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos);
- _fs->SetIntructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos);
- END_BREAKBLE_BLOCK(foreachpos - 1);
- //restore the local variable stack(remove index,val and ref idx)
- END_SCOPE();
- }
- void SwitchStatement()
- {
- Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
- Expect(_SC('{'));
- SQInteger expr = _fs->TopTarget();
- bool bfirst = true;
- SQInteger tonextcondjmp = -1;
- SQInteger skipcondjmp = -1;
- SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size();
- _fs->_breaktargets.push_back(0);
- while(_token == TK_CASE) {
- if(!bfirst) {
- _fs->AddInstruction(_OP_JMP, 0, 0);
- skipcondjmp = _fs->GetCurrentPos();
- _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
- }
- //condition
- Lex(); Expression(); Expect(_SC(':'));
- SQInteger trg = _fs->PopTarget();
- _fs->AddInstruction(_OP_EQ, trg, trg, expr);
- _fs->AddInstruction(_OP_JZ, trg, 0);
- //end condition
- if(skipcondjmp != -1) {
- _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp));
- }
- tonextcondjmp = _fs->GetCurrentPos();
- BEGIN_SCOPE();
- Statements();
- END_SCOPE();
- bfirst = false;
- }
- if(tonextcondjmp != -1)
- _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
- if(_token == TK_DEFAULT) {
- Lex(); Expect(_SC(':'));
- BEGIN_SCOPE();
- Statements();
- END_SCOPE();
- }
- Expect(_SC('}'));
- _fs->PopTarget();
- __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__;
- if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__);
- _fs->_breaktargets.pop_back();
- }
- void FunctionStatement()
- {
- SQObject id;
- Lex(); id = Expect(TK_IDENTIFIER);
- _fs->PushTarget(0);
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
-
- while(_token == TK_DOUBLE_COLON) {
- Lex();
- id = Expect(TK_IDENTIFIER);
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
- }
- Expect(_SC('('));
- CreateFunction(id);
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
- EmitDerefOp(_OP_NEWSLOT);
- _fs->PopTarget();
- }
- void ClassStatement()
- {
- SQExpState es;
- Lex();
- es = _es;
- _es.donot_get = true;
- PrefixedExpr();
- if(_es.etype == EXPR) {
- Error(_SC("invalid class name"));
- }
- else if(_es.etype == OBJECT || _es.etype == BASE) {
- ClassExp();
- EmitDerefOp(_OP_NEWSLOT);
- _fs->PopTarget();
- }
- else {
- Error(_SC("cannot create a class in a local with the syntax(class <local>)"));
- }
- _es = es;
- }
- SQObject ExpectScalar()
- {
- SQObject val;
- val._type = OT_NULL; val._unVal.nInteger = 0; //shut up GCC 4.x
- switch(_token) {
- case TK_INTEGER:
- val._type = OT_INTEGER;
- val._unVal.nInteger = _lex._nvalue;
- break;
- case TK_FLOAT:
- val._type = OT_FLOAT;
- val._unVal.fFloat = _lex._fvalue;
- break;
- case TK_STRING_LITERAL:
- val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
- break;
- case '-':
- Lex();
- switch(_token)
- {
- case TK_INTEGER:
- val._type = OT_INTEGER;
- val._unVal.nInteger = -_lex._nvalue;
- break;
- case TK_FLOAT:
- val._type = OT_FLOAT;
- val._unVal.fFloat = -_lex._fvalue;
- break;
- default:
- Error(_SC("scalar expected : integer,float"));
- }
- break;
- default:
- Error(_SC("scalar expected : integer,float or string"));
- }
- Lex();
- return val;
- }
- void EnumStatement()
- {
- Lex();
- SQObject id = Expect(TK_IDENTIFIER);
- Expect(_SC('{'));
-
- SQObject table = _fs->CreateTable();
- SQInteger nval = 0;
- while(_token != _SC('}')) {
- SQObject key = Expect(TK_IDENTIFIER);
- SQObject val;
- if(_token == _SC('=')) {
- Lex();
- val = ExpectScalar();
- }
- else {
- val._type = OT_INTEGER;
- val._unVal.nInteger = nval++;
- }
- _table(table)->NewSlot(SQObjectPtr(key),SQObjectPtr(val));
- if(_token == ',') Lex();
- }
- SQTable *enums = _table(_ss(_vm)->_consts);
- SQObjectPtr strongid = id;
- enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table));
- strongid.Null();
- Lex();
- }
- void TryCatchStatement()
- {
- SQObject exid;
- Lex();
- _fs->AddInstruction(_OP_PUSHTRAP,0,0);
- _fs->_traps++;
- if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++;
- if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++;
- SQInteger trappos = _fs->GetCurrentPos();
- {
- BEGIN_SCOPE();
- Statement();
- END_SCOPE();
- }
- _fs->_traps--;
- _fs->AddInstruction(_OP_POPTRAP, 1, 0);
- if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--;
- if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--;
- _fs->AddInstruction(_OP_JMP, 0, 0);
- SQInteger jmppos = _fs->GetCurrentPos();
- _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos));
- Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')'));
- {
- BEGIN_SCOPE();
- SQInteger ex_target = _fs->PushLocalVariable(exid);
- _fs->SetIntructionParam(trappos, 0, ex_target);
- Statement();
- _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0);
- END_SCOPE();
- }
- }
- void FunctionExp(SQInteger ftype,bool lambda = false)
- {
- Lex(); Expect(_SC('('));
- SQObjectPtr dummy;
- CreateFunction(dummy,lambda);
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1);
- }
- void ClassExp()
- {
- SQInteger base = -1;
- SQInteger attrs = -1;
- if(_token == TK_EXTENDS) {
- Lex(); Expression();
- base = _fs->TopTarget();
- }
- if(_token == TK_ATTR_OPEN) {
- Lex();
- _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE);
- ParseTableOrClass(_SC(','),TK_ATTR_CLOSE);
- attrs = _fs->TopTarget();
- }
- Expect(_SC('{'));
- if(attrs != -1) _fs->PopTarget();
- if(base != -1) _fs->PopTarget();
- _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(), base, attrs,NOT_CLASS);
- ParseTableOrClass(_SC(';'),_SC('}'));
- }
- void DeleteExpr()
- {
- SQExpState es;
- Lex();
- es = _es;
- _es.donot_get = true;
- PrefixedExpr();
- if(_es.etype==EXPR) Error(_SC("can't delete an expression"));
- if(_es.etype==OBJECT || _es.etype==BASE) {
- Emit2ArgsOP(_OP_DELETE);
- }
- else {
- Error(_SC("cannot delete an (outer) local"));
- }
- _es = es;
- }
- void PrefixIncDec(SQInteger token)
- {
- SQExpState es;
- SQInteger diff = (token==TK_MINUSMINUS) ? -1 : 1;
- Lex();
- es = _es;
- _es.donot_get = true;
- PrefixedExpr();
- if(_es.etype==EXPR) {
- Error(_SC("can't '++' or '--' an expression"));
- }
- else if(_es.etype==OBJECT || _es.etype==BASE) {
- Emit2ArgsOP(_OP_INC, diff);
- }
- else if(_es.etype==LOCAL) {
- SQInteger src = _fs->TopTarget();
- _fs->AddInstruction(_OP_INCL, src, src, 0, diff);
-
- }
- else if(_es.etype==OUTER) {
- SQInteger tmp = _fs->PushTarget();
- _fs->AddInstruction(_OP_GETOUTER, tmp, _es.epos);
- _fs->AddInstruction(_OP_INCL, tmp, tmp, 0, diff);
- _fs->AddInstruction(_OP_SETOUTER, tmp, _es.epos, tmp);
- }
- _es = es;
- }
- void CreateFunction(SQObject &name,bool lambda = false)
- {
- SQFuncState *funcstate = _fs->PushChildState(_ss(_vm));
- funcstate->_name = name;
- SQObject paramname;
- funcstate->AddParameter(_fs->CreateString(_SC("this")));
- funcstate->_sourcename = _sourcename;
- SQInteger defparams = 0;
- while(_token!=_SC(')')) {
- if(_token == TK_VARPARAMS) {
- if(defparams > 0) Error(_SC("function with default parameters cannot have variable number of parameters"));
- funcstate->AddParameter(_fs->CreateString(_SC("vargv")));
- funcstate->_varparams = true;
- Lex();
- if(_token != _SC(')')) Error(_SC("expected ')'"));
- break;
- }
- else {
- paramname = Expect(TK_IDENTIFIER);
- funcstate->AddParameter(paramname);
- if(_token == _SC('=')) {
- Lex();
- Expression();
- funcstate->AddDefaultParam(_fs->TopTarget());
- defparams++;
- }
- else {
- if(defparams > 0) Error(_SC("expected '='"));
- }
- if(_token == _SC(',')) Lex();
- else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
- }
- }
- Expect(_SC(')'));
- for(SQInteger n = 0; n < defparams; n++) {
- _fs->PopTarget();
- }
-
- SQFuncState *currchunk = _fs;
- _fs = funcstate;
- if(lambda) {
- Expression();
- _fs->AddInstruction(_OP_RETURN, 1, _fs->PopTarget());}
- else {
- Statement(false);
- }
- funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);
- funcstate->AddInstruction(_OP_RETURN, -1);
- funcstate->SetStackSize(0);
-
- SQFunctionProto *func = funcstate->BuildProto();
-#ifdef _DEBUG_DUMP
- funcstate->Dump(func);
-#endif
- _fs = currchunk;
- _fs->_functions.push_back(func);
- _fs->PopChildState();
- }
- void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve)
- {
- while(ntoresolve > 0) {
- SQInteger pos = funcstate->_unresolvedbreaks.back();
- funcstate->_unresolvedbreaks.pop_back();
- //set the jmp instruction
- funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0);
- ntoresolve--;
- }
- }
- void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos)
- {
- while(ntoresolve > 0) {
- SQInteger pos = funcstate->_unresolvedcontinues.back();
- funcstate->_unresolvedcontinues.pop_back();
- //set the jmp instruction
- funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0);
- ntoresolve--;
- }
- }
-private:
- SQInteger _token;
- SQFuncState *_fs;
- SQObjectPtr _sourcename;
- SQLexer _lex;
- bool _lineinfo;
- bool _raiseerror;
- SQInteger _debugline;
- SQInteger _debugop;
- SQExpState _es;
- SQScope _scope;
- SQChar *compilererror;
- jmp_buf _errorjmp;
- SQVM *_vm;
-};
-
-bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo)
-{
- SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo);
- return p.Compile(out);
-}
-
-#endif
+/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#ifndef NO_COMPILER +#include <stdarg.h> +#include <setjmp.h> +#include "sqopcodes.h" +#include "sqstring.h" +#include "sqfuncproto.h" +#include "sqcompiler.h" +#include "sqfuncstate.h" +#include "sqlexer.h" +#include "sqvm.h" +#include "sqtable.h" + +#define EXPR 1 +#define OBJECT 2 +#define BASE 3 +#define LOCAL 4 +#define OUTER 5 + +struct SQExpState { + SQInteger etype; /* expr. type; one of EXPR, OBJECT, BASE, OUTER or LOCAL */ + SQInteger epos; /* expr. location on stack; -1 for OBJECT and BASE */ + bool donot_get; /* signal not to deref the next value */ +}; + +struct SQScope { + SQInteger outers; + SQInteger stacksize; +}; + +#define BEGIN_SCOPE() SQScope __oldscope__ = _scope; \ + _scope.outers = _fs->_outers; \ + _scope.stacksize = _fs->GetStackSize(); + +#define RESOLVE_OUTERS() if(_fs->GetStackSize() != _scope.stacksize) { \ + if(_fs->CountOuters(_scope.stacksize)) { \ + _fs->AddInstruction(_OP_CLOSE,0,_scope.stacksize); \ + } \ + } + +#define END_SCOPE_NO_CLOSE() { if(_fs->GetStackSize() != _scope.stacksize) { \ + _fs->SetStackSize(_scope.stacksize); \ + } \ + _scope = __oldscope__; \ + } + +#define END_SCOPE() { SQInteger oldouters = _fs->_outers;\ + if(_fs->GetStackSize() != _scope.stacksize) { \ + _fs->SetStackSize(_scope.stacksize); \ + if(oldouters != _fs->_outers) { \ + _fs->AddInstruction(_OP_CLOSE,0,_scope.stacksize); \ + } \ + } \ + _scope = __oldscope__; \ + } + +#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \ + SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \ + _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0); + +#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \ + __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \ + if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \ + if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \ + _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();} + +class SQCompiler +{ +public: + SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) + { + _vm=v; + _lex.Init(_ss(v), rg, up,ThrowError,this); + _sourcename = SQString::Create(_ss(v), sourcename); + _lineinfo = lineinfo;_raiseerror = raiseerror; + _scope.outers = 0; + _scope.stacksize = 0; + compilererror = NULL; + } + static void ThrowError(void *ud, const SQChar *s) { + SQCompiler *c = (SQCompiler *)ud; + c->Error(s); + } + void Error(const SQChar *s, ...) + { + static SQChar temp[256]; + va_list vl; + va_start(vl, s); + scvsprintf(temp, s, vl); + va_end(vl); + compilererror = temp; + longjmp(_errorjmp,1); + } + void Lex(){ _token = _lex.Lex();} + SQObject Expect(SQInteger tok) + { + + if(_token != tok) { + if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) { + //do nothing + } + else { + const SQChar *etypename; + if(tok > 255) { + switch(tok) + { + case TK_IDENTIFIER: + etypename = _SC("IDENTIFIER"); + break; + case TK_STRING_LITERAL: + etypename = _SC("STRING_LITERAL"); + break; + case TK_INTEGER: + etypename = _SC("INTEGER"); + break; + case TK_FLOAT: + etypename = _SC("FLOAT"); + break; + default: + etypename = _lex.Tok2Str(tok); + } + Error(_SC("expected '%s'"), etypename); + } + Error(_SC("expected '%c'"), tok); + } + } + SQObjectPtr ret; + switch(tok) + { + case TK_IDENTIFIER: + ret = _fs->CreateString(_lex._svalue); + break; + case TK_STRING_LITERAL: + ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); + break; + case TK_INTEGER: + ret = SQObjectPtr(_lex._nvalue); + break; + case TK_FLOAT: + ret = SQObjectPtr(_lex._fvalue); + break; + } + Lex(); + return ret; + } + bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); } + void OptionalSemicolon() + { + if(_token == _SC(';')) { Lex(); return; } + if(!IsEndOfStatement()) { + Error(_SC("end of statement expected (; or lf)")); + } + } + void MoveIfCurrentTargetIsLocal() { + SQInteger trg = _fs->TopTarget(); + if(_fs->IsLocal(trg)) { + trg = _fs->PopTarget(); //no pops the target and move it + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg); + } + } + bool Compile(SQObjectPtr &o) + { + _debugline = 1; + _debugop = 0; + + SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this); + funcstate._name = SQString::Create(_ss(_vm), _SC("main")); + _fs = &funcstate; + _fs->AddParameter(_fs->CreateString(_SC("this"))); + _fs->AddParameter(_fs->CreateString(_SC("vargv"))); + _fs->_varparams = true; + _fs->_sourcename = _sourcename; + SQInteger stacksize = _fs->GetStackSize(); + if(setjmp(_errorjmp) == 0) { + Lex(); + while(_token > 0){ + Statement(); + if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); + } + _fs->SetStackSize(stacksize); + _fs->AddLineInfos(_lex._currentline, _lineinfo, true); + _fs->AddInstruction(_OP_RETURN, 0xFF); + _fs->SetStackSize(0); + o =_fs->BuildProto(); +#ifdef _DEBUG_DUMP + _fs->Dump(_funcproto(o)); +#endif + } + else { + if(_raiseerror && _ss(_vm)->_compilererrorhandler) { + _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"), + _lex._currentline, _lex._currentcolumn); + } + _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1); + return false; + } + return true; + } + void Statements() + { + while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) { + Statement(); + if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); + } + } + void Statement(bool closeframe = true) + { + _fs->AddLineInfos(_lex._currentline, _lineinfo); + switch(_token){ + case _SC(';'): Lex(); break; + case TK_IF: IfStatement(); break; + case TK_WHILE: WhileStatement(); break; + case TK_DO: DoWhileStatement(); break; + case TK_FOR: ForStatement(); break; + case TK_FOREACH: ForEachStatement(); break; + case TK_SWITCH: SwitchStatement(); break; + case TK_LOCAL: LocalDeclStatement(); break; + case TK_RETURN: + case TK_YIELD: { + SQOpcode op; + if(_token == TK_RETURN) { + op = _OP_RETURN; + } + else { + op = _OP_YIELD; + _fs->_bgenerator = true; + } + Lex(); + if(!IsEndOfStatement()) { + SQInteger retexp = _fs->GetCurrentPos()+1; + CommaExpr(); + if(op == _OP_RETURN && _fs->_traps > 0) + _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0); + _fs->_returnexp = retexp; + _fs->AddInstruction(op, 1, _fs->PopTarget(),_fs->GetStackSize()); + } + else{ + if(op == _OP_RETURN && _fs->_traps > 0) + _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0); + _fs->_returnexp = -1; + _fs->AddInstruction(op, 0xFF,0,_fs->GetStackSize()); + } + break;} + case TK_BREAK: + if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block")); + if(_fs->_breaktargets.top() > 0){ + _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0); + } + RESOLVE_OUTERS(); + _fs->AddInstruction(_OP_JMP, 0, -1234); + _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos()); + Lex(); + break; + case TK_CONTINUE: + if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block")); + if(_fs->_continuetargets.top() > 0) { + _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0); + } + RESOLVE_OUTERS(); + _fs->AddInstruction(_OP_JMP, 0, -1234); + _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos()); + Lex(); + break; + case TK_FUNCTION: + FunctionStatement(); + break; + case TK_CLASS: + ClassStatement(); + break; + case TK_ENUM: + EnumStatement(); + break; + case _SC('{'):{ + BEGIN_SCOPE(); + Lex(); + Statements(); + Expect(_SC('}')); + if(closeframe) { + END_SCOPE(); + } + else { + END_SCOPE_NO_CLOSE(); + } + } + break; + case TK_TRY: + TryCatchStatement(); + break; + case TK_THROW: + Lex(); + CommaExpr(); + _fs->AddInstruction(_OP_THROW, _fs->PopTarget()); + break; + case TK_CONST: + { + Lex(); + SQObject id = Expect(TK_IDENTIFIER); + Expect('='); + SQObject val = ExpectScalar(); + OptionalSemicolon(); + SQTable *enums = _table(_ss(_vm)->_consts); + SQObjectPtr strongid = id; + enums->NewSlot(strongid,SQObjectPtr(val)); + strongid.Null(); + } + break; + default: + CommaExpr(); + _fs->DiscardTarget(); + //_fs->PopTarget(); + break; + } + _fs->SnoozeOpt(); + } + void EmitDerefOp(SQOpcode op) + { + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(op,_fs->PushTarget(),src,key,val); + } + void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0) + { + SQInteger p2 = _fs->PopTarget(); //src in OP_GET + SQInteger p1 = _fs->PopTarget(); //key in OP_GET + _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3); + } + void EmitCompoundArith(SQInteger tok, SQInteger etype, SQInteger pos) + { + /* Generate code depending on the expression type */ + switch(etype) { + case LOCAL:{ + SQInteger p2 = _fs->PopTarget(); //src in OP_GET + SQInteger p1 = _fs->PopTarget(); //key in OP_GET + _fs->PushTarget(p1); + //EmitCompArithLocal(tok, p1, p1, p2); + _fs->AddInstruction(ChooseArithOpByToken(tok),p1, p2, p1, 0); + } + break; + case OBJECT: + case BASE: + { + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger src = _fs->PopTarget(); + /* _OP_COMPARITH mixes dest obj and source val in the arg1 */ + _fs->AddInstruction(_OP_COMPARITH, _fs->PushTarget(), (src<<16)|val, key, ChooseCompArithCharByToken(tok)); + } + break; + case OUTER: + { + SQInteger val = _fs->TopTarget(); + SQInteger tmp = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, tmp, pos); + _fs->AddInstruction(ChooseArithOpByToken(tok), tmp, val, tmp, 0); + _fs->AddInstruction(_OP_SETOUTER, tmp, pos, tmp); + } + break; + } + } + void CommaExpr() + { + for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr()); + } + void Expression() + { + SQExpState es = _es; + _es.etype = EXPR; + _es.epos = -1; + _es.donot_get = false; + LogicalOrExp(); + switch(_token) { + case _SC('='): + case TK_NEWSLOT: + case TK_MINUSEQ: + case TK_PLUSEQ: + case TK_MULEQ: + case TK_DIVEQ: + case TK_MODEQ:{ + SQInteger op = _token; + SQInteger ds = _es.etype; + SQInteger pos = _es.epos; + if(ds == EXPR) Error(_SC("can't assign expression")); + Lex(); Expression(); + + switch(op){ + case TK_NEWSLOT: + if(ds == OBJECT || ds == BASE) + EmitDerefOp(_OP_NEWSLOT); + else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local + Error(_SC("can't 'create' a local slot")); + break; + case _SC('='): //ASSIGN + switch(ds) { + case LOCAL: + { + SQInteger src = _fs->PopTarget(); + SQInteger dst = _fs->TopTarget(); + _fs->AddInstruction(_OP_MOVE, dst, src); + } + break; + case OBJECT: + case BASE: + EmitDerefOp(_OP_SET); + break; + case OUTER: + { + SQInteger src = _fs->PopTarget(); + SQInteger dst = _fs->PushTarget(); + _fs->AddInstruction(_OP_SETOUTER, dst, pos, src); + } + } + break; + case TK_MINUSEQ: + case TK_PLUSEQ: + case TK_MULEQ: + case TK_DIVEQ: + case TK_MODEQ: + EmitCompoundArith(op, ds, pos); + break; + } + } + break; + case _SC('?'): { + Lex(); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + SQInteger jzpos = _fs->GetCurrentPos(); + SQInteger trg = _fs->PushTarget(); + Expression(); + SQInteger first_exp = _fs->PopTarget(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + SQInteger endfirstexp = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_JMP, 0, 0); + Expect(_SC(':')); + SQInteger jmppos = _fs->GetCurrentPos(); + Expression(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); + _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1); + _fs->SnoozeOpt(); + } + break; + } + _es = es; + } + template<typename T> void BIN_EXP(SQOpcode op, T f,SQInteger op3 = 0) + { + Lex(); (this->*f)(); + SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget(); + _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3); + } + void LogicalOrExp() + { + LogicalAndExp(); + for(;;) if(_token == TK_OR) { + SQInteger first_exp = _fs->PopTarget(); + SQInteger trg = _fs->PushTarget(); + _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0); + SQInteger jpos = _fs->GetCurrentPos(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + Lex(); LogicalOrExp(); + _fs->SnoozeOpt(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SnoozeOpt(); + _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); + break; + }else return; + } + void LogicalAndExp() + { + BitwiseOrExp(); + for(;;) switch(_token) { + case TK_AND: { + SQInteger first_exp = _fs->PopTarget(); + SQInteger trg = _fs->PushTarget(); + _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0); + SQInteger jpos = _fs->GetCurrentPos(); + if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); + Lex(); LogicalAndExp(); + _fs->SnoozeOpt(); + SQInteger second_exp = _fs->PopTarget(); + if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); + _fs->SnoozeOpt(); + _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); + break; + } + case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::BitwiseOrExp); break; + case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::BitwiseOrExp); break; + default: + return; + } + } + void BitwiseOrExp() + { + BitwiseXorExp(); + for(;;) if(_token == _SC('|')) + {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR); + }else return; + } + void BitwiseXorExp() + { + BitwiseAndExp(); + for(;;) if(_token == _SC('^')) + {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR); + }else return; + } + void BitwiseAndExp() + { + EqExp(); + for(;;) if(_token == _SC('&')) + {BIN_EXP(_OP_BITW, &SQCompiler::EqExp,BW_AND); + }else return; + } + void EqExp() + { + CompExp(); + for(;;) switch(_token) { + case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::CompExp); break; + case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::CompExp); break; + case TK_3WAYSCMP: BIN_EXP(_OP_CMP, &SQCompiler::CompExp,CMP_3W); break; + default: return; + } + } + void CompExp() + { + ShiftExp(); + for(;;) switch(_token) { + case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break; + case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break; + case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break; + case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break; + default: return; + } + } + void ShiftExp() + { + PlusExp(); + for(;;) switch(_token) { + case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break; + case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break; + case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break; + default: return; + } + } + SQOpcode ChooseArithOpByToken(SQInteger tok) + { + switch(tok) { + case TK_PLUSEQ: case '+': return _OP_ADD; + case TK_MINUSEQ: case '-': return _OP_SUB; + case TK_MULEQ: case '*': return _OP_MUL; + case TK_DIVEQ: case '/': return _OP_DIV; + case TK_MODEQ: case '%': return _OP_MOD; + default: assert(0); + } + return _OP_ADD; + } + SQInteger ChooseCompArithCharByToken(SQInteger tok) + { + SQInteger oper; + switch(tok){ + case TK_MINUSEQ: oper = '-'; break; + case TK_PLUSEQ: oper = '+'; break; + case TK_MULEQ: oper = '*'; break; + case TK_DIVEQ: oper = '/'; break; + case TK_MODEQ: oper = '%'; break; + default: oper = 0; //shut up compiler + assert(0); break; + }; + return oper; + } + void PlusExp() + { + MultExp(); + for(;;) switch(_token) { + case _SC('+'): case _SC('-'): + BIN_EXP(ChooseArithOpByToken(_token), &SQCompiler::MultExp); break; + default: return; + } + } + + void MultExp() + { + PrefixedExpr(); + for(;;) switch(_token) { + case _SC('*'): case _SC('/'): case _SC('%'): + BIN_EXP(ChooseArithOpByToken(_token), &SQCompiler::PrefixedExpr); break; + default: return; + } + } + //if 'pos' != -1 the previous variable is a local variable + void PrefixedExpr() + { + SQInteger pos = Factor(); + for(;;) { + switch(_token) { + case _SC('.'): + pos = -1; + Lex(); + + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); + if(_es.etype==BASE) { + Emit2ArgsOP(_OP_GET); + pos = _fs->TopTarget(); + _es.etype = EXPR; + _es.epos = pos; + } + else { + if(NeedGet()) { + Emit2ArgsOP(_OP_GET); + } + _es.etype = OBJECT; + } + break; + case _SC('['): + if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration")); + Lex(); Expression(); Expect(_SC(']')); + pos = -1; + if(_es.etype==BASE) { + Emit2ArgsOP(_OP_GET); + pos = _fs->TopTarget(); + _es.etype = EXPR; + _es.epos = pos; + } + else { + if(NeedGet()) { + Emit2ArgsOP(_OP_GET); + } + _es.etype = OBJECT; + } + break; + case TK_MINUSMINUS: + case TK_PLUSPLUS: + { + if(IsEndOfStatement()) return; + SQInteger diff = (_token==TK_MINUSMINUS) ? -1 : 1; + Lex(); + switch(_es.etype) + { + case EXPR: Error(_SC("can't '++' or '--' an expression")); break; + case OBJECT: + case BASE: + Emit2ArgsOP(_OP_PINC, diff); + break; + case LOCAL: { + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, diff); + } + break; + case OUTER: { + SQInteger tmp1 = _fs->PushTarget(); + SQInteger tmp2 = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, tmp2, _es.epos); + _fs->AddInstruction(_OP_PINCL, tmp1, tmp2, 0, diff); + _fs->AddInstruction(_OP_SETOUTER, tmp2, _es.epos, tmp2); + _fs->PopTarget(); + } + } + } + return; + break; + case _SC('('): + switch(_es.etype) { + case OBJECT: { + SQInteger key = _fs->PopTarget(); /* location of the key */ + SQInteger table = _fs->PopTarget(); /* location of the object */ + SQInteger closure = _fs->PushTarget(); /* location for the closure */ + SQInteger ttarget = _fs->PushTarget(); /* location for 'this' pointer */ + _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget); + } + break; + case BASE: + //Emit2ArgsOP(_OP_GET); + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); + break; + case OUTER: + _fs->AddInstruction(_OP_GETOUTER, _fs->PushTarget(), _es.epos); + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); + break; + default: + _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); + } + _es.etype = EXPR; + Lex(); + FunctionCallArgs(); + break; + default: return; + } + } + } + SQInteger Factor() + { + _es.etype = EXPR; + switch(_token) + { + case TK_STRING_LITERAL: + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1))); + Lex(); + break; + case TK_BASE: + Lex(); + _fs->AddInstruction(_OP_GETBASE, _fs->PushTarget()); + _es.etype = BASE; + _es.epos = _fs->TopTarget(); + return (_es.epos); + break; + case TK_IDENTIFIER: + case TK_CONSTRUCTOR: + case TK_THIS:{ + SQObject id; + SQObject constant; + + switch(_token) { + case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break; + case TK_THIS: id = _fs->CreateString(_SC("this")); break; + case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break; + } + + SQInteger pos = -1; + Lex(); + if((pos = _fs->GetLocalVariable(id)) != -1) { + /* Handle a local variable (includes 'this') */ + _fs->PushTarget(pos); + _es.etype = LOCAL; + _es.epos = pos; + } + + else if((pos = _fs->GetOuterVariable(id)) != -1) { + /* Handle a free var */ + if(NeedGet()) { + _es.epos = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, _es.epos, pos); + /* _es.etype = EXPR; already default value */ + } + else { + _es.etype = OUTER; + _es.epos = pos; + } + } + + else if(_fs->IsConstant(id, constant)) { + /* Handle named constant */ + SQObjectPtr constval; + SQObject constid; + if(type(constant) == OT_TABLE) { + Expect('.'); + constid = Expect(TK_IDENTIFIER); + if(!_table(constant)->Get(constid, constval)) { + constval.Null(); + Error(_SC("invalid constant [%s.%s]"), _stringval(id), _stringval(constid)); + } + } + else { + constval = constant; + } + _es.epos = _fs->PushTarget(); + + /* generate direct or literal function depending on size */ + SQObjectType ctype = type(constval); + switch(ctype) { + case OT_INTEGER: EmitLoadConstInt(_integer(constval),_es.epos); break; + case OT_FLOAT: EmitLoadConstFloat(_float(constval),_es.epos); break; + default: _fs->AddInstruction(_OP_LOAD,_es.epos,_fs->GetConstant(constval)); break; + } + _es.etype = EXPR; + } + else { + /* Handle a non-local variable, aka a field. Push the 'this' pointer on + * the virtual stack (always found in offset 0, so no instruction needs to + * be generated), and push the key next. Generate an _OP_LOAD instruction + * for the latter. If we are not using the variable as a dref expr, generate + * the _OP_GET instruction. + */ + _fs->PushTarget(0); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(NeedGet()) { + Emit2ArgsOP(_OP_GET); + } + _es.etype = OBJECT; + } + return _es.epos; + } + break; + case TK_DOUBLE_COLON: // "::" + _fs->AddInstruction(_OP_LOADROOT, _fs->PushTarget()); + _es.etype = OBJECT; + _token = _SC('.'); /* hack: drop into PrefixExpr, case '.'*/ + _es.epos = -1; + return _es.epos; + break; + case TK_NULL: + _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); + Lex(); + break; + case TK_INTEGER: EmitLoadConstInt(_lex._nvalue,-1); Lex(); break; + case TK_FLOAT: EmitLoadConstFloat(_lex._fvalue,-1); Lex(); break; + case TK_TRUE: case TK_FALSE: + _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0); + Lex(); + break; + case _SC('['): { + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,0,NOT_ARRAY); + SQInteger apos = _fs->GetCurrentPos(),key = 0; + Lex(); + while(_token != _SC(']')) { + Expression(); + if(_token == _SC(',')) Lex(); + SQInteger val = _fs->PopTarget(); + SQInteger array = _fs->TopTarget(); + _fs->AddInstruction(_OP_APPENDARRAY, array, val, AAT_STACK); + key++; + } + _fs->SetIntructionParam(apos, 1, key); + Lex(); + } + break; + case _SC('{'): + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); + Lex();ParseTableOrClass(_SC(','),_SC('}')); + break; + case TK_FUNCTION: FunctionExp(_token);break; + case _SC('@'): FunctionExp(_token,true);break; + case TK_CLASS: Lex(); ClassExp();break; + case _SC('-'): + Lex(); + switch(_token) { + case TK_INTEGER: EmitLoadConstInt(-_lex._nvalue,-1); Lex(); break; + case TK_FLOAT: EmitLoadConstFloat(-_lex._fvalue,-1); Lex(); break; + default: UnaryOP(_OP_NEG); + } + break; + case _SC('!'): Lex(); UnaryOP(_OP_NOT); break; + case _SC('~'): + Lex(); + if(_token == TK_INTEGER) { EmitLoadConstInt(~_lex._nvalue,-1); Lex(); break; } + UnaryOP(_OP_BWNOT); + break; + case TK_TYPEOF : Lex() ;UnaryOP(_OP_TYPEOF); break; + case TK_RESUME : Lex(); UnaryOP(_OP_RESUME); break; + case TK_CLONE : Lex(); UnaryOP(_OP_CLONE); break; + case TK_MINUSMINUS : + case TK_PLUSPLUS :PrefixIncDec(_token); break; + case TK_DELETE : DeleteExpr(); break; + case _SC('('): Lex(); CommaExpr(); Expect(_SC(')')); + break; + default: Error(_SC("expression expected")); + } + return -1; + } + void EmitLoadConstInt(SQInteger value,SQInteger target) + { + if(target < 0) { + target = _fs->PushTarget(); + } + if((value & (~((SQInteger)0xFFFFFFFF))) == 0) { //does it fit in 32 bits? + _fs->AddInstruction(_OP_LOADINT, target,value); + } + else { + _fs->AddInstruction(_OP_LOAD, target, _fs->GetNumericConstant(value)); + } + } + void EmitLoadConstFloat(SQFloat value,SQInteger target) + { + if(target < 0) { + target = _fs->PushTarget(); + } + if(sizeof(SQFloat) == sizeof(SQInt32)) { + _fs->AddInstruction(_OP_LOADFLOAT, target,*((SQInt32 *)&value)); + } + else { + _fs->AddInstruction(_OP_LOAD, target, _fs->GetNumericConstant(value)); + } + } + void UnaryOP(SQOpcode op) + { + PrefixedExpr(); + SQInteger src = _fs->PopTarget(); + _fs->AddInstruction(op, _fs->PushTarget(), src); + } + bool NeedGet() + { + switch(_token) { + case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_MODEQ: case TK_MULEQ: + case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: case TK_PLUSPLUS: case TK_MINUSMINUS: + return false; + } + return (!_es.donot_get || ( _es.donot_get && (_token == _SC('.') || _token == _SC('[')))); + } + void FunctionCallArgs() + { + SQInteger nargs = 1;//this + while(_token != _SC(')')) { + Expression(); + MoveIfCurrentTargetIsLocal(); + nargs++; + if(_token == _SC(',')){ + Lex(); + if(_token == ')') Error(_SC("expression expected, found ')'")); + } + } + Lex(); + for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget(); + SQInteger stackbase = _fs->PopTarget(); + SQInteger closure = _fs->PopTarget(); + _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs); + } + void ParseTableOrClass(SQInteger separator,SQInteger terminator) + { + SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0; + while(_token != terminator) { + bool hasattrs = false; + bool isstatic = false; + //check if is an attribute + if(separator == ';') { + if(_token == TK_ATTR_OPEN) { + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); Lex(); + ParseTableOrClass(',',TK_ATTR_CLOSE); + hasattrs = true; + } + if(_token == TK_STATIC) { + isstatic = true; + Lex(); + } + } + switch(_token) { + case TK_FUNCTION: + case TK_CONSTRUCTOR:{ + SQInteger tk = _token; + Lex(); + SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor")); + Expect(_SC('(')); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + CreateFunction(id); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); + } + break; + case _SC('['): + Lex(); CommaExpr(); Expect(_SC(']')); + Expect(_SC('=')); Expression(); + break; + case TK_STRING_LITERAL: //JSON + if(separator == ',') { //only works for tables + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_STRING_LITERAL))); + Expect(_SC(':')); Expression(); + break; + } + default : + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); + Expect(_SC('=')); Expression(); + } + if(_token == separator) Lex();//optional comma/semicolon + nkeys++; + SQInteger val = _fs->PopTarget(); + SQInteger key = _fs->PopTarget(); + SQInteger attrs = hasattrs ? _fs->PopTarget():-1; + assert((hasattrs && (attrs == key-1)) || !hasattrs); + unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0); + SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE + if(separator == _SC(',')) { //hack recognizes a table from the separator + _fs->AddInstruction(_OP_NEWSLOT, 0xFF, table, key, val); + } + else { + _fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val); //this for classes only as it invokes _newmember + } + } + if(separator == _SC(',')) //hack recognizes a table from the separator + _fs->SetIntructionParam(tpos, 1, nkeys); + Lex(); + } + void LocalDeclStatement() + { + SQObject varname; + Lex(); + if( _token == TK_FUNCTION) { + Lex(); + varname = Expect(TK_IDENTIFIER); + Expect(_SC('(')); + CreateFunction(varname,false); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); + _fs->PopTarget(); + _fs->PushLocalVariable(varname); + return; + } + + do { + varname = Expect(TK_IDENTIFIER); + if(_token == _SC('=')) { + Lex(); Expression(); + SQInteger src = _fs->PopTarget(); + SQInteger dest = _fs->PushTarget(); + if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src); + } + else{ + _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); + } + _fs->PopTarget(); + _fs->PushLocalVariable(varname); + if(_token == _SC(',')) Lex(); else break; + } while(1); + } + void IfStatement() + { + SQInteger jmppos; + bool haselse = false; + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + SQInteger jnepos = _fs->GetCurrentPos(); + BEGIN_SCOPE(); + + Statement(); + // + if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon(); + + END_SCOPE(); + SQInteger endifblock = _fs->GetCurrentPos(); + if(_token == TK_ELSE){ + haselse = true; + BEGIN_SCOPE(); + _fs->AddInstruction(_OP_JMP); + jmppos = _fs->GetCurrentPos(); + Lex(); + Statement(); OptionalSemicolon(); + END_SCOPE(); + _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); + } + _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0)); + } + void WhileStatement() + { + SQInteger jzpos, jmppos; + jmppos = _fs->GetCurrentPos(); + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + + BEGIN_BREAKBLE_BLOCK(); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); + jzpos = _fs->GetCurrentPos(); + BEGIN_SCOPE(); + + Statement(); + + END_SCOPE(); + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); + _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); + + END_BREAKBLE_BLOCK(jmppos); + } + void DoWhileStatement() + { + Lex(); + SQInteger jmptrg = _fs->GetCurrentPos(); + BEGIN_BREAKBLE_BLOCK() + BEGIN_SCOPE(); + Statement(); + END_SCOPE(); + Expect(TK_WHILE); + SQInteger continuetrg = _fs->GetCurrentPos(); + Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + _fs->AddInstruction(_OP_JZ, _fs->PopTarget(), 1); + _fs->AddInstruction(_OP_JMP, 0, jmptrg - _fs->GetCurrentPos() - 1); + END_BREAKBLE_BLOCK(continuetrg); + } + void ForStatement() + { + Lex(); + BEGIN_SCOPE(); + Expect(_SC('(')); + if(_token == TK_LOCAL) LocalDeclStatement(); + else if(_token != _SC(';')){ + CommaExpr(); + _fs->PopTarget(); + } + Expect(_SC(';')); + _fs->SnoozeOpt(); + SQInteger jmppos = _fs->GetCurrentPos(); + SQInteger jzpos = -1; + if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); } + Expect(_SC(';')); + _fs->SnoozeOpt(); + SQInteger expstart = _fs->GetCurrentPos() + 1; + if(_token != _SC(')')) { + CommaExpr(); + _fs->PopTarget(); + } + Expect(_SC(')')); + _fs->SnoozeOpt(); + SQInteger expend = _fs->GetCurrentPos(); + SQInteger expsize = (expend - expstart) + 1; + SQInstructionVec exp; + if(expsize > 0) { + for(SQInteger i = 0; i < expsize; i++) + exp.push_back(_fs->GetInstruction(expstart + i)); + _fs->PopInstructions(expsize); + } + BEGIN_BREAKBLE_BLOCK() + Statement(); + SQInteger continuetrg = _fs->GetCurrentPos(); + if(expsize > 0) { + for(SQInteger i = 0; i < expsize; i++) + _fs->AddInstruction(exp[i]); + } + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0); + if(jzpos> 0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); + END_SCOPE(); + + END_BREAKBLE_BLOCK(continuetrg); + } + void ForEachStatement() + { + SQObject idxname, valname; + Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER); + if(_token == _SC(',')) { + idxname = valname; + Lex(); valname = Expect(TK_IDENTIFIER); + } + else{ + idxname = _fs->CreateString(_SC("@INDEX@")); + } + Expect(TK_IN); + + //save the stack size + BEGIN_SCOPE(); + //put the table in the stack(evaluate the table expression) + Expression(); Expect(_SC(')')); + SQInteger container = _fs->TopTarget(); + //push the index local var + SQInteger indexpos = _fs->PushLocalVariable(idxname); + _fs->AddInstruction(_OP_LOADNULLS, indexpos,1); + //push the value local var + SQInteger valuepos = _fs->PushLocalVariable(valname); + _fs->AddInstruction(_OP_LOADNULLS, valuepos,1); + //push reference index + SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible + _fs->AddInstruction(_OP_LOADNULLS, itrpos,1); + SQInteger jmppos = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos); + SQInteger foreachpos = _fs->GetCurrentPos(); + _fs->AddInstruction(_OP_POSTFOREACH, container, 0, indexpos); + //generate the statement code + BEGIN_BREAKBLE_BLOCK() + Statement(); + _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); + _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos); + _fs->SetIntructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos); + END_BREAKBLE_BLOCK(foreachpos - 1); + //restore the local variable stack(remove index,val and ref idx) + END_SCOPE(); + } + void SwitchStatement() + { + Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); + Expect(_SC('{')); + SQInteger expr = _fs->TopTarget(); + bool bfirst = true; + SQInteger tonextcondjmp = -1; + SQInteger skipcondjmp = -1; + SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size(); + _fs->_breaktargets.push_back(0); + while(_token == TK_CASE) { + if(!bfirst) { + _fs->AddInstruction(_OP_JMP, 0, 0); + skipcondjmp = _fs->GetCurrentPos(); + _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); + } + //condition + Lex(); Expression(); Expect(_SC(':')); + SQInteger trg = _fs->PopTarget(); + _fs->AddInstruction(_OP_EQ, trg, trg, expr); + _fs->AddInstruction(_OP_JZ, trg, 0); + //end condition + if(skipcondjmp != -1) { + _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp)); + } + tonextcondjmp = _fs->GetCurrentPos(); + BEGIN_SCOPE(); + Statements(); + END_SCOPE(); + bfirst = false; + } + if(tonextcondjmp != -1) + _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); + if(_token == TK_DEFAULT) { + Lex(); Expect(_SC(':')); + BEGIN_SCOPE(); + Statements(); + END_SCOPE(); + } + Expect(_SC('}')); + _fs->PopTarget(); + __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__; + if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__); + _fs->_breaktargets.pop_back(); + } + void FunctionStatement() + { + SQObject id; + Lex(); id = Expect(TK_IDENTIFIER); + _fs->PushTarget(0); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); + + while(_token == TK_DOUBLE_COLON) { + Lex(); + id = Expect(TK_IDENTIFIER); + _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); + if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); + } + Expect(_SC('(')); + CreateFunction(id); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0); + EmitDerefOp(_OP_NEWSLOT); + _fs->PopTarget(); + } + void ClassStatement() + { + SQExpState es; + Lex(); + es = _es; + _es.donot_get = true; + PrefixedExpr(); + if(_es.etype == EXPR) { + Error(_SC("invalid class name")); + } + else if(_es.etype == OBJECT || _es.etype == BASE) { + ClassExp(); + EmitDerefOp(_OP_NEWSLOT); + _fs->PopTarget(); + } + else { + Error(_SC("cannot create a class in a local with the syntax(class <local>)")); + } + _es = es; + } + SQObject ExpectScalar() + { + SQObject val; + val._type = OT_NULL; val._unVal.nInteger = 0; //shut up GCC 4.x + switch(_token) { + case TK_INTEGER: + val._type = OT_INTEGER; + val._unVal.nInteger = _lex._nvalue; + break; + case TK_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = _lex._fvalue; + break; + case TK_STRING_LITERAL: + val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); + break; + case '-': + Lex(); + switch(_token) + { + case TK_INTEGER: + val._type = OT_INTEGER; + val._unVal.nInteger = -_lex._nvalue; + break; + case TK_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = -_lex._fvalue; + break; + default: + Error(_SC("scalar expected : integer,float")); + } + break; + default: + Error(_SC("scalar expected : integer,float or string")); + } + Lex(); + return val; + } + void EnumStatement() + { + Lex(); + SQObject id = Expect(TK_IDENTIFIER); + Expect(_SC('{')); + + SQObject table = _fs->CreateTable(); + SQInteger nval = 0; + while(_token != _SC('}')) { + SQObject key = Expect(TK_IDENTIFIER); + SQObject val; + if(_token == _SC('=')) { + Lex(); + val = ExpectScalar(); + } + else { + val._type = OT_INTEGER; + val._unVal.nInteger = nval++; + } + _table(table)->NewSlot(SQObjectPtr(key),SQObjectPtr(val)); + if(_token == ',') Lex(); + } + SQTable *enums = _table(_ss(_vm)->_consts); + SQObjectPtr strongid = id; + enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table)); + strongid.Null(); + Lex(); + } + void TryCatchStatement() + { + SQObject exid; + Lex(); + _fs->AddInstruction(_OP_PUSHTRAP,0,0); + _fs->_traps++; + if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++; + if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++; + SQInteger trappos = _fs->GetCurrentPos(); + { + BEGIN_SCOPE(); + Statement(); + END_SCOPE(); + } + _fs->_traps--; + _fs->AddInstruction(_OP_POPTRAP, 1, 0); + if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--; + if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--; + _fs->AddInstruction(_OP_JMP, 0, 0); + SQInteger jmppos = _fs->GetCurrentPos(); + _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos)); + Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')')); + { + BEGIN_SCOPE(); + SQInteger ex_target = _fs->PushLocalVariable(exid); + _fs->SetIntructionParam(trappos, 0, ex_target); + Statement(); + _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0); + END_SCOPE(); + } + } + void FunctionExp(SQInteger ftype,bool lambda = false) + { + Lex(); Expect(_SC('(')); + SQObjectPtr dummy; + CreateFunction(dummy,lambda); + _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1); + } + void ClassExp() + { + SQInteger base = -1; + SQInteger attrs = -1; + if(_token == TK_EXTENDS) { + Lex(); Expression(); + base = _fs->TopTarget(); + } + if(_token == TK_ATTR_OPEN) { + Lex(); + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); + ParseTableOrClass(_SC(','),TK_ATTR_CLOSE); + attrs = _fs->TopTarget(); + } + Expect(_SC('{')); + if(attrs != -1) _fs->PopTarget(); + if(base != -1) _fs->PopTarget(); + _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(), base, attrs,NOT_CLASS); + ParseTableOrClass(_SC(';'),_SC('}')); + } + void DeleteExpr() + { + SQExpState es; + Lex(); + es = _es; + _es.donot_get = true; + PrefixedExpr(); + if(_es.etype==EXPR) Error(_SC("can't delete an expression")); + if(_es.etype==OBJECT || _es.etype==BASE) { + Emit2ArgsOP(_OP_DELETE); + } + else { + Error(_SC("cannot delete an (outer) local")); + } + _es = es; + } + void PrefixIncDec(SQInteger token) + { + SQExpState es; + SQInteger diff = (token==TK_MINUSMINUS) ? -1 : 1; + Lex(); + es = _es; + _es.donot_get = true; + PrefixedExpr(); + if(_es.etype==EXPR) { + Error(_SC("can't '++' or '--' an expression")); + } + else if(_es.etype==OBJECT || _es.etype==BASE) { + Emit2ArgsOP(_OP_INC, diff); + } + else if(_es.etype==LOCAL) { + SQInteger src = _fs->TopTarget(); + _fs->AddInstruction(_OP_INCL, src, src, 0, diff); + + } + else if(_es.etype==OUTER) { + SQInteger tmp = _fs->PushTarget(); + _fs->AddInstruction(_OP_GETOUTER, tmp, _es.epos); + _fs->AddInstruction(_OP_INCL, tmp, tmp, 0, diff); + _fs->AddInstruction(_OP_SETOUTER, tmp, _es.epos, tmp); + } + _es = es; + } + void CreateFunction(SQObject &name,bool lambda = false) + { + SQFuncState *funcstate = _fs->PushChildState(_ss(_vm)); + funcstate->_name = name; + SQObject paramname; + funcstate->AddParameter(_fs->CreateString(_SC("this"))); + funcstate->_sourcename = _sourcename; + SQInteger defparams = 0; + while(_token!=_SC(')')) { + if(_token == TK_VARPARAMS) { + if(defparams > 0) Error(_SC("function with default parameters cannot have variable number of parameters")); + funcstate->AddParameter(_fs->CreateString(_SC("vargv"))); + funcstate->_varparams = true; + Lex(); + if(_token != _SC(')')) Error(_SC("expected ')'")); + break; + } + else { + paramname = Expect(TK_IDENTIFIER); + funcstate->AddParameter(paramname); + if(_token == _SC('=')) { + Lex(); + Expression(); + funcstate->AddDefaultParam(_fs->TopTarget()); + defparams++; + } + else { + if(defparams > 0) Error(_SC("expected '='")); + } + if(_token == _SC(',')) Lex(); + else if(_token != _SC(')')) Error(_SC("expected ')' or ','")); + } + } + Expect(_SC(')')); + for(SQInteger n = 0; n < defparams; n++) { + _fs->PopTarget(); + } + + SQFuncState *currchunk = _fs; + _fs = funcstate; + if(lambda) { + Expression(); + _fs->AddInstruction(_OP_RETURN, 1, _fs->PopTarget());} + else { + Statement(false); + } + funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true); + funcstate->AddInstruction(_OP_RETURN, -1); + funcstate->SetStackSize(0); + + SQFunctionProto *func = funcstate->BuildProto(); +#ifdef _DEBUG_DUMP + funcstate->Dump(func); +#endif + _fs = currchunk; + _fs->_functions.push_back(func); + _fs->PopChildState(); + } + void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve) + { + while(ntoresolve > 0) { + SQInteger pos = funcstate->_unresolvedbreaks.back(); + funcstate->_unresolvedbreaks.pop_back(); + //set the jmp instruction + funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0); + ntoresolve--; + } + } + void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos) + { + while(ntoresolve > 0) { + SQInteger pos = funcstate->_unresolvedcontinues.back(); + funcstate->_unresolvedcontinues.pop_back(); + //set the jmp instruction + funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0); + ntoresolve--; + } + } +private: + SQInteger _token; + SQFuncState *_fs; + SQObjectPtr _sourcename; + SQLexer _lex; + bool _lineinfo; + bool _raiseerror; + SQInteger _debugline; + SQInteger _debugop; + SQExpState _es; + SQScope _scope; + SQChar *compilererror; + jmp_buf _errorjmp; + SQVM *_vm; +}; + +bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo) +{ + SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo); + return p.Compile(out); +} + +#endif diff --git a/squirrel_3_0_1_stable/squirrel/sqcompiler.h b/squirrel_3_0_1_stable/squirrel/sqcompiler.h index fcfd46a99..de5983b46 100644 --- a/squirrel_3_0_1_stable/squirrel/sqcompiler.h +++ b/squirrel_3_0_1_stable/squirrel/sqcompiler.h @@ -1,77 +1,77 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQCOMPILER_H_
-#define _SQCOMPILER_H_
-
-struct SQVM;
-
-#define TK_IDENTIFIER 258
-#define TK_STRING_LITERAL 259
-#define TK_INTEGER 260
-#define TK_FLOAT 261
-#define TK_BASE 262
-#define TK_DELETE 263
-#define TK_EQ 264
-#define TK_NE 265
-#define TK_LE 266
-#define TK_GE 267
-#define TK_SWITCH 268
-#define TK_ARROW 269
-#define TK_AND 270
-#define TK_OR 271
-#define TK_IF 272
-#define TK_ELSE 273
-#define TK_WHILE 274
-#define TK_BREAK 275
-#define TK_FOR 276
-#define TK_DO 277
-#define TK_NULL 278
-#define TK_FOREACH 279
-#define TK_IN 280
-#define TK_NEWSLOT 281
-#define TK_MODULO 282
-#define TK_LOCAL 283
-#define TK_CLONE 284
-#define TK_FUNCTION 285
-#define TK_RETURN 286
-#define TK_TYPEOF 287
-#define TK_UMINUS 288
-#define TK_PLUSEQ 289
-#define TK_MINUSEQ 290
-#define TK_CONTINUE 291
-#define TK_YIELD 292
-#define TK_TRY 293
-#define TK_CATCH 294
-#define TK_THROW 295
-#define TK_SHIFTL 296
-#define TK_SHIFTR 297
-#define TK_RESUME 298
-#define TK_DOUBLE_COLON 299
-#define TK_CASE 300
-#define TK_DEFAULT 301
-#define TK_THIS 302
-#define TK_PLUSPLUS 303
-#define TK_MINUSMINUS 304
-#define TK_3WAYSCMP 305
-#define TK_USHIFTR 306
-#define TK_CLASS 307
-#define TK_EXTENDS 308
-#define TK_CONSTRUCTOR 310
-#define TK_INSTANCEOF 311
-#define TK_VARPARAMS 312
-//#define TK_VARGC 313
-//#define TK_VARGV 314
-#define TK_TRUE 315
-#define TK_FALSE 316
-#define TK_MULEQ 317
-#define TK_DIVEQ 318
-#define TK_MODEQ 319
-#define TK_ATTR_OPEN 320
-#define TK_ATTR_CLOSE 321
-#define TK_STATIC 322
-#define TK_ENUM 323
-#define TK_CONST 324
-
-
-typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s);
-bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo);
-#endif //_SQCOMPILER_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQCOMPILER_H_ +#define _SQCOMPILER_H_ + +struct SQVM; + +#define TK_IDENTIFIER 258 +#define TK_STRING_LITERAL 259 +#define TK_INTEGER 260 +#define TK_FLOAT 261 +#define TK_BASE 262 +#define TK_DELETE 263 +#define TK_EQ 264 +#define TK_NE 265 +#define TK_LE 266 +#define TK_GE 267 +#define TK_SWITCH 268 +#define TK_ARROW 269 +#define TK_AND 270 +#define TK_OR 271 +#define TK_IF 272 +#define TK_ELSE 273 +#define TK_WHILE 274 +#define TK_BREAK 275 +#define TK_FOR 276 +#define TK_DO 277 +#define TK_NULL 278 +#define TK_FOREACH 279 +#define TK_IN 280 +#define TK_NEWSLOT 281 +#define TK_MODULO 282 +#define TK_LOCAL 283 +#define TK_CLONE 284 +#define TK_FUNCTION 285 +#define TK_RETURN 286 +#define TK_TYPEOF 287 +#define TK_UMINUS 288 +#define TK_PLUSEQ 289 +#define TK_MINUSEQ 290 +#define TK_CONTINUE 291 +#define TK_YIELD 292 +#define TK_TRY 293 +#define TK_CATCH 294 +#define TK_THROW 295 +#define TK_SHIFTL 296 +#define TK_SHIFTR 297 +#define TK_RESUME 298 +#define TK_DOUBLE_COLON 299 +#define TK_CASE 300 +#define TK_DEFAULT 301 +#define TK_THIS 302 +#define TK_PLUSPLUS 303 +#define TK_MINUSMINUS 304 +#define TK_3WAYSCMP 305 +#define TK_USHIFTR 306 +#define TK_CLASS 307 +#define TK_EXTENDS 308 +#define TK_CONSTRUCTOR 310 +#define TK_INSTANCEOF 311 +#define TK_VARPARAMS 312 +//#define TK_VARGC 313 +//#define TK_VARGV 314 +#define TK_TRUE 315 +#define TK_FALSE 316 +#define TK_MULEQ 317 +#define TK_DIVEQ 318 +#define TK_MODEQ 319 +#define TK_ATTR_OPEN 320 +#define TK_ATTR_CLOSE 321 +#define TK_STATIC 322 +#define TK_ENUM 323 +#define TK_CONST 324 + + +typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s); +bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo); +#endif //_SQCOMPILER_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqdebug.cpp b/squirrel_3_0_1_stable/squirrel/sqdebug.cpp index 3cb7b71cd..01d0261d2 100644 --- a/squirrel_3_0_1_stable/squirrel/sqdebug.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqdebug.cpp @@ -1,116 +1,116 @@ -/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <stdarg.h>
-#include "sqvm.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-
-SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi)
-{
- SQInteger cssize = v->_callsstacksize;
- if (cssize > level) {
- SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
- if(sq_isclosure(ci._closure)) {
- SQClosure *c = _closure(ci._closure);
- SQFunctionProto *proto = c->_function;
- fi->funcid = proto;
- fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown");
- fi->source = type(proto->_name) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown");
- return SQ_OK;
- }
- }
- return sq_throwerror(v,_SC("the object is not a closure"));
-}
-
-SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si)
-{
- SQInteger cssize = v->_callsstacksize;
- if (cssize > level) {
- memset(si, 0, sizeof(SQStackInfos));
- SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
- switch (type(ci._closure)) {
- case OT_CLOSURE:{
- SQFunctionProto *func = _closure(ci._closure)->_function;
- if (type(func->_name) == OT_STRING)
- si->funcname = _stringval(func->_name);
- if (type(func->_sourcename) == OT_STRING)
- si->source = _stringval(func->_sourcename);
- si->line = func->GetLine(ci._ip);
- }
- break;
- case OT_NATIVECLOSURE:
- si->source = _SC("NATIVE");
- si->funcname = _SC("unknown");
- if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)
- si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
- si->line = -1;
- break;
- default: break; //shutup compiler
- }
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-void SQVM::Raise_Error(const SQChar *s, ...)
-{
- va_list vl;
- va_start(vl, s);
- scvsprintf(_sp(rsl((SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl);
- va_end(vl);
- _lasterror = SQString::Create(_ss(this),_spval,-1);
-}
-
-void SQVM::Raise_Error(const SQObjectPtr &desc)
-{
- _lasterror = desc;
-}
-
-SQString *SQVM::PrintObjVal(const SQObjectPtr &o)
-{
- switch(type(o)) {
- case OT_STRING: return _string(o);
- case OT_INTEGER:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _PRINT_INT_FMT, _integer(o));
- return SQString::Create(_ss(this), _spval);
- break;
- case OT_FLOAT:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o));
- return SQString::Create(_ss(this), _spval);
- break;
- default:
- return SQString::Create(_ss(this), GetTypeName(o));
- }
-}
-
-void SQVM::Raise_IdxError(const SQObjectPtr &o)
-{
- SQObjectPtr oval = PrintObjVal(o);
- Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));
-}
-
-void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)
-{
- SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);
- Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));
-}
-
-
-void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)
-{
- SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);
- SQInteger found = 0;
- for(SQInteger i=0; i<16; i++)
- {
- SQInteger mask = 0x00000001 << i;
- if(typemask & (mask)) {
- if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);
- found ++;
- StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);
- }
- }
- Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));
-}
+/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include <stdarg.h> +#include "sqvm.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqstring.h" + +SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi) +{ + SQInteger cssize = v->_callsstacksize; + if (cssize > level) { + SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; + if(sq_isclosure(ci._closure)) { + SQClosure *c = _closure(ci._closure); + SQFunctionProto *proto = c->_function; + fi->funcid = proto; + fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown"); + fi->source = type(proto->_name) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown"); + return SQ_OK; + } + } + return sq_throwerror(v,_SC("the object is not a closure")); +} + +SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si) +{ + SQInteger cssize = v->_callsstacksize; + if (cssize > level) { + memset(si, 0, sizeof(SQStackInfos)); + SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; + switch (type(ci._closure)) { + case OT_CLOSURE:{ + SQFunctionProto *func = _closure(ci._closure)->_function; + if (type(func->_name) == OT_STRING) + si->funcname = _stringval(func->_name); + if (type(func->_sourcename) == OT_STRING) + si->source = _stringval(func->_sourcename); + si->line = func->GetLine(ci._ip); + } + break; + case OT_NATIVECLOSURE: + si->source = _SC("NATIVE"); + si->funcname = _SC("unknown"); + if(type(_nativeclosure(ci._closure)->_name) == OT_STRING) + si->funcname = _stringval(_nativeclosure(ci._closure)->_name); + si->line = -1; + break; + default: break; //shutup compiler + } + return SQ_OK; + } + return SQ_ERROR; +} + +void SQVM::Raise_Error(const SQChar *s, ...) +{ + va_list vl; + va_start(vl, s); + scvsprintf(_sp(rsl((SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl); + va_end(vl); + _lasterror = SQString::Create(_ss(this),_spval,-1); +} + +void SQVM::Raise_Error(const SQObjectPtr &desc) +{ + _lasterror = desc; +} + +SQString *SQVM::PrintObjVal(const SQObjectPtr &o) +{ + switch(type(o)) { + case OT_STRING: return _string(o); + case OT_INTEGER: + scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _PRINT_INT_FMT, _integer(o)); + return SQString::Create(_ss(this), _spval); + break; + case OT_FLOAT: + scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o)); + return SQString::Create(_ss(this), _spval); + break; + default: + return SQString::Create(_ss(this), GetTypeName(o)); + } +} + +void SQVM::Raise_IdxError(const SQObjectPtr &o) +{ + SQObjectPtr oval = PrintObjVal(o); + Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval)); +} + +void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2) +{ + SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2); + Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2)); +} + + +void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type) +{ + SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1); + SQInteger found = 0; + for(SQInteger i=0; i<16; i++) + { + SQInteger mask = 0x00000001 << i; + if(typemask & (mask)) { + if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes); + found ++; + StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes); + } + } + Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes)); +} diff --git a/squirrel_3_0_1_stable/squirrel/sqfuncproto.h b/squirrel_3_0_1_stable/squirrel/sqfuncproto.h index cd48aa6df..e6e9529ec 100644 --- a/squirrel_3_0_1_stable/squirrel/sqfuncproto.h +++ b/squirrel_3_0_1_stable/squirrel/sqfuncproto.h @@ -1,154 +1,154 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQFUNCTION_H_
-#define _SQFUNCTION_H_
-
-#include "sqopcodes.h"
-
-enum SQOuterType {
- otLOCAL = 0,
- otOUTER = 1
-};
-
-struct SQOuterVar
-{
-
- SQOuterVar(){}
- SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)
- {
- _name = name;
- _src=src;
- _type=t;
- }
- SQOuterVar(const SQOuterVar &ov)
- {
- _type=ov._type;
- _src=ov._src;
- _name=ov._name;
- }
- SQOuterType _type;
- SQObjectPtr _name;
- SQObjectPtr _src;
-};
-
-struct SQLocalVarInfo
-{
- SQLocalVarInfo():_start_op(0),_end_op(0),_pos(0){}
- SQLocalVarInfo(const SQLocalVarInfo &lvi)
- {
- _name=lvi._name;
- _start_op=lvi._start_op;
- _end_op=lvi._end_op;
- _pos=lvi._pos;
- }
- SQObjectPtr _name;
- SQUnsignedInteger _start_op;
- SQUnsignedInteger _end_op;
- SQUnsignedInteger _pos;
-};
-
-struct SQLineInfo { SQInteger _line;SQInteger _op; };
-
-typedef sqvector<SQOuterVar> SQOuterVarVec;
-typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec;
-typedef sqvector<SQLineInfo> SQLineInfoVec;
-
-#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \
- +((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \
- +(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \
- +(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \
- +(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger)))
-
-
-struct SQFunctionProto : public CHAINABLE_OBJ
-{
-private:
- SQFunctionProto(SQSharedState *ss);
- ~SQFunctionProto();
-
-public:
- static SQFunctionProto *Create(SQSharedState *ss,SQInteger ninstructions,
- SQInteger nliterals,SQInteger nparameters,
- SQInteger nfunctions,SQInteger noutervalues,
- SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams)
- {
- SQFunctionProto *f;
- //I compact the whole class and members in a single memory allocation
- f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams));
- new (f) SQFunctionProto(ss);
- f->_ninstructions = ninstructions;
- f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions];
- f->_nliterals = nliterals;
- f->_parameters = (SQObjectPtr*)&f->_literals[nliterals];
- f->_nparameters = nparameters;
- f->_functions = (SQObjectPtr*)&f->_parameters[nparameters];
- f->_nfunctions = nfunctions;
- f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions];
- f->_noutervalues = noutervalues;
- f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues];
- f->_nlineinfos = nlineinfos;
- f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos];
- f->_nlocalvarinfos = nlocalvarinfos;
- f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos];
- f->_ndefaultparams = ndefaultparams;
-
- _CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals);
- _CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters);
- _CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions);
- _CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues);
- //_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers
- _CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos);
- return f;
- }
- void Release(){
- _DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals);
- _DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters);
- _DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions);
- _DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues);
- //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers
- _DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos);
- SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams);
- this->~SQFunctionProto();
- sq_vm_free(this,size);
- }
-
- const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop);
- SQInteger GetLine(SQInstruction *curr);
- bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
- static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){ _NULL_SQOBJECT_VECTOR(_literals,_nliterals); }
- SQObjectType GetType() {return OT_FUNCPROTO;}
-#endif
- SQObjectPtr _sourcename;
- SQObjectPtr _name;
- SQInteger _stacksize;
- bool _bgenerator;
- SQInteger _varparams;
-
- SQInteger _nlocalvarinfos;
- SQLocalVarInfo *_localvarinfos;
-
- SQInteger _nlineinfos;
- SQLineInfo *_lineinfos;
-
- SQInteger _nliterals;
- SQObjectPtr *_literals;
-
- SQInteger _nparameters;
- SQObjectPtr *_parameters;
-
- SQInteger _nfunctions;
- SQObjectPtr *_functions;
-
- SQInteger _noutervalues;
- SQOuterVar *_outervalues;
-
- SQInteger _ndefaultparams;
- SQInteger *_defaultparams;
-
- SQInteger _ninstructions;
- SQInstruction _instructions[1];
-};
-
-#endif //_SQFUNCTION_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQFUNCTION_H_ +#define _SQFUNCTION_H_ + +#include "sqopcodes.h" + +enum SQOuterType { + otLOCAL = 0, + otOUTER = 1 +}; + +struct SQOuterVar +{ + + SQOuterVar(){} + SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t) + { + _name = name; + _src=src; + _type=t; + } + SQOuterVar(const SQOuterVar &ov) + { + _type=ov._type; + _src=ov._src; + _name=ov._name; + } + SQOuterType _type; + SQObjectPtr _name; + SQObjectPtr _src; +}; + +struct SQLocalVarInfo +{ + SQLocalVarInfo():_start_op(0),_end_op(0),_pos(0){} + SQLocalVarInfo(const SQLocalVarInfo &lvi) + { + _name=lvi._name; + _start_op=lvi._start_op; + _end_op=lvi._end_op; + _pos=lvi._pos; + } + SQObjectPtr _name; + SQUnsignedInteger _start_op; + SQUnsignedInteger _end_op; + SQUnsignedInteger _pos; +}; + +struct SQLineInfo { SQInteger _line;SQInteger _op; }; + +typedef sqvector<SQOuterVar> SQOuterVarVec; +typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec; +typedef sqvector<SQLineInfo> SQLineInfoVec; + +#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \ + +((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \ + +(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \ + +(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \ + +(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger))) + + +struct SQFunctionProto : public CHAINABLE_OBJ +{ +private: + SQFunctionProto(SQSharedState *ss); + ~SQFunctionProto(); + +public: + static SQFunctionProto *Create(SQSharedState *ss,SQInteger ninstructions, + SQInteger nliterals,SQInteger nparameters, + SQInteger nfunctions,SQInteger noutervalues, + SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams) + { + SQFunctionProto *f; + //I compact the whole class and members in a single memory allocation + f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams)); + new (f) SQFunctionProto(ss); + f->_ninstructions = ninstructions; + f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions]; + f->_nliterals = nliterals; + f->_parameters = (SQObjectPtr*)&f->_literals[nliterals]; + f->_nparameters = nparameters; + f->_functions = (SQObjectPtr*)&f->_parameters[nparameters]; + f->_nfunctions = nfunctions; + f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions]; + f->_noutervalues = noutervalues; + f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues]; + f->_nlineinfos = nlineinfos; + f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos]; + f->_nlocalvarinfos = nlocalvarinfos; + f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos]; + f->_ndefaultparams = ndefaultparams; + + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals); + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters); + _CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions); + _CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues); + //_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers + _CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos); + return f; + } + void Release(){ + _DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals); + _DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters); + _DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions); + _DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues); + //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers + _DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos); + SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams); + this->~SQFunctionProto(); + sq_vm_free(this,size); + } + + const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop); + SQInteger GetLine(SQInstruction *curr); + bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); + static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){ _NULL_SQOBJECT_VECTOR(_literals,_nliterals); } + SQObjectType GetType() {return OT_FUNCPROTO;} +#endif + SQObjectPtr _sourcename; + SQObjectPtr _name; + SQInteger _stacksize; + bool _bgenerator; + SQInteger _varparams; + + SQInteger _nlocalvarinfos; + SQLocalVarInfo *_localvarinfos; + + SQInteger _nlineinfos; + SQLineInfo *_lineinfos; + + SQInteger _nliterals; + SQObjectPtr *_literals; + + SQInteger _nparameters; + SQObjectPtr *_parameters; + + SQInteger _nfunctions; + SQObjectPtr *_functions; + + SQInteger _noutervalues; + SQOuterVar *_outervalues; + + SQInteger _ndefaultparams; + SQInteger *_defaultparams; + + SQInteger _ninstructions; + SQInstruction _instructions[1]; +}; + +#endif //_SQFUNCTION_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqfuncstate.cpp b/squirrel_3_0_1_stable/squirrel/sqfuncstate.cpp index 9e236c7e7..81ec7e31c 100644 --- a/squirrel_3_0_1_stable/squirrel/sqfuncstate.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqfuncstate.cpp @@ -1,652 +1,652 @@ -/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#ifndef NO_COMPILER
-#include "sqcompiler.h"
-#include "sqstring.h"
-#include "sqfuncproto.h"
-#include "sqtable.h"
-#include "sqopcodes.h"
-#include "sqfuncstate.h"
-
-#ifdef _DEBUG_DUMP
-SQInstructionDesc g_InstrDesc[]={
- {_SC("_OP_LINE")},
- {_SC("_OP_LOAD")},
- {_SC("_OP_LOADINT")},
- {_SC("_OP_LOADFLOAT")},
- {_SC("_OP_DLOAD")},
- {_SC("_OP_TAILCALL")},
- {_SC("_OP_CALL")},
- {_SC("_OP_PREPCALL")},
- {_SC("_OP_PREPCALLK")},
- {_SC("_OP_GETK")},
- {_SC("_OP_MOVE")},
- {_SC("_OP_NEWSLOT")},
- {_SC("_OP_DELETE")},
- {_SC("_OP_SET")},
- {_SC("_OP_GET")},
- {_SC("_OP_EQ")},
- {_SC("_OP_NE")},
- {_SC("_OP_ADD")},
- {_SC("_OP_SUB")},
- {_SC("_OP_MUL")},
- {_SC("_OP_DIV")},
- {_SC("_OP_MOD")},
- {_SC("_OP_BITW")},
- {_SC("_OP_RETURN")},
- {_SC("_OP_LOADNULLS")},
- {_SC("_OP_LOADROOT")},
- {_SC("_OP_LOADBOOL")},
- {_SC("_OP_DMOVE")},
- {_SC("_OP_JMP")},
- {_SC("_OP_JCMP")},
- {_SC("_OP_JZ")},
- {_SC("_OP_SETOUTER")},
- {_SC("_OP_GETOUTER")},
- {_SC("_OP_NEWOBJ")},
- {_SC("_OP_APPENDARRAY")},
- {_SC("_OP_COMPARITH")},
- {_SC("_OP_INC")},
- {_SC("_OP_INCL")},
- {_SC("_OP_PINC")},
- {_SC("_OP_PINCL")},
- {_SC("_OP_CMP")},
- {_SC("_OP_EXISTS")},
- {_SC("_OP_INSTANCEOF")},
- {_SC("_OP_AND")},
- {_SC("_OP_OR")},
- {_SC("_OP_NEG")},
- {_SC("_OP_NOT")},
- {_SC("_OP_BWNOT")},
- {_SC("_OP_CLOSURE")},
- {_SC("_OP_YIELD")},
- {_SC("_OP_RESUME")},
- {_SC("_OP_FOREACH")},
- {_SC("_OP_POSTFOREACH")},
- {_SC("_OP_CLONE")},
- {_SC("_OP_TYPEOF")},
- {_SC("_OP_PUSHTRAP")},
- {_SC("_OP_POPTRAP")},
- {_SC("_OP_THROW")},
- {_SC("_OP_NEWSLOTA")},
- {_SC("_OP_GETBASE")},
- {_SC("_OP_CLOSE")},
- {_SC("_OP_JCMP")}
-};
-#endif
-void DumpLiteral(SQObjectPtr &o)
-{
- switch(type(o)){
- case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break;
- case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break;
- case OT_INTEGER: scprintf(_SC("{") _PRINT_INT_FMT _SC("}"),_integer(o));break;
- case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break;
- default: scprintf(_SC("(%s %p)"),GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler
- }
-}
-
-SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
-{
- _nliterals = 0;
- _literals = SQTable::Create(ss,0);
- _strings = SQTable::Create(ss,0);
- _sharedstate = ss;
- _lastline = 0;
- _optimization = true;
- _parent = parent;
- _stacksize = 0;
- _traps = 0;
- _returnexp = 0;
- _varparams = false;
- _errfunc = efunc;
- _errtarget = ed;
- _bgenerator = false;
- _outers = 0;
- _ss = ss;
-
-}
-
-void SQFuncState::Error(const SQChar *err)
-{
- _errfunc(_errtarget,err);
-}
-
-#ifdef _DEBUG_DUMP
-void SQFuncState::Dump(SQFunctionProto *func)
-{
- SQUnsignedInteger n=0,i;
- SQInteger si;
- scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction));
- scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject));
- scprintf(_SC("--------------------------------------------------------------------\n"));
- scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown"));
- scprintf(_SC("-----LITERALS\n"));
- SQObjectPtr refidx,key,val;
- SQInteger idx;
- SQObjectPtrVec templiterals;
- templiterals.resize(_nliterals);
- while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
- refidx=idx;
- templiterals[_integer(val)]=key;
- }
- for(i=0;i<templiterals.size();i++){
- scprintf(_SC("[%d] "),n);
- DumpLiteral(templiterals[i]);
- scprintf(_SC("\n"));
- n++;
- }
- scprintf(_SC("-----PARAMS\n"));
- if(_varparams)
- scprintf(_SC("<<VARPARAMS>>\n"));
- n=0;
- for(i=0;i<_parameters.size();i++){
- scprintf(_SC("[%d] "),n);
- DumpLiteral(_parameters[i]);
- scprintf(_SC("\n"));
- n++;
- }
- scprintf(_SC("-----LOCALS\n"));
- for(si=0;si<func->_nlocalvarinfos;si++){
- SQLocalVarInfo lvi=func->_localvarinfos[si];
- scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op);
- n++;
- }
- scprintf(_SC("-----LINE INFO\n"));
- for(i=0;i<_lineinfos.size();i++){
- SQLineInfo li=_lineinfos[i];
- scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line);
- n++;
- }
- scprintf(_SC("-----dump\n"));
- n=0;
- for(i=0;i<_instructions.size();i++){
- SQInstruction &inst=_instructions[i];
- if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){
-
- SQInteger lidx = inst._arg1;
- scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0);
- if(lidx >= 0xFFFFFFFF)
- scprintf(_SC("null"));
- else {
- SQInteger refidx;
- SQObjectPtr val,key,refo;
- while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
- refo = refidx;
- }
- DumpLiteral(key);
- }
- if(inst.op != _OP_DLOAD) {
- scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3);
- }
- else {
- scprintf(_SC(" %d "),inst._arg2);
- lidx = inst._arg3;
- if(lidx >= 0xFFFFFFFF)
- scprintf(_SC("null"));
- else {
- SQInteger refidx;
- SQObjectPtr val,key,refo;
- while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
- refo = refidx;
- }
- DumpLiteral(key);
- scprintf(_SC("\n"));
- }
- }
- }
- else if(inst.op==_OP_LOADFLOAT) {
- scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3);
- }
- /* else if(inst.op==_OP_ARITH){
- scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
- }*/
- else {
- scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
- }
- n++;
- }
- scprintf(_SC("-----\n"));
- scprintf(_SC("stack size[%d]\n"),func->_stacksize);
- scprintf(_SC("--------------------------------------------------------------------\n\n"));
-}
-#endif
-
-SQInteger SQFuncState::GetNumericConstant(const SQInteger cons)
-{
- return GetConstant(SQObjectPtr(cons));
-}
-
-SQInteger SQFuncState::GetNumericConstant(const SQFloat cons)
-{
- return GetConstant(SQObjectPtr(cons));
-}
-
-SQInteger SQFuncState::GetConstant(const SQObject &cons)
-{
- SQObjectPtr val;
- if(!_table(_literals)->Get(cons,val))
- {
- val = _nliterals;
- _table(_literals)->NewSlot(cons,val);
- _nliterals++;
- if(_nliterals > MAX_LITERALS) {
- val.Null();
- Error(_SC("internal compiler error: too many literals"));
- }
- }
- return _integer(val);
-}
-
-void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3)
-{
- _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0);
- _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1);
- _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2);
- _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3);
-}
-
-void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)
-{
- switch(arg){
- case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break;
- case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break;
- case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break;
- case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break;
- };
-}
-
-SQInteger SQFuncState::AllocStackPos()
-{
- SQInteger npos=_vlocals.size();
- _vlocals.push_back(SQLocalVarInfo());
- if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) {
- if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals"));
- _stacksize=_vlocals.size();
- }
- return npos;
-}
-
-SQInteger SQFuncState::PushTarget(SQInteger n)
-{
- if(n!=-1){
- _targetstack.push_back(n);
- return n;
- }
- n=AllocStackPos();
- _targetstack.push_back(n);
- return n;
-}
-
-SQInteger SQFuncState::GetUpTarget(SQInteger n){
- return _targetstack[((_targetstack.size()-1)-n)];
-}
-
-SQInteger SQFuncState::TopTarget(){
- return _targetstack.back();
-}
-SQInteger SQFuncState::PopTarget()
-{
- SQInteger npos=_targetstack.back();
- SQLocalVarInfo &t=_vlocals[_targetstack.back()];
- if(type(t._name)==OT_NULL){
- _vlocals.pop_back();
- }
- _targetstack.pop_back();
- return npos;
-}
-
-SQInteger SQFuncState::GetStackSize()
-{
- return _vlocals.size();
-}
-
-SQInteger SQFuncState::CountOuters(SQInteger stacksize)
-{
- SQInteger outers = 0;
- SQInteger k = _vlocals.size() - 1;
- while(k >= stacksize) {
- SQLocalVarInfo &lvi = _vlocals[k];
- k--;
- if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer
- outers++;
- }
- }
- return outers;
-}
-
-void SQFuncState::SetStackSize(SQInteger n)
-{
- SQInteger size=_vlocals.size();
- while(size>n){
- size--;
- SQLocalVarInfo lvi = _vlocals.back();
- if(type(lvi._name)!=OT_NULL){
- if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer
- _outers--;
- }
- lvi._end_op = GetCurrentPos();
- _localvarinfos.push_back(lvi);
- }
- _vlocals.pop_back();
- }
-}
-
-bool SQFuncState::IsConstant(const SQObject &name,SQObject &e)
-{
- SQObjectPtr val;
- if(_table(_sharedstate->_consts)->Get(name,val)) {
- e = val;
- return true;
- }
- return false;
-}
-
-bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)
-{
- if(stkpos>=_vlocals.size())return false;
- else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true;
- return false;
-}
-
-SQInteger SQFuncState::PushLocalVariable(const SQObject &name)
-{
- SQInteger pos=_vlocals.size();
- SQLocalVarInfo lvi;
- lvi._name=name;
- lvi._start_op=GetCurrentPos()+1;
- lvi._pos=_vlocals.size();
- _vlocals.push_back(lvi);
- if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size();
- return pos;
-}
-
-
-
-SQInteger SQFuncState::GetLocalVariable(const SQObject &name)
-{
- SQInteger locals=_vlocals.size();
- while(locals>=1){
- SQLocalVarInfo &lvi = _vlocals[locals-1];
- if(type(lvi._name)==OT_STRING && _string(lvi._name)==_string(name)){
- return locals-1;
- }
- locals--;
- }
- return -1;
-}
-
-void SQFuncState::MarkLocalAsOuter(SQInteger pos)
-{
- SQLocalVarInfo &lvi = _vlocals[pos];
- lvi._end_op = UINT_MINUS_ONE;
- _outers++;
-}
-
-SQInteger SQFuncState::GetOuterVariable(const SQObject &name)
-{
- SQInteger outers = _outervalues.size();
- for(SQInteger i = 0; i<outers; i++) {
- if(_string(_outervalues[i]._name) == _string(name))
- return i;
- }
- SQInteger pos=-1;
- if(_parent) {
- pos = _parent->GetLocalVariable(name);
- if(pos == -1) {
- pos = _parent->GetOuterVariable(name);
- if(pos != -1) {
- _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local
- return _outervalues.size() - 1;
- }
- }
- else {
- _parent->MarkLocalAsOuter(pos);
- _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local
- return _outervalues.size() - 1;
-
-
- }
- }
- return -1;
-}
-
-void SQFuncState::AddParameter(const SQObject &name)
-{
- PushLocalVariable(name);
- _parameters.push_back(name);
-}
-
-void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force)
-{
- if(_lastline!=line || force){
- SQLineInfo li;
- li._line=line;li._op=(GetCurrentPos()+1);
- if(lineop)AddInstruction(_OP_LINE,0,line);
- if(_lastline!=line) {
- _lineinfos.push_back(li);
- }
- _lastline=line;
- }
-}
-
-void SQFuncState::DiscardTarget()
-{
- SQInteger discardedtarget = PopTarget();
- SQInteger size = _instructions.size();
- if(size > 0 && _optimization){
- SQInstruction &pi = _instructions[size-1];//previous instruction
- switch(pi.op) {
- case _OP_SET:case _OP_NEWSLOT:case _OP_SETOUTER:case _OP_CALL:
- if(pi._arg0 == discardedtarget) {
- pi._arg0 = 0xFF;
- }
- }
- }
-}
-
-void SQFuncState::AddInstruction(SQInstruction &i)
-{
- SQInteger size = _instructions.size();
- if(size > 0 && _optimization){ //simple optimizer
- SQInstruction &pi = _instructions[size-1];//previous instruction
- switch(i.op) {
- case _OP_JZ:
- if( pi.op == _OP_CMP && pi._arg1 < 0xFF) {
- pi.op = _OP_JCMP;
- pi._arg0 = (unsigned char)pi._arg1;
- pi._arg1 = i._arg1;
- return;
- }
- case _OP_SET:
- case _OP_NEWSLOT:
- if(i._arg0 == i._arg3) {
- i._arg0 = 0xFF;
- }
- break;
- case _OP_SETOUTER:
- if(i._arg0 == i._arg2) {
- i._arg0 = 0xFF;
- }
- break;
- case _OP_RETURN:
- if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) {
- pi.op = _OP_TAILCALL;
- } else if(pi.op == _OP_CLOSE){
- pi = i;
- return;
- }
- break;
- case _OP_GET:
- if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){
- pi._arg1 = pi._arg1;
- pi._arg2 = (unsigned char)i._arg1;
- pi.op = _OP_GETK;
- pi._arg0 = i._arg0;
-
- return;
- }
- break;
- case _OP_PREPCALL:
- if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
- pi.op = _OP_PREPCALLK;
- pi._arg0 = i._arg0;
- pi._arg1 = pi._arg1;
- pi._arg2 = i._arg2;
- pi._arg3 = i._arg3;
- return;
- }
- break;
- case _OP_APPENDARRAY: {
- SQInteger aat = -1;
- switch(pi.op) {
- case _OP_LOAD: aat = AAT_LITERAL; break;
- case _OP_LOADINT: aat = AAT_INT; break;
- case _OP_LOADBOOL: aat = AAT_BOOL; break;
- case _OP_LOADFLOAT: aat = AAT_FLOAT; break;
- default: break;
- }
- if(aat != -1 && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
- pi.op = _OP_APPENDARRAY;
- pi._arg0 = i._arg0;
- pi._arg1 = pi._arg1;
- pi._arg2 = (unsigned char)aat;
- pi._arg3 = MAX_FUNC_STACKSIZE;
- return;
- }
- }
- break;
- case _OP_MOVE:
- switch(pi.op) {
- case _OP_GET: case _OP_ADD: case _OP_SUB: case _OP_MUL: case _OP_DIV: case _OP_MOD: case _OP_BITW:
- case _OP_LOADINT: case _OP_LOADFLOAT: case _OP_LOADBOOL: case _OP_LOAD:
-
- if(pi._arg0 == i._arg1)
- {
- pi._arg0 = i._arg0;
- _optimization = false;
- //_result_elimination = false;
- return;
- }
- }
-
- if(pi.op == _OP_MOVE)
- {
- pi.op = _OP_DMOVE;
- pi._arg2 = i._arg0;
- pi._arg3 = (unsigned char)i._arg1;
- return;
- }
- break;
- case _OP_LOAD:
- if(pi.op == _OP_LOAD && i._arg1 < 256) {
- pi.op = _OP_DLOAD;
- pi._arg2 = i._arg0;
- pi._arg3 = (unsigned char)i._arg1;
- return;
- }
- break;
- case _OP_EQ:case _OP_NE:
- if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) ))
- {
- pi.op = i.op;
- pi._arg0 = i._arg0;
- pi._arg1 = pi._arg1;
- pi._arg2 = i._arg2;
- pi._arg3 = MAX_FUNC_STACKSIZE;
- return;
- }
- break;
- case _OP_LOADNULLS:
- if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) {
-
- pi._arg1 = pi._arg1 + 1;
- pi.op = _OP_LOADNULLS;
- return;
- }
- break;
- case _OP_LINE:
- if(pi.op == _OP_LINE) {
- _instructions.pop_back();
- _lineinfos.pop_back();
- }
- break;
- }
- }
- _optimization = true;
- _instructions.push_back(i);
-}
-
-SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len)
-{
- SQObjectPtr ns(SQString::Create(_sharedstate,s,len));
- _table(_strings)->NewSlot(ns,(SQInteger)1);
- return ns;
-}
-
-SQObject SQFuncState::CreateTable()
-{
- SQObjectPtr nt(SQTable::Create(_sharedstate,0));
- _table(_strings)->NewSlot(nt,(SQInteger)1);
- return nt;
-}
-
-SQFunctionProto *SQFuncState::BuildProto()
-{
-
- SQFunctionProto *f=SQFunctionProto::Create(_ss,_instructions.size(),
- _nliterals,_parameters.size(),_functions.size(),_outervalues.size(),
- _lineinfos.size(),_localvarinfos.size(),_defaultparams.size());
-
- SQObjectPtr refidx,key,val;
- SQInteger idx;
-
- f->_stacksize = _stacksize;
- f->_sourcename = _sourcename;
- f->_bgenerator = _bgenerator;
- f->_name = _name;
-
- while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
- f->_literals[_integer(val)]=key;
- refidx=idx;
- }
-
- for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf];
- for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np];
- for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no];
- for(SQUnsignedInteger nl = 0; nl < _localvarinfos.size(); nl++) f->_localvarinfos[nl] = _localvarinfos[nl];
- for(SQUnsignedInteger ni = 0; ni < _lineinfos.size(); ni++) f->_lineinfos[ni] = _lineinfos[ni];
- for(SQUnsignedInteger nd = 0; nd < _defaultparams.size(); nd++) f->_defaultparams[nd] = _defaultparams[nd];
-
- memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction));
-
- f->_varparams = _varparams;
-
- return f;
-}
-
-SQFuncState *SQFuncState::PushChildState(SQSharedState *ss)
-{
- SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));
- new (child) SQFuncState(ss,this,_errfunc,_errtarget);
- _childstates.push_back(child);
- return child;
-}
-
-void SQFuncState::PopChildState()
-{
- SQFuncState *child = _childstates.back();
- sq_delete(child,SQFuncState);
- _childstates.pop_back();
-}
-
-SQFuncState::~SQFuncState()
-{
- while(_childstates.size() > 0)
- {
- PopChildState();
- }
-}
-
-#endif
+/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#ifndef NO_COMPILER +#include "sqcompiler.h" +#include "sqstring.h" +#include "sqfuncproto.h" +#include "sqtable.h" +#include "sqopcodes.h" +#include "sqfuncstate.h" + +#ifdef _DEBUG_DUMP +SQInstructionDesc g_InstrDesc[]={ + {_SC("_OP_LINE")}, + {_SC("_OP_LOAD")}, + {_SC("_OP_LOADINT")}, + {_SC("_OP_LOADFLOAT")}, + {_SC("_OP_DLOAD")}, + {_SC("_OP_TAILCALL")}, + {_SC("_OP_CALL")}, + {_SC("_OP_PREPCALL")}, + {_SC("_OP_PREPCALLK")}, + {_SC("_OP_GETK")}, + {_SC("_OP_MOVE")}, + {_SC("_OP_NEWSLOT")}, + {_SC("_OP_DELETE")}, + {_SC("_OP_SET")}, + {_SC("_OP_GET")}, + {_SC("_OP_EQ")}, + {_SC("_OP_NE")}, + {_SC("_OP_ADD")}, + {_SC("_OP_SUB")}, + {_SC("_OP_MUL")}, + {_SC("_OP_DIV")}, + {_SC("_OP_MOD")}, + {_SC("_OP_BITW")}, + {_SC("_OP_RETURN")}, + {_SC("_OP_LOADNULLS")}, + {_SC("_OP_LOADROOT")}, + {_SC("_OP_LOADBOOL")}, + {_SC("_OP_DMOVE")}, + {_SC("_OP_JMP")}, + {_SC("_OP_JCMP")}, + {_SC("_OP_JZ")}, + {_SC("_OP_SETOUTER")}, + {_SC("_OP_GETOUTER")}, + {_SC("_OP_NEWOBJ")}, + {_SC("_OP_APPENDARRAY")}, + {_SC("_OP_COMPARITH")}, + {_SC("_OP_INC")}, + {_SC("_OP_INCL")}, + {_SC("_OP_PINC")}, + {_SC("_OP_PINCL")}, + {_SC("_OP_CMP")}, + {_SC("_OP_EXISTS")}, + {_SC("_OP_INSTANCEOF")}, + {_SC("_OP_AND")}, + {_SC("_OP_OR")}, + {_SC("_OP_NEG")}, + {_SC("_OP_NOT")}, + {_SC("_OP_BWNOT")}, + {_SC("_OP_CLOSURE")}, + {_SC("_OP_YIELD")}, + {_SC("_OP_RESUME")}, + {_SC("_OP_FOREACH")}, + {_SC("_OP_POSTFOREACH")}, + {_SC("_OP_CLONE")}, + {_SC("_OP_TYPEOF")}, + {_SC("_OP_PUSHTRAP")}, + {_SC("_OP_POPTRAP")}, + {_SC("_OP_THROW")}, + {_SC("_OP_NEWSLOTA")}, + {_SC("_OP_GETBASE")}, + {_SC("_OP_CLOSE")}, + {_SC("_OP_JCMP")} +}; +#endif +void DumpLiteral(SQObjectPtr &o) +{ + switch(type(o)){ + case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break; + case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break; + case OT_INTEGER: scprintf(_SC("{") _PRINT_INT_FMT _SC("}"),_integer(o));break; + case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break; + default: scprintf(_SC("(%s %p)"),GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler + } +} + +SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed) +{ + _nliterals = 0; + _literals = SQTable::Create(ss,0); + _strings = SQTable::Create(ss,0); + _sharedstate = ss; + _lastline = 0; + _optimization = true; + _parent = parent; + _stacksize = 0; + _traps = 0; + _returnexp = 0; + _varparams = false; + _errfunc = efunc; + _errtarget = ed; + _bgenerator = false; + _outers = 0; + _ss = ss; + +} + +void SQFuncState::Error(const SQChar *err) +{ + _errfunc(_errtarget,err); +} + +#ifdef _DEBUG_DUMP +void SQFuncState::Dump(SQFunctionProto *func) +{ + SQUnsignedInteger n=0,i; + SQInteger si; + scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction)); + scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject)); + scprintf(_SC("--------------------------------------------------------------------\n")); + scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown")); + scprintf(_SC("-----LITERALS\n")); + SQObjectPtr refidx,key,val; + SQInteger idx; + SQObjectPtrVec templiterals; + templiterals.resize(_nliterals); + while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { + refidx=idx; + templiterals[_integer(val)]=key; + } + for(i=0;i<templiterals.size();i++){ + scprintf(_SC("[%d] "),n); + DumpLiteral(templiterals[i]); + scprintf(_SC("\n")); + n++; + } + scprintf(_SC("-----PARAMS\n")); + if(_varparams) + scprintf(_SC("<<VARPARAMS>>\n")); + n=0; + for(i=0;i<_parameters.size();i++){ + scprintf(_SC("[%d] "),n); + DumpLiteral(_parameters[i]); + scprintf(_SC("\n")); + n++; + } + scprintf(_SC("-----LOCALS\n")); + for(si=0;si<func->_nlocalvarinfos;si++){ + SQLocalVarInfo lvi=func->_localvarinfos[si]; + scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op); + n++; + } + scprintf(_SC("-----LINE INFO\n")); + for(i=0;i<_lineinfos.size();i++){ + SQLineInfo li=_lineinfos[i]; + scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line); + n++; + } + scprintf(_SC("-----dump\n")); + n=0; + for(i=0;i<_instructions.size();i++){ + SQInstruction &inst=_instructions[i]; + if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){ + + SQInteger lidx = inst._arg1; + scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0); + if(lidx >= 0xFFFFFFFF) + scprintf(_SC("null")); + else { + SQInteger refidx; + SQObjectPtr val,key,refo; + while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { + refo = refidx; + } + DumpLiteral(key); + } + if(inst.op != _OP_DLOAD) { + scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3); + } + else { + scprintf(_SC(" %d "),inst._arg2); + lidx = inst._arg3; + if(lidx >= 0xFFFFFFFF) + scprintf(_SC("null")); + else { + SQInteger refidx; + SQObjectPtr val,key,refo; + while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { + refo = refidx; + } + DumpLiteral(key); + scprintf(_SC("\n")); + } + } + } + else if(inst.op==_OP_LOADFLOAT) { + scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3); + } + /* else if(inst.op==_OP_ARITH){ + scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); + }*/ + else { + scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); + } + n++; + } + scprintf(_SC("-----\n")); + scprintf(_SC("stack size[%d]\n"),func->_stacksize); + scprintf(_SC("--------------------------------------------------------------------\n\n")); +} +#endif + +SQInteger SQFuncState::GetNumericConstant(const SQInteger cons) +{ + return GetConstant(SQObjectPtr(cons)); +} + +SQInteger SQFuncState::GetNumericConstant(const SQFloat cons) +{ + return GetConstant(SQObjectPtr(cons)); +} + +SQInteger SQFuncState::GetConstant(const SQObject &cons) +{ + SQObjectPtr val; + if(!_table(_literals)->Get(cons,val)) + { + val = _nliterals; + _table(_literals)->NewSlot(cons,val); + _nliterals++; + if(_nliterals > MAX_LITERALS) { + val.Null(); + Error(_SC("internal compiler error: too many literals")); + } + } + return _integer(val); +} + +void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3) +{ + _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0); + _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1); + _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2); + _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3); +} + +void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val) +{ + switch(arg){ + case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break; + case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break; + case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break; + case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break; + }; +} + +SQInteger SQFuncState::AllocStackPos() +{ + SQInteger npos=_vlocals.size(); + _vlocals.push_back(SQLocalVarInfo()); + if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) { + if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals")); + _stacksize=_vlocals.size(); + } + return npos; +} + +SQInteger SQFuncState::PushTarget(SQInteger n) +{ + if(n!=-1){ + _targetstack.push_back(n); + return n; + } + n=AllocStackPos(); + _targetstack.push_back(n); + return n; +} + +SQInteger SQFuncState::GetUpTarget(SQInteger n){ + return _targetstack[((_targetstack.size()-1)-n)]; +} + +SQInteger SQFuncState::TopTarget(){ + return _targetstack.back(); +} +SQInteger SQFuncState::PopTarget() +{ + SQInteger npos=_targetstack.back(); + SQLocalVarInfo &t=_vlocals[_targetstack.back()]; + if(type(t._name)==OT_NULL){ + _vlocals.pop_back(); + } + _targetstack.pop_back(); + return npos; +} + +SQInteger SQFuncState::GetStackSize() +{ + return _vlocals.size(); +} + +SQInteger SQFuncState::CountOuters(SQInteger stacksize) +{ + SQInteger outers = 0; + SQInteger k = _vlocals.size() - 1; + while(k >= stacksize) { + SQLocalVarInfo &lvi = _vlocals[k]; + k--; + if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer + outers++; + } + } + return outers; +} + +void SQFuncState::SetStackSize(SQInteger n) +{ + SQInteger size=_vlocals.size(); + while(size>n){ + size--; + SQLocalVarInfo lvi = _vlocals.back(); + if(type(lvi._name)!=OT_NULL){ + if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer + _outers--; + } + lvi._end_op = GetCurrentPos(); + _localvarinfos.push_back(lvi); + } + _vlocals.pop_back(); + } +} + +bool SQFuncState::IsConstant(const SQObject &name,SQObject &e) +{ + SQObjectPtr val; + if(_table(_sharedstate->_consts)->Get(name,val)) { + e = val; + return true; + } + return false; +} + +bool SQFuncState::IsLocal(SQUnsignedInteger stkpos) +{ + if(stkpos>=_vlocals.size())return false; + else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true; + return false; +} + +SQInteger SQFuncState::PushLocalVariable(const SQObject &name) +{ + SQInteger pos=_vlocals.size(); + SQLocalVarInfo lvi; + lvi._name=name; + lvi._start_op=GetCurrentPos()+1; + lvi._pos=_vlocals.size(); + _vlocals.push_back(lvi); + if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size(); + return pos; +} + + + +SQInteger SQFuncState::GetLocalVariable(const SQObject &name) +{ + SQInteger locals=_vlocals.size(); + while(locals>=1){ + SQLocalVarInfo &lvi = _vlocals[locals-1]; + if(type(lvi._name)==OT_STRING && _string(lvi._name)==_string(name)){ + return locals-1; + } + locals--; + } + return -1; +} + +void SQFuncState::MarkLocalAsOuter(SQInteger pos) +{ + SQLocalVarInfo &lvi = _vlocals[pos]; + lvi._end_op = UINT_MINUS_ONE; + _outers++; +} + +SQInteger SQFuncState::GetOuterVariable(const SQObject &name) +{ + SQInteger outers = _outervalues.size(); + for(SQInteger i = 0; i<outers; i++) { + if(_string(_outervalues[i]._name) == _string(name)) + return i; + } + SQInteger pos=-1; + if(_parent) { + pos = _parent->GetLocalVariable(name); + if(pos == -1) { + pos = _parent->GetOuterVariable(name); + if(pos != -1) { + _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local + return _outervalues.size() - 1; + } + } + else { + _parent->MarkLocalAsOuter(pos); + _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local + return _outervalues.size() - 1; + + + } + } + return -1; +} + +void SQFuncState::AddParameter(const SQObject &name) +{ + PushLocalVariable(name); + _parameters.push_back(name); +} + +void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force) +{ + if(_lastline!=line || force){ + SQLineInfo li; + li._line=line;li._op=(GetCurrentPos()+1); + if(lineop)AddInstruction(_OP_LINE,0,line); + if(_lastline!=line) { + _lineinfos.push_back(li); + } + _lastline=line; + } +} + +void SQFuncState::DiscardTarget() +{ + SQInteger discardedtarget = PopTarget(); + SQInteger size = _instructions.size(); + if(size > 0 && _optimization){ + SQInstruction &pi = _instructions[size-1];//previous instruction + switch(pi.op) { + case _OP_SET:case _OP_NEWSLOT:case _OP_SETOUTER:case _OP_CALL: + if(pi._arg0 == discardedtarget) { + pi._arg0 = 0xFF; + } + } + } +} + +void SQFuncState::AddInstruction(SQInstruction &i) +{ + SQInteger size = _instructions.size(); + if(size > 0 && _optimization){ //simple optimizer + SQInstruction &pi = _instructions[size-1];//previous instruction + switch(i.op) { + case _OP_JZ: + if( pi.op == _OP_CMP && pi._arg1 < 0xFF) { + pi.op = _OP_JCMP; + pi._arg0 = (unsigned char)pi._arg1; + pi._arg1 = i._arg1; + return; + } + case _OP_SET: + case _OP_NEWSLOT: + if(i._arg0 == i._arg3) { + i._arg0 = 0xFF; + } + break; + case _OP_SETOUTER: + if(i._arg0 == i._arg2) { + i._arg0 = 0xFF; + } + break; + case _OP_RETURN: + if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) { + pi.op = _OP_TAILCALL; + } else if(pi.op == _OP_CLOSE){ + pi = i; + return; + } + break; + case _OP_GET: + if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){ + pi._arg1 = pi._arg1; + pi._arg2 = (unsigned char)i._arg1; + pi.op = _OP_GETK; + pi._arg0 = i._arg0; + + return; + } + break; + case _OP_PREPCALL: + if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ + pi.op = _OP_PREPCALLK; + pi._arg0 = i._arg0; + pi._arg1 = pi._arg1; + pi._arg2 = i._arg2; + pi._arg3 = i._arg3; + return; + } + break; + case _OP_APPENDARRAY: { + SQInteger aat = -1; + switch(pi.op) { + case _OP_LOAD: aat = AAT_LITERAL; break; + case _OP_LOADINT: aat = AAT_INT; break; + case _OP_LOADBOOL: aat = AAT_BOOL; break; + case _OP_LOADFLOAT: aat = AAT_FLOAT; break; + default: break; + } + if(aat != -1 && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ + pi.op = _OP_APPENDARRAY; + pi._arg0 = i._arg0; + pi._arg1 = pi._arg1; + pi._arg2 = (unsigned char)aat; + pi._arg3 = MAX_FUNC_STACKSIZE; + return; + } + } + break; + case _OP_MOVE: + switch(pi.op) { + case _OP_GET: case _OP_ADD: case _OP_SUB: case _OP_MUL: case _OP_DIV: case _OP_MOD: case _OP_BITW: + case _OP_LOADINT: case _OP_LOADFLOAT: case _OP_LOADBOOL: case _OP_LOAD: + + if(pi._arg0 == i._arg1) + { + pi._arg0 = i._arg0; + _optimization = false; + //_result_elimination = false; + return; + } + } + + if(pi.op == _OP_MOVE) + { + pi.op = _OP_DMOVE; + pi._arg2 = i._arg0; + pi._arg3 = (unsigned char)i._arg1; + return; + } + break; + case _OP_LOAD: + if(pi.op == _OP_LOAD && i._arg1 < 256) { + pi.op = _OP_DLOAD; + pi._arg2 = i._arg0; + pi._arg3 = (unsigned char)i._arg1; + return; + } + break; + case _OP_EQ:case _OP_NE: + if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) )) + { + pi.op = i.op; + pi._arg0 = i._arg0; + pi._arg1 = pi._arg1; + pi._arg2 = i._arg2; + pi._arg3 = MAX_FUNC_STACKSIZE; + return; + } + break; + case _OP_LOADNULLS: + if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) { + + pi._arg1 = pi._arg1 + 1; + pi.op = _OP_LOADNULLS; + return; + } + break; + case _OP_LINE: + if(pi.op == _OP_LINE) { + _instructions.pop_back(); + _lineinfos.pop_back(); + } + break; + } + } + _optimization = true; + _instructions.push_back(i); +} + +SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len) +{ + SQObjectPtr ns(SQString::Create(_sharedstate,s,len)); + _table(_strings)->NewSlot(ns,(SQInteger)1); + return ns; +} + +SQObject SQFuncState::CreateTable() +{ + SQObjectPtr nt(SQTable::Create(_sharedstate,0)); + _table(_strings)->NewSlot(nt,(SQInteger)1); + return nt; +} + +SQFunctionProto *SQFuncState::BuildProto() +{ + + SQFunctionProto *f=SQFunctionProto::Create(_ss,_instructions.size(), + _nliterals,_parameters.size(),_functions.size(),_outervalues.size(), + _lineinfos.size(),_localvarinfos.size(),_defaultparams.size()); + + SQObjectPtr refidx,key,val; + SQInteger idx; + + f->_stacksize = _stacksize; + f->_sourcename = _sourcename; + f->_bgenerator = _bgenerator; + f->_name = _name; + + while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { + f->_literals[_integer(val)]=key; + refidx=idx; + } + + for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf]; + for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np]; + for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no]; + for(SQUnsignedInteger nl = 0; nl < _localvarinfos.size(); nl++) f->_localvarinfos[nl] = _localvarinfos[nl]; + for(SQUnsignedInteger ni = 0; ni < _lineinfos.size(); ni++) f->_lineinfos[ni] = _lineinfos[ni]; + for(SQUnsignedInteger nd = 0; nd < _defaultparams.size(); nd++) f->_defaultparams[nd] = _defaultparams[nd]; + + memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction)); + + f->_varparams = _varparams; + + return f; +} + +SQFuncState *SQFuncState::PushChildState(SQSharedState *ss) +{ + SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState)); + new (child) SQFuncState(ss,this,_errfunc,_errtarget); + _childstates.push_back(child); + return child; +} + +void SQFuncState::PopChildState() +{ + SQFuncState *child = _childstates.back(); + sq_delete(child,SQFuncState); + _childstates.pop_back(); +} + +SQFuncState::~SQFuncState() +{ + while(_childstates.size() > 0) + { + PopChildState(); + } +} + +#endif diff --git a/squirrel_3_0_1_stable/squirrel/sqfuncstate.h b/squirrel_3_0_1_stable/squirrel/sqfuncstate.h index 1da13212a..2ae220087 100644 --- a/squirrel_3_0_1_stable/squirrel/sqfuncstate.h +++ b/squirrel_3_0_1_stable/squirrel/sqfuncstate.h @@ -1,91 +1,91 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQFUNCSTATE_H_
-#define _SQFUNCSTATE_H_
-///////////////////////////////////
-#include "squtils.h"
-
-struct SQFuncState
-{
- SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);
- ~SQFuncState();
-#ifdef _DEBUG_DUMP
- void Dump(SQFunctionProto *func);
-#endif
- void Error(const SQChar *err);
- SQFuncState *PushChildState(SQSharedState *ss);
- void PopChildState();
- void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}
- void AddInstruction(SQInstruction &i);
- void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0);
- void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val);
- SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];}
- void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();}
- void SetStackSize(SQInteger n);
- SQInteger CountOuters(SQInteger stacksize);
- void SnoozeOpt(){_optimization=false;}
- void AddDefaultParam(SQInteger trg) { _defaultparams.push_back(trg); }
- SQInteger GetDefaultParamCount() { return _defaultparams.size(); }
- SQInteger GetCurrentPos(){return _instructions.size()-1;}
- SQInteger GetNumericConstant(const SQInteger cons);
- SQInteger GetNumericConstant(const SQFloat cons);
- SQInteger PushLocalVariable(const SQObject &name);
- void AddParameter(const SQObject &name);
- //void AddOuterValue(const SQObject &name);
- SQInteger GetLocalVariable(const SQObject &name);
- void MarkLocalAsOuter(SQInteger pos);
- SQInteger GetOuterVariable(const SQObject &name);
- SQInteger GenerateCode();
- SQInteger GetStackSize();
- SQInteger CalcStackFrameSize();
- void AddLineInfos(SQInteger line,bool lineop,bool force=false);
- SQFunctionProto *BuildProto();
- SQInteger AllocStackPos();
- SQInteger PushTarget(SQInteger n=-1);
- SQInteger PopTarget();
- SQInteger TopTarget();
- SQInteger GetUpTarget(SQInteger n);
- void DiscardTarget();
- bool IsLocal(SQUnsignedInteger stkpos);
- SQObject CreateString(const SQChar *s,SQInteger len = -1);
- SQObject CreateTable();
- bool IsConstant(const SQObject &name,SQObject &e);
- SQInteger _returnexp;
- SQLocalVarInfoVec _vlocals;
- SQIntVec _targetstack;
- SQInteger _stacksize;
- bool _varparams;
- bool _bgenerator;
- SQIntVec _unresolvedbreaks;
- SQIntVec _unresolvedcontinues;
- SQObjectPtrVec _functions;
- SQObjectPtrVec _parameters;
- SQOuterVarVec _outervalues;
- SQInstructionVec _instructions;
- SQLocalVarInfoVec _localvarinfos;
- SQObjectPtr _literals;
- SQObjectPtr _strings;
- SQObjectPtr _name;
- SQObjectPtr _sourcename;
- SQInteger _nliterals;
- SQLineInfoVec _lineinfos;
- SQFuncState *_parent;
- SQIntVec _scope_blocks;
- SQIntVec _breaktargets;
- SQIntVec _continuetargets;
- SQIntVec _defaultparams;
- SQInteger _lastline;
- SQInteger _traps; //contains number of nested exception traps
- SQInteger _outers;
- bool _optimization;
- SQSharedState *_sharedstate;
- sqvector<SQFuncState*> _childstates;
- SQInteger GetConstant(const SQObject &cons);
-private:
- CompilerErrorFunc _errfunc;
- void *_errtarget;
- SQSharedState *_ss;
-};
-
-
-#endif //_SQFUNCSTATE_H_
-
+/* see copyright notice in squirrel.h */ +#ifndef _SQFUNCSTATE_H_ +#define _SQFUNCSTATE_H_ +/////////////////////////////////// +#include "squtils.h" + +struct SQFuncState +{ + SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed); + ~SQFuncState(); +#ifdef _DEBUG_DUMP + void Dump(SQFunctionProto *func); +#endif + void Error(const SQChar *err); + SQFuncState *PushChildState(SQSharedState *ss); + void PopChildState(); + void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);} + void AddInstruction(SQInstruction &i); + void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0); + void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val); + SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];} + void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();} + void SetStackSize(SQInteger n); + SQInteger CountOuters(SQInteger stacksize); + void SnoozeOpt(){_optimization=false;} + void AddDefaultParam(SQInteger trg) { _defaultparams.push_back(trg); } + SQInteger GetDefaultParamCount() { return _defaultparams.size(); } + SQInteger GetCurrentPos(){return _instructions.size()-1;} + SQInteger GetNumericConstant(const SQInteger cons); + SQInteger GetNumericConstant(const SQFloat cons); + SQInteger PushLocalVariable(const SQObject &name); + void AddParameter(const SQObject &name); + //void AddOuterValue(const SQObject &name); + SQInteger GetLocalVariable(const SQObject &name); + void MarkLocalAsOuter(SQInteger pos); + SQInteger GetOuterVariable(const SQObject &name); + SQInteger GenerateCode(); + SQInteger GetStackSize(); + SQInteger CalcStackFrameSize(); + void AddLineInfos(SQInteger line,bool lineop,bool force=false); + SQFunctionProto *BuildProto(); + SQInteger AllocStackPos(); + SQInteger PushTarget(SQInteger n=-1); + SQInteger PopTarget(); + SQInteger TopTarget(); + SQInteger GetUpTarget(SQInteger n); + void DiscardTarget(); + bool IsLocal(SQUnsignedInteger stkpos); + SQObject CreateString(const SQChar *s,SQInteger len = -1); + SQObject CreateTable(); + bool IsConstant(const SQObject &name,SQObject &e); + SQInteger _returnexp; + SQLocalVarInfoVec _vlocals; + SQIntVec _targetstack; + SQInteger _stacksize; + bool _varparams; + bool _bgenerator; + SQIntVec _unresolvedbreaks; + SQIntVec _unresolvedcontinues; + SQObjectPtrVec _functions; + SQObjectPtrVec _parameters; + SQOuterVarVec _outervalues; + SQInstructionVec _instructions; + SQLocalVarInfoVec _localvarinfos; + SQObjectPtr _literals; + SQObjectPtr _strings; + SQObjectPtr _name; + SQObjectPtr _sourcename; + SQInteger _nliterals; + SQLineInfoVec _lineinfos; + SQFuncState *_parent; + SQIntVec _scope_blocks; + SQIntVec _breaktargets; + SQIntVec _continuetargets; + SQIntVec _defaultparams; + SQInteger _lastline; + SQInteger _traps; //contains number of nested exception traps + SQInteger _outers; + bool _optimization; + SQSharedState *_sharedstate; + sqvector<SQFuncState*> _childstates; + SQInteger GetConstant(const SQObject &cons); +private: + CompilerErrorFunc _errfunc; + void *_errtarget; + SQSharedState *_ss; +}; + + +#endif //_SQFUNCSTATE_H_ + diff --git a/squirrel_3_0_1_stable/squirrel/sqlexer.cpp b/squirrel_3_0_1_stable/squirrel/sqlexer.cpp index ab17ba619..ec1704b71 100644 --- a/squirrel_3_0_1_stable/squirrel/sqlexer.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqlexer.cpp @@ -1,489 +1,489 @@ -/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <ctype.h>
-#include <stdlib.h>
-#include "sqtable.h"
-#include "sqstring.h"
-#include "sqcompiler.h"
-#include "sqlexer.h"
-
-#define CUR_CHAR (_currdata)
-#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;}
-#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB)
-#define NEXT() {Next();_currentcolumn++;}
-#define INIT_TEMP_STRING() { _longstr.resize(0);}
-#define APPEND_CHAR(c) { _longstr.push_back(c);}
-#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));}
-#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id))
-
-SQLexer::SQLexer(){}
-SQLexer::~SQLexer()
-{
- _keywords->Release();
-}
-
-void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
-{
- _errfunc = efunc;
- _errtarget = ed;
- _sharedstate = ss;
- _keywords = SQTable::Create(ss, 26);
- ADD_KEYWORD(while, TK_WHILE);
- ADD_KEYWORD(do, TK_DO);
- ADD_KEYWORD(if, TK_IF);
- ADD_KEYWORD(else, TK_ELSE);
- ADD_KEYWORD(break, TK_BREAK);
- ADD_KEYWORD(continue, TK_CONTINUE);
- ADD_KEYWORD(return, TK_RETURN);
- ADD_KEYWORD(null, TK_NULL);
- ADD_KEYWORD(function, TK_FUNCTION);
- ADD_KEYWORD(local, TK_LOCAL);
- ADD_KEYWORD(for, TK_FOR);
- ADD_KEYWORD(foreach, TK_FOREACH);
- ADD_KEYWORD(in, TK_IN);
- ADD_KEYWORD(typeof, TK_TYPEOF);
- ADD_KEYWORD(base, TK_BASE);
- ADD_KEYWORD(delete, TK_DELETE);
- ADD_KEYWORD(try, TK_TRY);
- ADD_KEYWORD(catch, TK_CATCH);
- ADD_KEYWORD(throw, TK_THROW);
- ADD_KEYWORD(clone, TK_CLONE);
- ADD_KEYWORD(yield, TK_YIELD);
- ADD_KEYWORD(resume, TK_RESUME);
- ADD_KEYWORD(switch, TK_SWITCH);
- ADD_KEYWORD(case, TK_CASE);
- ADD_KEYWORD(default, TK_DEFAULT);
- ADD_KEYWORD(this, TK_THIS);
- ADD_KEYWORD(class,TK_CLASS);
- ADD_KEYWORD(extends,TK_EXTENDS);
- ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
- ADD_KEYWORD(instanceof,TK_INSTANCEOF);
- ADD_KEYWORD(true,TK_TRUE);
- ADD_KEYWORD(false,TK_FALSE);
- ADD_KEYWORD(static,TK_STATIC);
- ADD_KEYWORD(enum,TK_ENUM);
- ADD_KEYWORD(const,TK_CONST);
-
- _readf = rg;
- _up = up;
- _lasttokenline = _currentline = 1;
- _currentcolumn = 0;
- _prevtoken = -1;
- _reached_eof = SQFalse;
- Next();
-}
-
-void SQLexer::Error(const SQChar *err)
-{
- _errfunc(_errtarget,err);
-}
-
-void SQLexer::Next()
-{
- SQInteger t = _readf(_up);
- if(t > MAX_CHAR) Error(_SC("Invalid character"));
- if(t != 0) {
- _currdata = (LexChar)t;
- return;
- }
- _currdata = SQUIRREL_EOB;
- _reached_eof = SQTrue;
-}
-
-const SQChar *SQLexer::Tok2Str(SQInteger tok)
-{
- SQObjectPtr itr, key, val;
- SQInteger nitr;
- while((nitr = _keywords->Next(false,itr, key, val)) != -1) {
- itr = (SQInteger)nitr;
- if(((SQInteger)_integer(val)) == tok)
- return _stringval(key);
- }
- return NULL;
-}
-
-void SQLexer::LexBlockComment()
-{
- bool done = false;
- while(!done) {
- switch(CUR_CHAR) {
- case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
- case _SC('\n'): _currentline++; NEXT(); continue;
- case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
- default: NEXT();
- }
- }
-}
-void SQLexer::LexLineComment()
-{
- do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
-}
-
-SQInteger SQLexer::Lex()
-{
- _lasttokenline = _currentline;
- while(CUR_CHAR != SQUIRREL_EOB) {
- switch(CUR_CHAR){
- case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;
- case _SC('\n'):
- _currentline++;
- _prevtoken=_curtoken;
- _curtoken=_SC('\n');
- NEXT();
- _currentcolumn=1;
- continue;
- case _SC('#'): LexLineComment(); continue;
- case _SC('/'):
- NEXT();
- switch(CUR_CHAR){
- case _SC('*'):
- NEXT();
- LexBlockComment();
- continue;
- case _SC('/'):
- LexLineComment();
- continue;
- case _SC('='):
- NEXT();
- RETURN_TOKEN(TK_DIVEQ);
- continue;
- case _SC('>'):
- NEXT();
- RETURN_TOKEN(TK_ATTR_CLOSE);
- continue;
- default:
- RETURN_TOKEN('/');
- }
- case _SC('='):
- NEXT();
- if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }
- else { NEXT(); RETURN_TOKEN(TK_EQ); }
- case _SC('<'):
- NEXT();
- switch(CUR_CHAR) {
- case _SC('='):
- NEXT();
- if(CUR_CHAR == _SC('>')) {
- NEXT();
- RETURN_TOKEN(TK_3WAYSCMP);
- }
- RETURN_TOKEN(TK_LE)
- break;
- case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break;
- case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break;
- case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break;
- }
- RETURN_TOKEN('<');
- case _SC('>'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}
- else if(CUR_CHAR == _SC('>')){
- NEXT();
- if(CUR_CHAR == _SC('>')){
- NEXT();
- RETURN_TOKEN(TK_USHIFTR);
- }
- RETURN_TOKEN(TK_SHIFTR);
- }
- else { RETURN_TOKEN('>') }
- case _SC('!'):
- NEXT();
- if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
- else { NEXT(); RETURN_TOKEN(TK_NE); }
- case _SC('@'): {
- SQInteger stype;
- NEXT();
- if(CUR_CHAR != _SC('"')) {
- RETURN_TOKEN('@');
- }
- if((stype=ReadString('"',true))!=-1) {
- RETURN_TOKEN(stype);
- }
- Error(_SC("error parsing the string"));
- }
- case _SC('"'):
- case _SC('\''): {
- SQInteger stype;
- if((stype=ReadString(CUR_CHAR,false))!=-1){
- RETURN_TOKEN(stype);
- }
- Error(_SC("error parsing the string"));
- }
- case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
- case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):
- {SQInteger ret = CUR_CHAR;
- NEXT(); RETURN_TOKEN(ret); }
- case _SC('.'):
- NEXT();
- if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
- NEXT();
- if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
- NEXT();
- RETURN_TOKEN(TK_VARPARAMS);
- case _SC('&'):
- NEXT();
- if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
- else { NEXT(); RETURN_TOKEN(TK_AND); }
- case _SC('|'):
- NEXT();
- if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }
- else { NEXT(); RETURN_TOKEN(TK_OR); }
- case _SC(':'):
- NEXT();
- if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }
- else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }
- case _SC('*'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}
- else RETURN_TOKEN('*');
- case _SC('%'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}
- else RETURN_TOKEN('%');
- case _SC('-'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}
- else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}
- else RETURN_TOKEN('-');
- case _SC('+'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}
- else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}
- else RETURN_TOKEN('+');
- case SQUIRREL_EOB:
- return 0;
- default:{
- if (scisdigit(CUR_CHAR)) {
- SQInteger ret = ReadNumber();
- RETURN_TOKEN(ret);
- }
- else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
- SQInteger t = ReadID();
- RETURN_TOKEN(t);
- }
- else {
- SQInteger c = CUR_CHAR;
- if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
- NEXT();
- RETURN_TOKEN(c);
- }
- RETURN_TOKEN(0);
- }
- }
- }
- return 0;
-}
-
-SQInteger SQLexer::GetIDType(SQChar *s)
-{
- SQObjectPtr t;
- if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {
- return SQInteger(_integer(t));
- }
- return TK_IDENTIFIER;
-}
-
-
-SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
-{
- INIT_TEMP_STRING();
- NEXT();
- if(IS_EOB()) return -1;
- for(;;) {
- while(CUR_CHAR != ndelim) {
- switch(CUR_CHAR) {
- case SQUIRREL_EOB:
- Error(_SC("unfinished string"));
- return -1;
- case _SC('\n'):
- if(!verbatim) Error(_SC("newline in a constant"));
- APPEND_CHAR(CUR_CHAR); NEXT();
- _currentline++;
- break;
- case _SC('\\'):
- if(verbatim) {
- APPEND_CHAR('\\'); NEXT();
- }
- else {
- NEXT();
- switch(CUR_CHAR) {
- case _SC('x'): NEXT(); {
- if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
- const SQInteger maxdigits = 4;
- SQChar temp[maxdigits+1];
- SQInteger n = 0;
- while(isxdigit(CUR_CHAR) && n < maxdigits) {
- temp[n] = CUR_CHAR;
- n++;
- NEXT();
- }
- temp[n] = 0;
- SQChar *sTemp;
- APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));
- }
- break;
- case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;
- case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;
- case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;
- case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;
- case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;
- case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;
- case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;
- case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;
- case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;
- case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
- case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
- default:
- Error(_SC("unrecognised escaper char"));
- break;
- }
- }
- break;
- default:
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- }
- NEXT();
- if(verbatim && CUR_CHAR == '"') { //double quotation
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- else {
- break;
- }
- }
- TERMINATE_BUFFER();
- SQInteger len = _longstr.size()-1;
- if(ndelim == _SC('\'')) {
- if(len == 0) Error(_SC("empty constant"));
- if(len > 1) Error(_SC("constant too long"));
- _nvalue = _longstr[0];
- return TK_INTEGER;
- }
- _svalue = &_longstr[0];
- return TK_STRING_LITERAL;
-}
-
-void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res)
-{
- *res = 0;
- while(*s != 0)
- {
- if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0');
- else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10);
- else { assert(0); }
- }
-}
-
-void LexInteger(const SQChar *s,SQUnsignedInteger *res)
-{
- *res = 0;
- while(*s != 0)
- {
- *res = (*res)*10+((*s++)-'0');
- }
-}
-
-SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); }
-
-void LexOctal(const SQChar *s,SQUnsignedInteger *res)
-{
- *res = 0;
- while(*s != 0)
- {
- if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0');
- else { assert(0); }
- }
-}
-
-SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; }
-
-
-#define MAX_HEX_DIGITS (sizeof(SQInteger)*2)
-SQInteger SQLexer::ReadNumber()
-{
-#define TINT 1
-#define TFLOAT 2
-#define THEX 3
-#define TSCIENTIFIC 4
-#define TOCTAL 5
- SQInteger type = TINT, firstchar = CUR_CHAR;
- SQChar *sTemp;
- INIT_TEMP_STRING();
- NEXT();
- if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) {
- if(scisodigit(CUR_CHAR)) {
- type = TOCTAL;
- while(scisodigit(CUR_CHAR)) {
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number"));
- }
- else {
- NEXT();
- type = THEX;
- while(isxdigit(CUR_CHAR)) {
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));
- }
- }
- else {
- APPEND_CHAR((int)firstchar);
- while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
- if(CUR_CHAR == _SC('.')) type = TFLOAT;
- if(isexponent(CUR_CHAR)) {
- if(type != TFLOAT) Error(_SC("invalid numeric format"));
- type = TSCIENTIFIC;
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- if(CUR_CHAR == '+' || CUR_CHAR == '-'){
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
- }
-
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- }
- TERMINATE_BUFFER();
- switch(type) {
- case TSCIENTIFIC:
- case TFLOAT:
- _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
- return TK_FLOAT;
- case TINT:
- LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
- return TK_INTEGER;
- case THEX:
- LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
- return TK_INTEGER;
- case TOCTAL:
- LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
- return TK_INTEGER;
- }
- return 0;
-}
-
-SQInteger SQLexer::ReadID()
-{
- SQInteger res;
- INIT_TEMP_STRING();
- do {
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
- TERMINATE_BUFFER();
- res = GetIDType(&_longstr[0]);
- if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
- _svalue = &_longstr[0];
- }
- return res;
-}
+/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include <ctype.h> +#include <stdlib.h> +#include "sqtable.h" +#include "sqstring.h" +#include "sqcompiler.h" +#include "sqlexer.h" + +#define CUR_CHAR (_currdata) +#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;} +#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB) +#define NEXT() {Next();_currentcolumn++;} +#define INIT_TEMP_STRING() { _longstr.resize(0);} +#define APPEND_CHAR(c) { _longstr.push_back(c);} +#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));} +#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id)) + +SQLexer::SQLexer(){} +SQLexer::~SQLexer() +{ + _keywords->Release(); +} + +void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed) +{ + _errfunc = efunc; + _errtarget = ed; + _sharedstate = ss; + _keywords = SQTable::Create(ss, 26); + ADD_KEYWORD(while, TK_WHILE); + ADD_KEYWORD(do, TK_DO); + ADD_KEYWORD(if, TK_IF); + ADD_KEYWORD(else, TK_ELSE); + ADD_KEYWORD(break, TK_BREAK); + ADD_KEYWORD(continue, TK_CONTINUE); + ADD_KEYWORD(return, TK_RETURN); + ADD_KEYWORD(null, TK_NULL); + ADD_KEYWORD(function, TK_FUNCTION); + ADD_KEYWORD(local, TK_LOCAL); + ADD_KEYWORD(for, TK_FOR); + ADD_KEYWORD(foreach, TK_FOREACH); + ADD_KEYWORD(in, TK_IN); + ADD_KEYWORD(typeof, TK_TYPEOF); + ADD_KEYWORD(base, TK_BASE); + ADD_KEYWORD(delete, TK_DELETE); + ADD_KEYWORD(try, TK_TRY); + ADD_KEYWORD(catch, TK_CATCH); + ADD_KEYWORD(throw, TK_THROW); + ADD_KEYWORD(clone, TK_CLONE); + ADD_KEYWORD(yield, TK_YIELD); + ADD_KEYWORD(resume, TK_RESUME); + ADD_KEYWORD(switch, TK_SWITCH); + ADD_KEYWORD(case, TK_CASE); + ADD_KEYWORD(default, TK_DEFAULT); + ADD_KEYWORD(this, TK_THIS); + ADD_KEYWORD(class,TK_CLASS); + ADD_KEYWORD(extends,TK_EXTENDS); + ADD_KEYWORD(constructor,TK_CONSTRUCTOR); + ADD_KEYWORD(instanceof,TK_INSTANCEOF); + ADD_KEYWORD(true,TK_TRUE); + ADD_KEYWORD(false,TK_FALSE); + ADD_KEYWORD(static,TK_STATIC); + ADD_KEYWORD(enum,TK_ENUM); + ADD_KEYWORD(const,TK_CONST); + + _readf = rg; + _up = up; + _lasttokenline = _currentline = 1; + _currentcolumn = 0; + _prevtoken = -1; + _reached_eof = SQFalse; + Next(); +} + +void SQLexer::Error(const SQChar *err) +{ + _errfunc(_errtarget,err); +} + +void SQLexer::Next() +{ + SQInteger t = _readf(_up); + if(t > MAX_CHAR) Error(_SC("Invalid character")); + if(t != 0) { + _currdata = (LexChar)t; + return; + } + _currdata = SQUIRREL_EOB; + _reached_eof = SQTrue; +} + +const SQChar *SQLexer::Tok2Str(SQInteger tok) +{ + SQObjectPtr itr, key, val; + SQInteger nitr; + while((nitr = _keywords->Next(false,itr, key, val)) != -1) { + itr = (SQInteger)nitr; + if(((SQInteger)_integer(val)) == tok) + return _stringval(key); + } + return NULL; +} + +void SQLexer::LexBlockComment() +{ + bool done = false; + while(!done) { + switch(CUR_CHAR) { + case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue; + case _SC('\n'): _currentline++; NEXT(); continue; + case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment")); + default: NEXT(); + } + } +} +void SQLexer::LexLineComment() +{ + do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB())); +} + +SQInteger SQLexer::Lex() +{ + _lasttokenline = _currentline; + while(CUR_CHAR != SQUIRREL_EOB) { + switch(CUR_CHAR){ + case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue; + case _SC('\n'): + _currentline++; + _prevtoken=_curtoken; + _curtoken=_SC('\n'); + NEXT(); + _currentcolumn=1; + continue; + case _SC('#'): LexLineComment(); continue; + case _SC('/'): + NEXT(); + switch(CUR_CHAR){ + case _SC('*'): + NEXT(); + LexBlockComment(); + continue; + case _SC('/'): + LexLineComment(); + continue; + case _SC('='): + NEXT(); + RETURN_TOKEN(TK_DIVEQ); + continue; + case _SC('>'): + NEXT(); + RETURN_TOKEN(TK_ATTR_CLOSE); + continue; + default: + RETURN_TOKEN('/'); + } + case _SC('='): + NEXT(); + if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') } + else { NEXT(); RETURN_TOKEN(TK_EQ); } + case _SC('<'): + NEXT(); + switch(CUR_CHAR) { + case _SC('='): + NEXT(); + if(CUR_CHAR == _SC('>')) { + NEXT(); + RETURN_TOKEN(TK_3WAYSCMP); + } + RETURN_TOKEN(TK_LE) + break; + case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break; + case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break; + case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break; + } + RETURN_TOKEN('<'); + case _SC('>'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);} + else if(CUR_CHAR == _SC('>')){ + NEXT(); + if(CUR_CHAR == _SC('>')){ + NEXT(); + RETURN_TOKEN(TK_USHIFTR); + } + RETURN_TOKEN(TK_SHIFTR); + } + else { RETURN_TOKEN('>') } + case _SC('!'): + NEXT(); + if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')} + else { NEXT(); RETURN_TOKEN(TK_NE); } + case _SC('@'): { + SQInteger stype; + NEXT(); + if(CUR_CHAR != _SC('"')) { + RETURN_TOKEN('@'); + } + if((stype=ReadString('"',true))!=-1) { + RETURN_TOKEN(stype); + } + Error(_SC("error parsing the string")); + } + case _SC('"'): + case _SC('\''): { + SQInteger stype; + if((stype=ReadString(CUR_CHAR,false))!=-1){ + RETURN_TOKEN(stype); + } + Error(_SC("error parsing the string")); + } + case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'): + case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'): + {SQInteger ret = CUR_CHAR; + NEXT(); RETURN_TOKEN(ret); } + case _SC('.'): + NEXT(); + if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') } + NEXT(); + if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); } + NEXT(); + RETURN_TOKEN(TK_VARPARAMS); + case _SC('&'): + NEXT(); + if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') } + else { NEXT(); RETURN_TOKEN(TK_AND); } + case _SC('|'): + NEXT(); + if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') } + else { NEXT(); RETURN_TOKEN(TK_OR); } + case _SC(':'): + NEXT(); + if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') } + else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); } + case _SC('*'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);} + else RETURN_TOKEN('*'); + case _SC('%'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);} + else RETURN_TOKEN('%'); + case _SC('-'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);} + else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);} + else RETURN_TOKEN('-'); + case _SC('+'): + NEXT(); + if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);} + else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);} + else RETURN_TOKEN('+'); + case SQUIRREL_EOB: + return 0; + default:{ + if (scisdigit(CUR_CHAR)) { + SQInteger ret = ReadNumber(); + RETURN_TOKEN(ret); + } + else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) { + SQInteger t = ReadID(); + RETURN_TOKEN(t); + } + else { + SQInteger c = CUR_CHAR; + if (sciscntrl((int)c)) Error(_SC("unexpected character(control)")); + NEXT(); + RETURN_TOKEN(c); + } + RETURN_TOKEN(0); + } + } + } + return 0; +} + +SQInteger SQLexer::GetIDType(SQChar *s) +{ + SQObjectPtr t; + if(_keywords->Get(SQString::Create(_sharedstate, s), t)) { + return SQInteger(_integer(t)); + } + return TK_IDENTIFIER; +} + + +SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim) +{ + INIT_TEMP_STRING(); + NEXT(); + if(IS_EOB()) return -1; + for(;;) { + while(CUR_CHAR != ndelim) { + switch(CUR_CHAR) { + case SQUIRREL_EOB: + Error(_SC("unfinished string")); + return -1; + case _SC('\n'): + if(!verbatim) Error(_SC("newline in a constant")); + APPEND_CHAR(CUR_CHAR); NEXT(); + _currentline++; + break; + case _SC('\\'): + if(verbatim) { + APPEND_CHAR('\\'); NEXT(); + } + else { + NEXT(); + switch(CUR_CHAR) { + case _SC('x'): NEXT(); { + if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); + const SQInteger maxdigits = 4; + SQChar temp[maxdigits+1]; + SQInteger n = 0; + while(isxdigit(CUR_CHAR) && n < maxdigits) { + temp[n] = CUR_CHAR; + n++; + NEXT(); + } + temp[n] = 0; + SQChar *sTemp; + APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16)); + } + break; + case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break; + case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break; + case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break; + case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break; + case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break; + case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break; + case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break; + case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break; + case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break; + case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break; + case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break; + default: + Error(_SC("unrecognised escaper char")); + break; + } + } + break; + default: + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + } + NEXT(); + if(verbatim && CUR_CHAR == '"') { //double quotation + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + else { + break; + } + } + TERMINATE_BUFFER(); + SQInteger len = _longstr.size()-1; + if(ndelim == _SC('\'')) { + if(len == 0) Error(_SC("empty constant")); + if(len > 1) Error(_SC("constant too long")); + _nvalue = _longstr[0]; + return TK_INTEGER; + } + _svalue = &_longstr[0]; + return TK_STRING_LITERAL; +} + +void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res) +{ + *res = 0; + while(*s != 0) + { + if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0'); + else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10); + else { assert(0); } + } +} + +void LexInteger(const SQChar *s,SQUnsignedInteger *res) +{ + *res = 0; + while(*s != 0) + { + *res = (*res)*10+((*s++)-'0'); + } +} + +SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); } + +void LexOctal(const SQChar *s,SQUnsignedInteger *res) +{ + *res = 0; + while(*s != 0) + { + if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0'); + else { assert(0); } + } +} + +SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; } + + +#define MAX_HEX_DIGITS (sizeof(SQInteger)*2) +SQInteger SQLexer::ReadNumber() +{ +#define TINT 1 +#define TFLOAT 2 +#define THEX 3 +#define TSCIENTIFIC 4 +#define TOCTAL 5 + SQInteger type = TINT, firstchar = CUR_CHAR; + SQChar *sTemp; + INIT_TEMP_STRING(); + NEXT(); + if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) { + if(scisodigit(CUR_CHAR)) { + type = TOCTAL; + while(scisodigit(CUR_CHAR)) { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number")); + } + else { + NEXT(); + type = THEX; + while(isxdigit(CUR_CHAR)) { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number")); + } + } + else { + APPEND_CHAR((int)firstchar); + while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) { + if(CUR_CHAR == _SC('.')) type = TFLOAT; + if(isexponent(CUR_CHAR)) { + if(type != TFLOAT) Error(_SC("invalid numeric format")); + type = TSCIENTIFIC; + APPEND_CHAR(CUR_CHAR); + NEXT(); + if(CUR_CHAR == '+' || CUR_CHAR == '-'){ + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected")); + } + + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + } + TERMINATE_BUFFER(); + switch(type) { + case TSCIENTIFIC: + case TFLOAT: + _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp); + return TK_FLOAT; + case TINT: + LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue); + return TK_INTEGER; + case THEX: + LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); + return TK_INTEGER; + case TOCTAL: + LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); + return TK_INTEGER; + } + return 0; +} + +SQInteger SQLexer::ReadID() +{ + SQInteger res; + INIT_TEMP_STRING(); + do { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_')); + TERMINATE_BUFFER(); + res = GetIDType(&_longstr[0]); + if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) { + _svalue = &_longstr[0]; + } + return res; +} diff --git a/squirrel_3_0_1_stable/squirrel/sqlexer.h b/squirrel_3_0_1_stable/squirrel/sqlexer.h index d3283c6f7..49fadd90a 100644 --- a/squirrel_3_0_1_stable/squirrel/sqlexer.h +++ b/squirrel_3_0_1_stable/squirrel/sqlexer.h @@ -1,47 +1,47 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQLEXER_H_
-#define _SQLEXER_H_
-
-#ifdef SQUNICODE
-typedef SQChar LexChar;
-#else
-typedef unsigned char LexChar;
-#endif
-
-struct SQLexer
-{
- SQLexer();
- ~SQLexer();
- void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
- void Error(const SQChar *err);
- SQInteger Lex();
- const SQChar *Tok2Str(SQInteger tok);
-private:
- SQInteger GetIDType(SQChar *s);
- SQInteger ReadString(SQInteger ndelim,bool verbatim);
- SQInteger ReadNumber();
- void LexBlockComment();
- void LexLineComment();
- SQInteger ReadID();
- void Next();
- SQInteger _curtoken;
- SQTable *_keywords;
- SQBool _reached_eof;
-public:
- SQInteger _prevtoken;
- SQInteger _currentline;
- SQInteger _lasttokenline;
- SQInteger _currentcolumn;
- const SQChar *_svalue;
- SQInteger _nvalue;
- SQFloat _fvalue;
- SQLEXREADFUNC _readf;
- SQUserPointer _up;
- LexChar _currdata;
- SQSharedState *_sharedstate;
- sqvector<SQChar> _longstr;
- CompilerErrorFunc _errfunc;
- void *_errtarget;
-};
-
-#endif
+/* see copyright notice in squirrel.h */ +#ifndef _SQLEXER_H_ +#define _SQLEXER_H_ + +#ifdef SQUNICODE +typedef SQChar LexChar; +#else +typedef unsigned char LexChar; +#endif + +struct SQLexer +{ + SQLexer(); + ~SQLexer(); + void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed); + void Error(const SQChar *err); + SQInteger Lex(); + const SQChar *Tok2Str(SQInteger tok); +private: + SQInteger GetIDType(SQChar *s); + SQInteger ReadString(SQInteger ndelim,bool verbatim); + SQInteger ReadNumber(); + void LexBlockComment(); + void LexLineComment(); + SQInteger ReadID(); + void Next(); + SQInteger _curtoken; + SQTable *_keywords; + SQBool _reached_eof; +public: + SQInteger _prevtoken; + SQInteger _currentline; + SQInteger _lasttokenline; + SQInteger _currentcolumn; + const SQChar *_svalue; + SQInteger _nvalue; + SQFloat _fvalue; + SQLEXREADFUNC _readf; + SQUserPointer _up; + LexChar _currdata; + SQSharedState *_sharedstate; + sqvector<SQChar> _longstr; + CompilerErrorFunc _errfunc; + void *_errtarget; +}; + +#endif diff --git a/squirrel_3_0_1_stable/squirrel/sqmem.cpp b/squirrel_3_0_1_stable/squirrel/sqmem.cpp index 520f7eb76..6faf8165a 100644 --- a/squirrel_3_0_1_stable/squirrel/sqmem.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqmem.cpp @@ -1,9 +1,9 @@ -/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); }
-
-void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); }
-
-void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); }
+/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); } + +void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); } + +void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); } diff --git a/squirrel_3_0_1_stable/squirrel/sqobject.cpp b/squirrel_3_0_1_stable/squirrel/sqobject.cpp index 418a6d656..e32cd72b9 100644 --- a/squirrel_3_0_1_stable/squirrel/sqobject.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqobject.cpp @@ -1,655 +1,655 @@ -/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqarray.h"
-#include "sqtable.h"
-#include "squserdata.h"
-#include "sqfuncproto.h"
-#include "sqclass.h"
-#include "sqclosure.h"
-
-
-const SQChar *IdType2Name(SQObjectType type)
-{
- switch(_RAW_TYPE(type))
- {
- case _RT_NULL:return _SC("null");
- case _RT_INTEGER:return _SC("integer");
- case _RT_FLOAT:return _SC("float");
- case _RT_BOOL:return _SC("bool");
- case _RT_STRING:return _SC("string");
- case _RT_TABLE:return _SC("table");
- case _RT_ARRAY:return _SC("array");
- case _RT_GENERATOR:return _SC("generator");
- case _RT_CLOSURE:
- case _RT_NATIVECLOSURE:
- return _SC("function");
- case _RT_USERDATA:
- case _RT_USERPOINTER:
- return _SC("userdata");
- case _RT_THREAD: return _SC("thread");
- case _RT_FUNCPROTO: return _SC("function");
- case _RT_CLASS: return _SC("class");
- case _RT_INSTANCE: return _SC("instance");
- case _RT_WEAKREF: return _SC("weakref");
- case _RT_OUTER: return _SC("outer");
- default:
- return NULL;
- }
-}
-
-const SQChar *GetTypeName(const SQObjectPtr &obj1)
-{
- return IdType2Name(type(obj1));
-}
-
-SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len)
-{
- SQString *str=ADD_STRING(ss,s,len);
- return str;
-}
-
-void SQString::Release()
-{
- REMOVE_STRING(_sharedstate,this);
-}
-
-SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
- SQInteger idx = (SQInteger)TranslateIndex(refpos);
- while(idx < _len){
- outkey = (SQInteger)idx;
- outval = SQInteger(_val[idx]);
- //return idx for the next iteration
- return ++idx;
- }
- //nothing to iterate anymore
- return -1;
-}
-
-SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx)
-{
- switch(type(idx)){
- case OT_NULL:
- return 0;
- case OT_INTEGER:
- return (SQUnsignedInteger)_integer(idx);
- default: assert(0); break;
- }
- return 0;
-}
-
-SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type)
-{
- if(!_weakref) {
- sq_new(_weakref,SQWeakRef);
- _weakref->_obj._type = type;
- _weakref->_obj._unVal.pRefCounted = this;
- }
- return _weakref;
-}
-
-SQRefCounted::~SQRefCounted()
-{
- if(_weakref) {
- _weakref->_obj._type = OT_NULL;
- _weakref->_obj._unVal.pRefCounted = NULL;
- }
-}
-
-void SQWeakRef::Release() {
- if(ISREFCOUNTED(_obj._type)) {
- _obj._unVal.pRefCounted->_weakref = NULL;
- }
- sq_delete(this,SQWeakRef);
-}
-
-bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) {
- if(_delegate) {
- return _delegate->Get((*_ss(v)->_metamethods)[mm],res);
- }
- return false;
-}
-
-bool SQDelegable::SetDelegate(SQTable *mt)
-{
- SQTable *temp = mt;
- if(temp == this) return false;
- while (temp) {
- if (temp->_delegate == this) return false; //cycle detected
- temp = temp->_delegate;
- }
- if (mt) __ObjAddRef(mt);
- __ObjRelease(_delegate);
- _delegate = mt;
- return true;
-}
-
-bool SQGenerator::Yield(SQVM *v,SQInteger target)
-{
- if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;}
- if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; }
- SQInteger size = v->_top-v->_stackbase;
-
- _stack.resize(size);
- SQObject _this = v->_stack[v->_stackbase];
- _stack._vals[0] = ISREFCOUNTED(type(_this)) ? SQObjectPtr(_refcounted(_this)->GetWeakRef(type(_this))) : _this;
- for(SQInteger n =1; n<target; n++) {
- _stack._vals[n] = v->_stack[v->_stackbase+n];
- }
- for(SQInteger j =0; j < size; j++)
- {
- v->_stack[v->_stackbase+j].Null();
- }
-
- _ci = *v->ci;
- _ci._generator=NULL;
- for(SQInteger i=0;i<_ci._etraps;i++) {
- _etraps.push_back(v->_etraps.top());
- v->_etraps.pop_back();
- }
- _state=eSuspended;
- return true;
-}
-
-bool SQGenerator::Resume(SQVM *v,SQObjectPtr &dest)
-{
- if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; }
- if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; }
- SQInteger size = _stack.size();
- SQInteger target = &dest - &(v->_stack._vals[v->_stackbase]);
- assert(target>=0 && target<=255);
- if(!v->EnterFrame(v->_top, v->_top + size, false))
- return false;
- v->ci->_generator = this;
- v->ci->_target = (SQInt32)target;
- v->ci->_closure = _ci._closure;
- v->ci->_ip = _ci._ip;
- v->ci->_literals = _ci._literals;
- v->ci->_ncalls = _ci._ncalls;
- v->ci->_etraps = _ci._etraps;
- v->ci->_root = _ci._root;
-
-
- for(SQInteger i=0;i<_ci._etraps;i++) {
- v->_etraps.push_back(_etraps.top());
- _etraps.pop_back();
- }
- SQObject _this = _stack._vals[0];
- v->_stack[v->_stackbase] = type(_this) == OT_WEAKREF ? _weakref(_this)->_obj : _this;
-
- for(SQInteger n = 1; n<size; n++) {
- v->_stack[v->_stackbase+n] = _stack._vals[n];
- _stack._vals[n].Null();
- }
-
- _state=eRunning;
- if (v->_debughook)
- v->CallDebugHook(_SC('c'));
-
- return true;
-}
-
-void SQArray::Extend(const SQArray *a){
- SQInteger xlen;
- if((xlen=a->Size()))
- for(SQInteger i=0;i<xlen;i++)
- Append(a->_values[i]);
-}
-
-const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)
-{
- SQUnsignedInteger nvars=_nlocalvarinfos;
- const SQChar *res=NULL;
- if(nvars>=nseq){
- for(SQUnsignedInteger i=0;i<nvars;i++){
- if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
- {
- if(nseq==0){
- vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]);
- res=_stringval(_localvarinfos[i]._name);
- break;
- }
- nseq--;
- }
- }
- }
- return res;
-}
-
-
-SQInteger SQFunctionProto::GetLine(SQInstruction *curr)
-{
- SQInteger op = (SQInteger)(curr-_instructions);
- SQInteger line=_lineinfos[0]._line;
- SQInteger low = 0;
- SQInteger high = _nlineinfos - 1;
- SQInteger mid = 0;
- while(low <= high)
- {
- mid = low + ((high - low) >> 1);
- SQInteger curop = _lineinfos[mid]._op;
- if(curop > op)
- {
- high = mid - 1;
- }
- else if(curop < op) {
- if(mid < (_nlineinfos - 1)
- && _lineinfos[mid + 1]._op >= op) {
- break;
- }
- low = mid + 1;
- }
- else { //equal
- break;
- }
- }
-
- line = _lineinfos[mid]._line;
- return line;
-}
-
-SQClosure::~SQClosure()
-{
- __ObjRelease(_env);
- __ObjRelease(_base);
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
-}
-
-#define _CHECK_IO(exp) { if(!exp)return false; }
-bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size)
-{
- if(write(up,dest,size) != size) {
- v->Raise_Error(_SC("io error (write function failure)"));
- return false;
- }
- return true;
-}
-
-bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size)
-{
- if(size && read(up,dest,size) != size) {
- v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
- return false;
- }
- return true;
-}
-
-bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger32 tag)
-{
- return SafeWrite(v,write,up,&tag,sizeof(tag));
-}
-
-bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUnsignedInteger32 tag)
-{
- SQUnsignedInteger32 t;
- _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
- if(t != tag){
- v->Raise_Error(_SC("invalid or corrupted closure stream"));
- return false;
- }
- return true;
-}
-
-bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)
-{
- SQUnsignedInteger32 _type = (SQUnsignedInteger32)type(o);
- _CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type)));
- switch(type(o)){
- case OT_STRING:
- _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));
- _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len)));
- break;
- case OT_INTEGER:
- _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break;
- case OT_FLOAT:
- _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break;
- case OT_NULL:
- break;
- default:
- v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o));
- return false;
- }
- return true;
-}
-
-bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
-{
- SQUnsignedInteger32 _type;
- _CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type)));
- SQObjectType t = (SQObjectType)_type;
- switch(t){
- case OT_STRING:{
- SQInteger len;
- _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));
- _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len)));
- o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);
- }
- break;
- case OT_INTEGER:{
- SQInteger i;
- _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break;
- }
- case OT_FLOAT:{
- SQFloat f;
- _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break;
- }
- case OT_NULL:
- o.Null();
- break;
- default:
- v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t));
- return false;
- }
- return true;
-}
-
-bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
-{
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));
- _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar)));
- _CHECK_IO(WriteTag(v,write,up,sizeof(SQInteger)));
- _CHECK_IO(WriteTag(v,write,up,sizeof(SQFloat)));
- _CHECK_IO(_function->Save(v,up,write));
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));
- return true;
-}
-
-bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret)
-{
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));
- _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar)));
- _CHECK_IO(CheckTag(v,read,up,sizeof(SQInteger)));
- _CHECK_IO(CheckTag(v,read,up,sizeof(SQFloat)));
- SQObjectPtr func;
- _CHECK_IO(SQFunctionProto::Load(v,up,read,func));
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));
- ret = SQClosure::Create(_ss(v),_funcproto(func));
- return true;
-}
-
-SQFunctionProto::SQFunctionProto(SQSharedState *ss)
-{
- _stacksize=0;
- _bgenerator=false;
- INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
-}
-
-SQFunctionProto::~SQFunctionProto()
-{
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
-}
-
-bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
-{
- SQInteger i,nliterals = _nliterals,nparameters = _nparameters;
- SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos;
- SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions;
- SQInteger ndefaultparams = _ndefaultparams;
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(WriteObject(v,up,write,_sourcename));
- _CHECK_IO(WriteObject(v,up,write,_name));
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals)));
- _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters)));
- _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues)));
- _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos)));
- _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos)));
- _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams)));
- _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions)));
- _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions)));
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nliterals;i++){
- _CHECK_IO(WriteObject(v,up,write,_literals[i]));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nparameters;i++){
- _CHECK_IO(WriteObject(v,up,write,_parameters[i]));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<noutervalues;i++){
- _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger)));
- _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));
- _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nlocalvarinfos;i++){
- SQLocalVarInfo &lvi=_localvarinfos[i];
- _CHECK_IO(WriteObject(v,up,write,lvi._name));
- _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger)));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos));
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeWrite(v,write,up,_defaultparams,sizeof(SQInteger)*ndefaultparams));
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions));
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nfunctions;i++){
- _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write));
- }
- _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));
- _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));
- _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));
- return true;
-}
-
-bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret)
-{
- SQInteger i, nliterals,nparameters;
- SQInteger noutervalues ,nlocalvarinfos ;
- SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ;
- SQObjectPtr sourcename, name;
- SQObjectPtr o;
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(ReadObject(v, up, read, sourcename));
- _CHECK_IO(ReadObject(v, up, read, name));
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals)));
- _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters)));
- _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues)));
- _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos)));
- _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos)));
- _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams)));
- _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions)));
- _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions)));
-
-
- SQFunctionProto *f = SQFunctionProto::Create(_opt_ss(v),ninstructions,nliterals,nparameters,
- nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams);
- SQObjectPtr proto = f; //gets a ref in case of failure
- f->_sourcename = sourcename;
- f->_name = name;
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0;i < nliterals; i++){
- _CHECK_IO(ReadObject(v, up, read, o));
- f->_literals[i] = o;
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0; i < nparameters; i++){
- _CHECK_IO(ReadObject(v, up, read, o));
- f->_parameters[i] = o;
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0; i < noutervalues; i++){
- SQUnsignedInteger type;
- SQObjectPtr name;
- _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger)));
- _CHECK_IO(ReadObject(v, up, read, o));
- _CHECK_IO(ReadObject(v, up, read, name));
- f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type);
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0; i < nlocalvarinfos; i++){
- SQLocalVarInfo lvi;
- _CHECK_IO(ReadObject(v, up, read, lvi._name));
- _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger)));
- f->_localvarinfos[i] = lvi;
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos));
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams));
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions));
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- for(i = 0; i < nfunctions; i++){
- _CHECK_IO(_funcproto(o)->Load(v, up, read, o));
- f->_functions[i] = o;
- }
- _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize)));
- _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator)));
- _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams)));
-
- ret = f;
- return true;
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-
-#define START_MARK() if(!(_uiRef&MARK_FLAG)){ \
- _uiRef|=MARK_FLAG;
-
-#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \
- AddToChain(chain, this); }
-
-void SQVM::Mark(SQCollectable **chain)
-{
- START_MARK()
- SQSharedState::MarkObject(_lasterror,chain);
- SQSharedState::MarkObject(_errorhandler,chain);
- SQSharedState::MarkObject(_debughook_closure,chain);
- SQSharedState::MarkObject(_roottable, chain);
- SQSharedState::MarkObject(temp_reg, chain);
- for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
- for(SQInteger k = 0; k < _callsstacksize; k++) SQSharedState::MarkObject(_callsstack[k]._closure, chain);
- END_MARK()
-}
-
-void SQArray::Mark(SQCollectable **chain)
-{
- START_MARK()
- SQInteger len = _values.size();
- for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain);
- END_MARK()
-}
-void SQTable::Mark(SQCollectable **chain)
-{
- START_MARK()
- if(_delegate) _delegate->Mark(chain);
- SQInteger len = _numofnodes;
- for(SQInteger i = 0; i < len; i++){
- SQSharedState::MarkObject(_nodes[i].key, chain);
- SQSharedState::MarkObject(_nodes[i].val, chain);
- }
- END_MARK()
-}
-
-void SQClass::Mark(SQCollectable **chain)
-{
- START_MARK()
- _members->Mark(chain);
- if(_base) _base->Mark(chain);
- SQSharedState::MarkObject(_attributes, chain);
- for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) {
- SQSharedState::MarkObject(_defaultvalues[i].val, chain);
- SQSharedState::MarkObject(_defaultvalues[i].attrs, chain);
- }
- for(SQUnsignedInteger j =0; j< _methods.size(); j++) {
- SQSharedState::MarkObject(_methods[j].val, chain);
- SQSharedState::MarkObject(_methods[j].attrs, chain);
- }
- for(SQUnsignedInteger k =0; k< MT_LAST; k++) {
- SQSharedState::MarkObject(_metamethods[k], chain);
- }
- END_MARK()
-}
-
-void SQInstance::Mark(SQCollectable **chain)
-{
- START_MARK()
- _class->Mark(chain);
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- for(SQUnsignedInteger i =0; i< nvalues; i++) {
- SQSharedState::MarkObject(_values[i], chain);
- }
- END_MARK()
-}
-
-void SQGenerator::Mark(SQCollectable **chain)
-{
- START_MARK()
- for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
- SQSharedState::MarkObject(_closure, chain);
- END_MARK()
-}
-
-void SQFunctionProto::Mark(SQCollectable **chain)
-{
- START_MARK()
- for(SQInteger i = 0; i < _nliterals; i++) SQSharedState::MarkObject(_literals[i], chain);
- for(SQInteger k = 0; k < _nfunctions; k++) SQSharedState::MarkObject(_functions[k], chain);
- END_MARK()
-}
-
-void SQClosure::Mark(SQCollectable **chain)
-{
- START_MARK()
- if(_base) _base->Mark(chain);
- SQFunctionProto *fp = _function;
- fp->Mark(chain);
- for(SQInteger i = 0; i < fp->_noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain);
- for(SQInteger k = 0; k < fp->_ndefaultparams; k++) SQSharedState::MarkObject(_defaultparams[k], chain);
- END_MARK()
-}
-
-void SQNativeClosure::Mark(SQCollectable **chain)
-{
- START_MARK()
- for(SQUnsignedInteger i = 0; i < _noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain);
- END_MARK()
-}
-
-void SQOuter::Mark(SQCollectable **chain)
-{
- START_MARK()
- /* If the valptr points to a closed value, that value is alive */
- if(_valptr == &_value) {
- SQSharedState::MarkObject(_value, chain);
- }
- END_MARK()
-}
-
-void SQUserData::Mark(SQCollectable **chain){
- START_MARK()
- if(_delegate) _delegate->Mark(chain);
- END_MARK()
-}
-
-void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; }
-
-#endif
-
+/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqstring.h" +#include "sqarray.h" +#include "sqtable.h" +#include "squserdata.h" +#include "sqfuncproto.h" +#include "sqclass.h" +#include "sqclosure.h" + + +const SQChar *IdType2Name(SQObjectType type) +{ + switch(_RAW_TYPE(type)) + { + case _RT_NULL:return _SC("null"); + case _RT_INTEGER:return _SC("integer"); + case _RT_FLOAT:return _SC("float"); + case _RT_BOOL:return _SC("bool"); + case _RT_STRING:return _SC("string"); + case _RT_TABLE:return _SC("table"); + case _RT_ARRAY:return _SC("array"); + case _RT_GENERATOR:return _SC("generator"); + case _RT_CLOSURE: + case _RT_NATIVECLOSURE: + return _SC("function"); + case _RT_USERDATA: + case _RT_USERPOINTER: + return _SC("userdata"); + case _RT_THREAD: return _SC("thread"); + case _RT_FUNCPROTO: return _SC("function"); + case _RT_CLASS: return _SC("class"); + case _RT_INSTANCE: return _SC("instance"); + case _RT_WEAKREF: return _SC("weakref"); + case _RT_OUTER: return _SC("outer"); + default: + return NULL; + } +} + +const SQChar *GetTypeName(const SQObjectPtr &obj1) +{ + return IdType2Name(type(obj1)); +} + +SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len) +{ + SQString *str=ADD_STRING(ss,s,len); + return str; +} + +void SQString::Release() +{ + REMOVE_STRING(_sharedstate,this); +} + +SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) +{ + SQInteger idx = (SQInteger)TranslateIndex(refpos); + while(idx < _len){ + outkey = (SQInteger)idx; + outval = SQInteger(_val[idx]); + //return idx for the next iteration + return ++idx; + } + //nothing to iterate anymore + return -1; +} + +SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx) +{ + switch(type(idx)){ + case OT_NULL: + return 0; + case OT_INTEGER: + return (SQUnsignedInteger)_integer(idx); + default: assert(0); break; + } + return 0; +} + +SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type) +{ + if(!_weakref) { + sq_new(_weakref,SQWeakRef); + _weakref->_obj._type = type; + _weakref->_obj._unVal.pRefCounted = this; + } + return _weakref; +} + +SQRefCounted::~SQRefCounted() +{ + if(_weakref) { + _weakref->_obj._type = OT_NULL; + _weakref->_obj._unVal.pRefCounted = NULL; + } +} + +void SQWeakRef::Release() { + if(ISREFCOUNTED(_obj._type)) { + _obj._unVal.pRefCounted->_weakref = NULL; + } + sq_delete(this,SQWeakRef); +} + +bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) { + if(_delegate) { + return _delegate->Get((*_ss(v)->_metamethods)[mm],res); + } + return false; +} + +bool SQDelegable::SetDelegate(SQTable *mt) +{ + SQTable *temp = mt; + if(temp == this) return false; + while (temp) { + if (temp->_delegate == this) return false; //cycle detected + temp = temp->_delegate; + } + if (mt) __ObjAddRef(mt); + __ObjRelease(_delegate); + _delegate = mt; + return true; +} + +bool SQGenerator::Yield(SQVM *v,SQInteger target) +{ + if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;} + if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; } + SQInteger size = v->_top-v->_stackbase; + + _stack.resize(size); + SQObject _this = v->_stack[v->_stackbase]; + _stack._vals[0] = ISREFCOUNTED(type(_this)) ? SQObjectPtr(_refcounted(_this)->GetWeakRef(type(_this))) : _this; + for(SQInteger n =1; n<target; n++) { + _stack._vals[n] = v->_stack[v->_stackbase+n]; + } + for(SQInteger j =0; j < size; j++) + { + v->_stack[v->_stackbase+j].Null(); + } + + _ci = *v->ci; + _ci._generator=NULL; + for(SQInteger i=0;i<_ci._etraps;i++) { + _etraps.push_back(v->_etraps.top()); + v->_etraps.pop_back(); + } + _state=eSuspended; + return true; +} + +bool SQGenerator::Resume(SQVM *v,SQObjectPtr &dest) +{ + if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; } + if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; } + SQInteger size = _stack.size(); + SQInteger target = &dest - &(v->_stack._vals[v->_stackbase]); + assert(target>=0 && target<=255); + if(!v->EnterFrame(v->_top, v->_top + size, false)) + return false; + v->ci->_generator = this; + v->ci->_target = (SQInt32)target; + v->ci->_closure = _ci._closure; + v->ci->_ip = _ci._ip; + v->ci->_literals = _ci._literals; + v->ci->_ncalls = _ci._ncalls; + v->ci->_etraps = _ci._etraps; + v->ci->_root = _ci._root; + + + for(SQInteger i=0;i<_ci._etraps;i++) { + v->_etraps.push_back(_etraps.top()); + _etraps.pop_back(); + } + SQObject _this = _stack._vals[0]; + v->_stack[v->_stackbase] = type(_this) == OT_WEAKREF ? _weakref(_this)->_obj : _this; + + for(SQInteger n = 1; n<size; n++) { + v->_stack[v->_stackbase+n] = _stack._vals[n]; + _stack._vals[n].Null(); + } + + _state=eRunning; + if (v->_debughook) + v->CallDebugHook(_SC('c')); + + return true; +} + +void SQArray::Extend(const SQArray *a){ + SQInteger xlen; + if((xlen=a->Size())) + for(SQInteger i=0;i<xlen;i++) + Append(a->_values[i]); +} + +const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop) +{ + SQUnsignedInteger nvars=_nlocalvarinfos; + const SQChar *res=NULL; + if(nvars>=nseq){ + for(SQUnsignedInteger i=0;i<nvars;i++){ + if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop) + { + if(nseq==0){ + vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]); + res=_stringval(_localvarinfos[i]._name); + break; + } + nseq--; + } + } + } + return res; +} + + +SQInteger SQFunctionProto::GetLine(SQInstruction *curr) +{ + SQInteger op = (SQInteger)(curr-_instructions); + SQInteger line=_lineinfos[0]._line; + SQInteger low = 0; + SQInteger high = _nlineinfos - 1; + SQInteger mid = 0; + while(low <= high) + { + mid = low + ((high - low) >> 1); + SQInteger curop = _lineinfos[mid]._op; + if(curop > op) + { + high = mid - 1; + } + else if(curop < op) { + if(mid < (_nlineinfos - 1) + && _lineinfos[mid + 1]._op >= op) { + break; + } + low = mid + 1; + } + else { //equal + break; + } + } + + line = _lineinfos[mid]._line; + return line; +} + +SQClosure::~SQClosure() +{ + __ObjRelease(_env); + __ObjRelease(_base); + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); +} + +#define _CHECK_IO(exp) { if(!exp)return false; } +bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size) +{ + if(write(up,dest,size) != size) { + v->Raise_Error(_SC("io error (write function failure)")); + return false; + } + return true; +} + +bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size) +{ + if(size && read(up,dest,size) != size) { + v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated")); + return false; + } + return true; +} + +bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger32 tag) +{ + return SafeWrite(v,write,up,&tag,sizeof(tag)); +} + +bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUnsignedInteger32 tag) +{ + SQUnsignedInteger32 t; + _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t))); + if(t != tag){ + v->Raise_Error(_SC("invalid or corrupted closure stream")); + return false; + } + return true; +} + +bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o) +{ + SQUnsignedInteger32 _type = (SQUnsignedInteger32)type(o); + _CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type))); + switch(type(o)){ + case OT_STRING: + _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger))); + _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len))); + break; + case OT_INTEGER: + _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break; + case OT_FLOAT: + _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break; + case OT_NULL: + break; + default: + v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o)); + return false; + } + return true; +} + +bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o) +{ + SQUnsignedInteger32 _type; + _CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type))); + SQObjectType t = (SQObjectType)_type; + switch(t){ + case OT_STRING:{ + SQInteger len; + _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger))); + _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len))); + o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len); + } + break; + case OT_INTEGER:{ + SQInteger i; + _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break; + } + case OT_FLOAT:{ + SQFloat f; + _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break; + } + case OT_NULL: + o.Null(); + break; + default: + v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t)); + return false; + } + return true; +} + +bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) +{ + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD)); + _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar))); + _CHECK_IO(WriteTag(v,write,up,sizeof(SQInteger))); + _CHECK_IO(WriteTag(v,write,up,sizeof(SQFloat))); + _CHECK_IO(_function->Save(v,up,write)); + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL)); + return true; +} + +bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) +{ + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD)); + _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar))); + _CHECK_IO(CheckTag(v,read,up,sizeof(SQInteger))); + _CHECK_IO(CheckTag(v,read,up,sizeof(SQFloat))); + SQObjectPtr func; + _CHECK_IO(SQFunctionProto::Load(v,up,read,func)); + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL)); + ret = SQClosure::Create(_ss(v),_funcproto(func)); + return true; +} + +SQFunctionProto::SQFunctionProto(SQSharedState *ss) +{ + _stacksize=0; + _bgenerator=false; + INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); +} + +SQFunctionProto::~SQFunctionProto() +{ + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); +} + +bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) +{ + SQInteger i,nliterals = _nliterals,nparameters = _nparameters; + SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos; + SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions; + SQInteger ndefaultparams = _ndefaultparams; + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(WriteObject(v,up,write,_sourcename)); + _CHECK_IO(WriteObject(v,up,write,_name)); + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals))); + _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters))); + _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues))); + _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos))); + _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos))); + _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams))); + _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions))); + _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions))); + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + for(i=0;i<nliterals;i++){ + _CHECK_IO(WriteObject(v,up,write,_literals[i])); + } + + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + for(i=0;i<nparameters;i++){ + _CHECK_IO(WriteObject(v,up,write,_parameters[i])); + } + + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + for(i=0;i<noutervalues;i++){ + _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger))); + _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src)); + _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name)); + } + + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + for(i=0;i<nlocalvarinfos;i++){ + SQLocalVarInfo &lvi=_localvarinfos[i]; + _CHECK_IO(WriteObject(v,up,write,lvi._name)); + _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger))); + _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger))); + _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger))); + } + + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos)); + + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeWrite(v,write,up,_defaultparams,sizeof(SQInteger)*ndefaultparams)); + + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions)); + + _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); + for(i=0;i<nfunctions;i++){ + _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write)); + } + _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize))); + _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator))); + _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams))); + return true; +} + +bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) +{ + SQInteger i, nliterals,nparameters; + SQInteger noutervalues ,nlocalvarinfos ; + SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ; + SQObjectPtr sourcename, name; + SQObjectPtr o; + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(ReadObject(v, up, read, sourcename)); + _CHECK_IO(ReadObject(v, up, read, name)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals))); + _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters))); + _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues))); + _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos))); + _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos))); + _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams))); + _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions))); + _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions))); + + + SQFunctionProto *f = SQFunctionProto::Create(_opt_ss(v),ninstructions,nliterals,nparameters, + nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams); + SQObjectPtr proto = f; //gets a ref in case of failure + f->_sourcename = sourcename; + f->_name = name; + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0;i < nliterals; i++){ + _CHECK_IO(ReadObject(v, up, read, o)); + f->_literals[i] = o; + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0; i < nparameters; i++){ + _CHECK_IO(ReadObject(v, up, read, o)); + f->_parameters[i] = o; + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0; i < noutervalues; i++){ + SQUnsignedInteger type; + SQObjectPtr name; + _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger))); + _CHECK_IO(ReadObject(v, up, read, o)); + _CHECK_IO(ReadObject(v, up, read, name)); + f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type); + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + + for(i = 0; i < nlocalvarinfos; i++){ + SQLocalVarInfo lvi; + _CHECK_IO(ReadObject(v, up, read, lvi._name)); + _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger))); + _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger))); + _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger))); + f->_localvarinfos[i] = lvi; + } + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions)); + + _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); + for(i = 0; i < nfunctions; i++){ + _CHECK_IO(_funcproto(o)->Load(v, up, read, o)); + f->_functions[i] = o; + } + _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize))); + _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator))); + _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams))); + + ret = f; + return true; +} + +#ifndef NO_GARBAGE_COLLECTOR + +#define START_MARK() if(!(_uiRef&MARK_FLAG)){ \ + _uiRef|=MARK_FLAG; + +#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \ + AddToChain(chain, this); } + +void SQVM::Mark(SQCollectable **chain) +{ + START_MARK() + SQSharedState::MarkObject(_lasterror,chain); + SQSharedState::MarkObject(_errorhandler,chain); + SQSharedState::MarkObject(_debughook_closure,chain); + SQSharedState::MarkObject(_roottable, chain); + SQSharedState::MarkObject(temp_reg, chain); + for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); + for(SQInteger k = 0; k < _callsstacksize; k++) SQSharedState::MarkObject(_callsstack[k]._closure, chain); + END_MARK() +} + +void SQArray::Mark(SQCollectable **chain) +{ + START_MARK() + SQInteger len = _values.size(); + for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain); + END_MARK() +} +void SQTable::Mark(SQCollectable **chain) +{ + START_MARK() + if(_delegate) _delegate->Mark(chain); + SQInteger len = _numofnodes; + for(SQInteger i = 0; i < len; i++){ + SQSharedState::MarkObject(_nodes[i].key, chain); + SQSharedState::MarkObject(_nodes[i].val, chain); + } + END_MARK() +} + +void SQClass::Mark(SQCollectable **chain) +{ + START_MARK() + _members->Mark(chain); + if(_base) _base->Mark(chain); + SQSharedState::MarkObject(_attributes, chain); + for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) { + SQSharedState::MarkObject(_defaultvalues[i].val, chain); + SQSharedState::MarkObject(_defaultvalues[i].attrs, chain); + } + for(SQUnsignedInteger j =0; j< _methods.size(); j++) { + SQSharedState::MarkObject(_methods[j].val, chain); + SQSharedState::MarkObject(_methods[j].attrs, chain); + } + for(SQUnsignedInteger k =0; k< MT_LAST; k++) { + SQSharedState::MarkObject(_metamethods[k], chain); + } + END_MARK() +} + +void SQInstance::Mark(SQCollectable **chain) +{ + START_MARK() + _class->Mark(chain); + SQUnsignedInteger nvalues = _class->_defaultvalues.size(); + for(SQUnsignedInteger i =0; i< nvalues; i++) { + SQSharedState::MarkObject(_values[i], chain); + } + END_MARK() +} + +void SQGenerator::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); + SQSharedState::MarkObject(_closure, chain); + END_MARK() +} + +void SQFunctionProto::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQInteger i = 0; i < _nliterals; i++) SQSharedState::MarkObject(_literals[i], chain); + for(SQInteger k = 0; k < _nfunctions; k++) SQSharedState::MarkObject(_functions[k], chain); + END_MARK() +} + +void SQClosure::Mark(SQCollectable **chain) +{ + START_MARK() + if(_base) _base->Mark(chain); + SQFunctionProto *fp = _function; + fp->Mark(chain); + for(SQInteger i = 0; i < fp->_noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); + for(SQInteger k = 0; k < fp->_ndefaultparams; k++) SQSharedState::MarkObject(_defaultparams[k], chain); + END_MARK() +} + +void SQNativeClosure::Mark(SQCollectable **chain) +{ + START_MARK() + for(SQUnsignedInteger i = 0; i < _noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); + END_MARK() +} + +void SQOuter::Mark(SQCollectable **chain) +{ + START_MARK() + /* If the valptr points to a closed value, that value is alive */ + if(_valptr == &_value) { + SQSharedState::MarkObject(_value, chain); + } + END_MARK() +} + +void SQUserData::Mark(SQCollectable **chain){ + START_MARK() + if(_delegate) _delegate->Mark(chain); + END_MARK() +} + +void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; } + +#endif + diff --git a/squirrel_3_0_1_stable/squirrel/sqobject.h b/squirrel_3_0_1_stable/squirrel/sqobject.h index a7d1e1ed3..2b85e24c3 100644 --- a/squirrel_3_0_1_stable/squirrel/sqobject.h +++ b/squirrel_3_0_1_stable/squirrel/sqobject.h @@ -1,354 +1,354 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQOBJECT_H_
-#define _SQOBJECT_H_
-
-#include "squtils.h"
-
-#ifdef _SQ64
-#define UINT_MINUS_ONE (0xFFFFFFFFFFFFFFFF)
-#else
-#define UINT_MINUS_ONE (0xFFFFFFFF)
-#endif
-
-#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
-#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
-#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
-
-struct SQSharedState;
-
-enum SQMetaMethod{
- MT_ADD=0,
- MT_SUB=1,
- MT_MUL=2,
- MT_DIV=3,
- MT_UNM=4,
- MT_MODULO=5,
- MT_SET=6,
- MT_GET=7,
- MT_TYPEOF=8,
- MT_NEXTI=9,
- MT_CMP=10,
- MT_CALL=11,
- MT_CLONED=12,
- MT_NEWSLOT=13,
- MT_DELSLOT=14,
- MT_TOSTRING=15,
- MT_NEWMEMBER=16,
- MT_INHERITED=17,
- MT_LAST = 18
-};
-
-#define MM_ADD _SC("_add")
-#define MM_SUB _SC("_sub")
-#define MM_MUL _SC("_mul")
-#define MM_DIV _SC("_div")
-#define MM_UNM _SC("_unm")
-#define MM_MODULO _SC("_modulo")
-#define MM_SET _SC("_set")
-#define MM_GET _SC("_get")
-#define MM_TYPEOF _SC("_typeof")
-#define MM_NEXTI _SC("_nexti")
-#define MM_CMP _SC("_cmp")
-#define MM_CALL _SC("_call")
-#define MM_CLONED _SC("_cloned")
-#define MM_NEWSLOT _SC("_newslot")
-#define MM_DELSLOT _SC("_delslot")
-#define MM_TOSTRING _SC("_tostring")
-#define MM_NEWMEMBER _SC("_newmember")
-#define MM_INHERITED _SC("_inherited")
-
-
-#define _CONSTRUCT_VECTOR(type,size,ptr) { \
- for(SQInteger n = 0; n < ((SQInteger)size); n++) { \
- new (&ptr[n]) type(); \
- } \
-}
-
-#define _DESTRUCT_VECTOR(type,size,ptr) { \
- for(SQInteger nl = 0; nl < ((SQInteger)size); nl++) { \
- ptr[nl].~type(); \
- } \
-}
-
-#define _COPY_VECTOR(dest,src,size) { \
- for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \
- dest[_n_] = src[_n_]; \
- } \
-}
-
-#define _NULL_SQOBJECT_VECTOR(vec,size) { \
- for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \
- vec[_n_].Null(); \
- } \
-}
-
-#define MINPOWER2 4
-
-struct SQRefCounted
-{
- SQUnsignedInteger _uiRef;
- struct SQWeakRef *_weakref;
- SQRefCounted() { _uiRef = 0; _weakref = NULL; }
- virtual ~SQRefCounted();
- SQWeakRef *GetWeakRef(SQObjectType type);
- virtual void Release()=0;
-
-};
-
-struct SQWeakRef : SQRefCounted
-{
- void Release();
- SQObject _obj;
-};
-
-#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj)
-
-struct SQObjectPtr;
-
-#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \
- { \
- unval.pRefCounted->_uiRef++; \
- }
-
-#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)==0)) \
- { \
- unval.pRefCounted->Release(); \
- }
-
-#define __ObjRelease(obj) { \
- if((obj)) { \
- (obj)->_uiRef--; \
- if((obj)->_uiRef == 0) \
- (obj)->Release(); \
- (obj) = NULL; \
- } \
-}
-
-#define __ObjAddRef(obj) { \
- (obj)->_uiRef++; \
-}
-
-#define type(obj) ((obj)._type)
-#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)
-#define raw_type(obj) _RAW_TYPE((obj)._type)
-
-#define _integer(obj) ((obj)._unVal.nInteger)
-#define _float(obj) ((obj)._unVal.fFloat)
-#define _string(obj) ((obj)._unVal.pString)
-#define _table(obj) ((obj)._unVal.pTable)
-#define _array(obj) ((obj)._unVal.pArray)
-#define _closure(obj) ((obj)._unVal.pClosure)
-#define _generator(obj) ((obj)._unVal.pGenerator)
-#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
-#define _userdata(obj) ((obj)._unVal.pUserData)
-#define _userpointer(obj) ((obj)._unVal.pUserPointer)
-#define _thread(obj) ((obj)._unVal.pThread)
-#define _funcproto(obj) ((obj)._unVal.pFunctionProto)
-#define _class(obj) ((obj)._unVal.pClass)
-#define _instance(obj) ((obj)._unVal.pInstance)
-#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
-#define _weakref(obj) ((obj)._unVal.pWeakRef)
-#define _outer(obj) ((obj)._unVal.pOuter)
-#define _refcounted(obj) ((obj)._unVal.pRefCounted)
-#define _rawval(obj) ((obj)._unVal.raw)
-
-#define _stringval(obj) (obj)._unVal.pString->_val
-#define _userdataval(obj) ((SQUserPointer)sq_aligning((obj)._unVal.pUserData + 1))
-
-#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))
-#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))
-/////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////
-#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64)
-#define SQ_REFOBJECT_INIT() SQ_OBJECT_RAWINIT()
-#else
-#define SQ_REFOBJECT_INIT()
-#endif
-
-#define _REF_TYPE_DECL(type,_class,sym) \
- SQObjectPtr(_class * x) \
- { \
- SQ_OBJECT_RAWINIT() \
- _type=type; \
- _unVal.sym = x; \
- assert(_unVal.pTable); \
- _unVal.pRefCounted->_uiRef++; \
- } \
- inline SQObjectPtr& operator=(_class *x) \
- { \
- SQObjectType tOldType; \
- SQObjectValue unOldVal; \
- tOldType=_type; \
- unOldVal=_unVal; \
- _type = type; \
- SQ_REFOBJECT_INIT() \
- _unVal.sym = x; \
- _unVal.pRefCounted->_uiRef++; \
- __Release(tOldType,unOldVal); \
- return *this; \
- }
-
-#define _SCALAR_TYPE_DECL(type,_class,sym) \
- SQObjectPtr(_class x) \
- { \
- SQ_OBJECT_RAWINIT() \
- _type=type; \
- _unVal.sym = x; \
- } \
- inline SQObjectPtr& operator=(_class x) \
- { \
- __Release(_type,_unVal); \
- _type = type; \
- SQ_OBJECT_RAWINIT() \
- _unVal.sym = x; \
- return *this; \
- }
-struct SQObjectPtr : public SQObject
-{
- SQObjectPtr()
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_NULL;
- _unVal.pUserPointer=NULL;
- }
- SQObjectPtr(const SQObjectPtr &o)
- {
- //SQ_OBJECT_RAWINIT()
- _type=o._type;
- _unVal=o._unVal;
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(const SQObject &o)
- {
- //SQ_OBJECT_RAWINIT()
- _type=o._type;
- _unVal=o._unVal;
- __AddRef(_type,_unVal);
- }
- _REF_TYPE_DECL(OT_TABLE,SQTable,pTable)
- _REF_TYPE_DECL(OT_CLASS,SQClass,pClass)
- _REF_TYPE_DECL(OT_INSTANCE,SQInstance,pInstance)
- _REF_TYPE_DECL(OT_ARRAY,SQArray,pArray)
- _REF_TYPE_DECL(OT_CLOSURE,SQClosure,pClosure)
- _REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,pNativeClosure)
- _REF_TYPE_DECL(OT_OUTER,SQOuter,pOuter)
- _REF_TYPE_DECL(OT_GENERATOR,SQGenerator,pGenerator)
- _REF_TYPE_DECL(OT_STRING,SQString,pString)
- _REF_TYPE_DECL(OT_USERDATA,SQUserData,pUserData)
- _REF_TYPE_DECL(OT_WEAKREF,SQWeakRef,pWeakRef)
- _REF_TYPE_DECL(OT_THREAD,SQVM,pThread)
- _REF_TYPE_DECL(OT_FUNCPROTO,SQFunctionProto,pFunctionProto)
-
- _SCALAR_TYPE_DECL(OT_INTEGER,SQInteger,nInteger)
- _SCALAR_TYPE_DECL(OT_FLOAT,SQFloat,fFloat)
- _SCALAR_TYPE_DECL(OT_USERPOINTER,SQUserPointer,pUserPointer)
-
- SQObjectPtr(bool bBool)
- {
- SQ_OBJECT_RAWINIT()
- _type = OT_BOOL;
- _unVal.nInteger = bBool?1:0;
- }
- inline SQObjectPtr& operator=(bool b)
- {
- __Release(_type,_unVal);
- SQ_OBJECT_RAWINIT()
- _type = OT_BOOL;
- _unVal.nInteger = b?1:0;
- return *this;
- }
-
- ~SQObjectPtr()
- {
- __Release(_type,_unVal);
- }
-
- inline SQObjectPtr& operator=(const SQObjectPtr& obj)
- {
- SQObjectType tOldType;
- SQObjectValue unOldVal;
- tOldType=_type;
- unOldVal=_unVal;
- _unVal = obj._unVal;
- _type = obj._type;
- __AddRef(_type,_unVal);
- __Release(tOldType,unOldVal);
- return *this;
- }
- inline SQObjectPtr& operator=(const SQObject& obj)
- {
- SQObjectType tOldType;
- SQObjectValue unOldVal;
- tOldType=_type;
- unOldVal=_unVal;
- _unVal = obj._unVal;
- _type = obj._type;
- __AddRef(_type,_unVal);
- __Release(tOldType,unOldVal);
- return *this;
- }
- inline void Null()
- {
- __Release(_type ,_unVal);
- _type = OT_NULL;
- _unVal.raw = NULL;
- }
- private:
- SQObjectPtr(const SQChar *){} //safety
-};
-
-
-inline void _Swap(SQObject &a,SQObject &b)
-{
- SQObjectType tOldType = a._type;
- SQObjectValue unOldVal = a._unVal;
- a._type = b._type;
- a._unVal = b._unVal;
- b._type = tOldType;
- b._unVal = unOldVal;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////
-#ifndef NO_GARBAGE_COLLECTOR
-#define MARK_FLAG 0x80000000
-struct SQCollectable : public SQRefCounted {
- SQCollectable *_next;
- SQCollectable *_prev;
- SQSharedState *_sharedstate;
- virtual SQObjectType GetType()=0;
- virtual void Release()=0;
- virtual void Mark(SQCollectable **chain)=0;
- void UnMark();
- virtual void Finalize()=0;
- static void AddToChain(SQCollectable **chain,SQCollectable *c);
- static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
-};
-
-
-#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
-#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
-#define CHAINABLE_OBJ SQCollectable
-#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
-#else
-
-#define ADD_TO_CHAIN(chain,obj) ((void)0)
-#define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
-#define CHAINABLE_OBJ SQRefCounted
-#define INIT_CHAIN() ((void)0)
-#endif
-
-struct SQDelegable : public CHAINABLE_OBJ {
- bool SetDelegate(SQTable *m);
- virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
- SQTable *_delegate;
-};
-
-SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);
-typedef sqvector<SQObjectPtr> SQObjectPtrVec;
-typedef sqvector<SQInteger> SQIntVec;
-const SQChar *GetTypeName(const SQObjectPtr &obj1);
-const SQChar *IdType2Name(SQObjectType type);
-
-
-
-#endif //_SQOBJECT_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQOBJECT_H_ +#define _SQOBJECT_H_ + +#include "squtils.h" + +#ifdef _SQ64 +#define UINT_MINUS_ONE (0xFFFFFFFFFFFFFFFF) +#else +#define UINT_MINUS_ONE (0xFFFFFFFF) +#endif + +#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R')) +#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T')) +#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L')) + +struct SQSharedState; + +enum SQMetaMethod{ + MT_ADD=0, + MT_SUB=1, + MT_MUL=2, + MT_DIV=3, + MT_UNM=4, + MT_MODULO=5, + MT_SET=6, + MT_GET=7, + MT_TYPEOF=8, + MT_NEXTI=9, + MT_CMP=10, + MT_CALL=11, + MT_CLONED=12, + MT_NEWSLOT=13, + MT_DELSLOT=14, + MT_TOSTRING=15, + MT_NEWMEMBER=16, + MT_INHERITED=17, + MT_LAST = 18 +}; + +#define MM_ADD _SC("_add") +#define MM_SUB _SC("_sub") +#define MM_MUL _SC("_mul") +#define MM_DIV _SC("_div") +#define MM_UNM _SC("_unm") +#define MM_MODULO _SC("_modulo") +#define MM_SET _SC("_set") +#define MM_GET _SC("_get") +#define MM_TYPEOF _SC("_typeof") +#define MM_NEXTI _SC("_nexti") +#define MM_CMP _SC("_cmp") +#define MM_CALL _SC("_call") +#define MM_CLONED _SC("_cloned") +#define MM_NEWSLOT _SC("_newslot") +#define MM_DELSLOT _SC("_delslot") +#define MM_TOSTRING _SC("_tostring") +#define MM_NEWMEMBER _SC("_newmember") +#define MM_INHERITED _SC("_inherited") + + +#define _CONSTRUCT_VECTOR(type,size,ptr) { \ + for(SQInteger n = 0; n < ((SQInteger)size); n++) { \ + new (&ptr[n]) type(); \ + } \ +} + +#define _DESTRUCT_VECTOR(type,size,ptr) { \ + for(SQInteger nl = 0; nl < ((SQInteger)size); nl++) { \ + ptr[nl].~type(); \ + } \ +} + +#define _COPY_VECTOR(dest,src,size) { \ + for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \ + dest[_n_] = src[_n_]; \ + } \ +} + +#define _NULL_SQOBJECT_VECTOR(vec,size) { \ + for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \ + vec[_n_].Null(); \ + } \ +} + +#define MINPOWER2 4 + +struct SQRefCounted +{ + SQUnsignedInteger _uiRef; + struct SQWeakRef *_weakref; + SQRefCounted() { _uiRef = 0; _weakref = NULL; } + virtual ~SQRefCounted(); + SQWeakRef *GetWeakRef(SQObjectType type); + virtual void Release()=0; + +}; + +struct SQWeakRef : SQRefCounted +{ + void Release(); + SQObject _obj; +}; + +#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj) + +struct SQObjectPtr; + +#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \ + { \ + unval.pRefCounted->_uiRef++; \ + } + +#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)==0)) \ + { \ + unval.pRefCounted->Release(); \ + } + +#define __ObjRelease(obj) { \ + if((obj)) { \ + (obj)->_uiRef--; \ + if((obj)->_uiRef == 0) \ + (obj)->Release(); \ + (obj) = NULL; \ + } \ +} + +#define __ObjAddRef(obj) { \ + (obj)->_uiRef++; \ +} + +#define type(obj) ((obj)._type) +#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE) +#define raw_type(obj) _RAW_TYPE((obj)._type) + +#define _integer(obj) ((obj)._unVal.nInteger) +#define _float(obj) ((obj)._unVal.fFloat) +#define _string(obj) ((obj)._unVal.pString) +#define _table(obj) ((obj)._unVal.pTable) +#define _array(obj) ((obj)._unVal.pArray) +#define _closure(obj) ((obj)._unVal.pClosure) +#define _generator(obj) ((obj)._unVal.pGenerator) +#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure) +#define _userdata(obj) ((obj)._unVal.pUserData) +#define _userpointer(obj) ((obj)._unVal.pUserPointer) +#define _thread(obj) ((obj)._unVal.pThread) +#define _funcproto(obj) ((obj)._unVal.pFunctionProto) +#define _class(obj) ((obj)._unVal.pClass) +#define _instance(obj) ((obj)._unVal.pInstance) +#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable) +#define _weakref(obj) ((obj)._unVal.pWeakRef) +#define _outer(obj) ((obj)._unVal.pOuter) +#define _refcounted(obj) ((obj)._unVal.pRefCounted) +#define _rawval(obj) ((obj)._unVal.raw) + +#define _stringval(obj) (obj)._unVal.pString->_val +#define _userdataval(obj) ((SQUserPointer)sq_aligning((obj)._unVal.pUserData + 1)) + +#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num)) +#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num)) +///////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////// +#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64) +#define SQ_REFOBJECT_INIT() SQ_OBJECT_RAWINIT() +#else +#define SQ_REFOBJECT_INIT() +#endif + +#define _REF_TYPE_DECL(type,_class,sym) \ + SQObjectPtr(_class * x) \ + { \ + SQ_OBJECT_RAWINIT() \ + _type=type; \ + _unVal.sym = x; \ + assert(_unVal.pTable); \ + _unVal.pRefCounted->_uiRef++; \ + } \ + inline SQObjectPtr& operator=(_class *x) \ + { \ + SQObjectType tOldType; \ + SQObjectValue unOldVal; \ + tOldType=_type; \ + unOldVal=_unVal; \ + _type = type; \ + SQ_REFOBJECT_INIT() \ + _unVal.sym = x; \ + _unVal.pRefCounted->_uiRef++; \ + __Release(tOldType,unOldVal); \ + return *this; \ + } + +#define _SCALAR_TYPE_DECL(type,_class,sym) \ + SQObjectPtr(_class x) \ + { \ + SQ_OBJECT_RAWINIT() \ + _type=type; \ + _unVal.sym = x; \ + } \ + inline SQObjectPtr& operator=(_class x) \ + { \ + __Release(_type,_unVal); \ + _type = type; \ + SQ_OBJECT_RAWINIT() \ + _unVal.sym = x; \ + return *this; \ + } +struct SQObjectPtr : public SQObject +{ + SQObjectPtr() + { + SQ_OBJECT_RAWINIT() + _type=OT_NULL; + _unVal.pUserPointer=NULL; + } + SQObjectPtr(const SQObjectPtr &o) + { + //SQ_OBJECT_RAWINIT() + _type=o._type; + _unVal=o._unVal; + __AddRef(_type,_unVal); + } + SQObjectPtr(const SQObject &o) + { + //SQ_OBJECT_RAWINIT() + _type=o._type; + _unVal=o._unVal; + __AddRef(_type,_unVal); + } + _REF_TYPE_DECL(OT_TABLE,SQTable,pTable) + _REF_TYPE_DECL(OT_CLASS,SQClass,pClass) + _REF_TYPE_DECL(OT_INSTANCE,SQInstance,pInstance) + _REF_TYPE_DECL(OT_ARRAY,SQArray,pArray) + _REF_TYPE_DECL(OT_CLOSURE,SQClosure,pClosure) + _REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,pNativeClosure) + _REF_TYPE_DECL(OT_OUTER,SQOuter,pOuter) + _REF_TYPE_DECL(OT_GENERATOR,SQGenerator,pGenerator) + _REF_TYPE_DECL(OT_STRING,SQString,pString) + _REF_TYPE_DECL(OT_USERDATA,SQUserData,pUserData) + _REF_TYPE_DECL(OT_WEAKREF,SQWeakRef,pWeakRef) + _REF_TYPE_DECL(OT_THREAD,SQVM,pThread) + _REF_TYPE_DECL(OT_FUNCPROTO,SQFunctionProto,pFunctionProto) + + _SCALAR_TYPE_DECL(OT_INTEGER,SQInteger,nInteger) + _SCALAR_TYPE_DECL(OT_FLOAT,SQFloat,fFloat) + _SCALAR_TYPE_DECL(OT_USERPOINTER,SQUserPointer,pUserPointer) + + SQObjectPtr(bool bBool) + { + SQ_OBJECT_RAWINIT() + _type = OT_BOOL; + _unVal.nInteger = bBool?1:0; + } + inline SQObjectPtr& operator=(bool b) + { + __Release(_type,_unVal); + SQ_OBJECT_RAWINIT() + _type = OT_BOOL; + _unVal.nInteger = b?1:0; + return *this; + } + + ~SQObjectPtr() + { + __Release(_type,_unVal); + } + + inline SQObjectPtr& operator=(const SQObjectPtr& obj) + { + SQObjectType tOldType; + SQObjectValue unOldVal; + tOldType=_type; + unOldVal=_unVal; + _unVal = obj._unVal; + _type = obj._type; + __AddRef(_type,_unVal); + __Release(tOldType,unOldVal); + return *this; + } + inline SQObjectPtr& operator=(const SQObject& obj) + { + SQObjectType tOldType; + SQObjectValue unOldVal; + tOldType=_type; + unOldVal=_unVal; + _unVal = obj._unVal; + _type = obj._type; + __AddRef(_type,_unVal); + __Release(tOldType,unOldVal); + return *this; + } + inline void Null() + { + __Release(_type ,_unVal); + _type = OT_NULL; + _unVal.raw = NULL; + } + private: + SQObjectPtr(const SQChar *){} //safety +}; + + +inline void _Swap(SQObject &a,SQObject &b) +{ + SQObjectType tOldType = a._type; + SQObjectValue unOldVal = a._unVal; + a._type = b._type; + a._unVal = b._unVal; + b._type = tOldType; + b._unVal = unOldVal; +} + +///////////////////////////////////////////////////////////////////////////////////// +#ifndef NO_GARBAGE_COLLECTOR +#define MARK_FLAG 0x80000000 +struct SQCollectable : public SQRefCounted { + SQCollectable *_next; + SQCollectable *_prev; + SQSharedState *_sharedstate; + virtual SQObjectType GetType()=0; + virtual void Release()=0; + virtual void Mark(SQCollectable **chain)=0; + void UnMark(); + virtual void Finalize()=0; + static void AddToChain(SQCollectable **chain,SQCollectable *c); + static void RemoveFromChain(SQCollectable **chain,SQCollectable *c); +}; + + +#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj) +#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);} +#define CHAINABLE_OBJ SQCollectable +#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;} +#else + +#define ADD_TO_CHAIN(chain,obj) ((void)0) +#define REMOVE_FROM_CHAIN(chain,obj) ((void)0) +#define CHAINABLE_OBJ SQRefCounted +#define INIT_CHAIN() ((void)0) +#endif + +struct SQDelegable : public CHAINABLE_OBJ { + bool SetDelegate(SQTable *m); + virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); + SQTable *_delegate; +}; + +SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx); +typedef sqvector<SQObjectPtr> SQObjectPtrVec; +typedef sqvector<SQInteger> SQIntVec; +const SQChar *GetTypeName(const SQObjectPtr &obj1); +const SQChar *IdType2Name(SQObjectType type); + + + +#endif //_SQOBJECT_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqopcodes.h b/squirrel_3_0_1_stable/squirrel/sqopcodes.h index 4d179812f..f5f5697c9 100644 --- a/squirrel_3_0_1_stable/squirrel/sqopcodes.h +++ b/squirrel_3_0_1_stable/squirrel/sqopcodes.h @@ -1,132 +1,132 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQOPCODES_H_
-#define _SQOPCODES_H_
-
-#define MAX_FUNC_STACKSIZE 0xFF
-#define MAX_LITERALS ((SQInteger)0x7FFFFFFF)
-
-enum BitWiseOP {
- BW_AND = 0,
- BW_OR = 2,
- BW_XOR = 3,
- BW_SHIFTL = 4,
- BW_SHIFTR = 5,
- BW_USHIFTR = 6
-};
-
-enum CmpOP {
- CMP_G = 0,
- CMP_GE = 2,
- CMP_L = 3,
- CMP_LE = 4,
- CMP_3W = 5
-};
-
-enum NewObjectType {
- NOT_TABLE = 0,
- NOT_ARRAY = 1,
- NOT_CLASS = 2
-};
-
-enum AppendArrayType {
- AAT_STACK = 0,
- AAT_LITERAL = 1,
- AAT_INT = 2,
- AAT_FLOAT = 3,
- AAT_BOOL = 4
-};
-
-enum SQOpcode
-{
- _OP_LINE= 0x00,
- _OP_LOAD= 0x01,
- _OP_LOADINT= 0x02,
- _OP_LOADFLOAT= 0x03,
- _OP_DLOAD= 0x04,
- _OP_TAILCALL= 0x05,
- _OP_CALL= 0x06,
- _OP_PREPCALL= 0x07,
- _OP_PREPCALLK= 0x08,
- _OP_GETK= 0x09,
- _OP_MOVE= 0x0A,
- _OP_NEWSLOT= 0x0B,
- _OP_DELETE= 0x0C,
- _OP_SET= 0x0D,
- _OP_GET= 0x0E,
- _OP_EQ= 0x0F,
- _OP_NE= 0x10,
- _OP_ADD= 0x11,
- _OP_SUB= 0x12,
- _OP_MUL= 0x13,
- _OP_DIV= 0x14,
- _OP_MOD= 0x15,
- _OP_BITW= 0x16,
- _OP_RETURN= 0x17,
- _OP_LOADNULLS= 0x18,
- _OP_LOADROOT= 0x19,
- _OP_LOADBOOL= 0x1A,
- _OP_DMOVE= 0x1B,
- _OP_JMP= 0x1C,
- //_OP_JNZ= 0x1D,
- _OP_JCMP= 0x1D,
- _OP_JZ= 0x1E,
- _OP_SETOUTER= 0x1F,
- _OP_GETOUTER= 0x20,
- _OP_NEWOBJ= 0x21,
- _OP_APPENDARRAY= 0x22,
- _OP_COMPARITH= 0x23,
- _OP_INC= 0x24,
- _OP_INCL= 0x25,
- _OP_PINC= 0x26,
- _OP_PINCL= 0x27,
- _OP_CMP= 0x28,
- _OP_EXISTS= 0x29,
- _OP_INSTANCEOF= 0x2A,
- _OP_AND= 0x2B,
- _OP_OR= 0x2C,
- _OP_NEG= 0x2D,
- _OP_NOT= 0x2E,
- _OP_BWNOT= 0x2F,
- _OP_CLOSURE= 0x30,
- _OP_YIELD= 0x31,
- _OP_RESUME= 0x32,
- _OP_FOREACH= 0x33,
- _OP_POSTFOREACH= 0x34,
- _OP_CLONE= 0x35,
- _OP_TYPEOF= 0x36,
- _OP_PUSHTRAP= 0x37,
- _OP_POPTRAP= 0x38,
- _OP_THROW= 0x39,
- _OP_NEWSLOTA= 0x3A,
- _OP_GETBASE= 0x3B,
- _OP_CLOSE= 0x3C,
-};
-
-struct SQInstructionDesc {
- const SQChar *name;
-};
-
-struct SQInstruction
-{
- SQInstruction(){};
- SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0)
- { op = _op;
- _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1;
- _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3;
- }
-
-
- SQInt32 _arg1;
- unsigned char op;
- unsigned char _arg0;
- unsigned char _arg2;
- unsigned char _arg3;
-};
-
-#include "squtils.h"
-typedef sqvector<SQInstruction> SQInstructionVec;
-
-#define NEW_SLOT_ATTRIBUTES_FLAG 0x01
-#define NEW_SLOT_STATIC_FLAG 0x02
-
-#endif // _SQOPCODES_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQOPCODES_H_ +#define _SQOPCODES_H_ + +#define MAX_FUNC_STACKSIZE 0xFF +#define MAX_LITERALS ((SQInteger)0x7FFFFFFF) + +enum BitWiseOP { + BW_AND = 0, + BW_OR = 2, + BW_XOR = 3, + BW_SHIFTL = 4, + BW_SHIFTR = 5, + BW_USHIFTR = 6 +}; + +enum CmpOP { + CMP_G = 0, + CMP_GE = 2, + CMP_L = 3, + CMP_LE = 4, + CMP_3W = 5 +}; + +enum NewObjectType { + NOT_TABLE = 0, + NOT_ARRAY = 1, + NOT_CLASS = 2 +}; + +enum AppendArrayType { + AAT_STACK = 0, + AAT_LITERAL = 1, + AAT_INT = 2, + AAT_FLOAT = 3, + AAT_BOOL = 4 +}; + +enum SQOpcode +{ + _OP_LINE= 0x00, + _OP_LOAD= 0x01, + _OP_LOADINT= 0x02, + _OP_LOADFLOAT= 0x03, + _OP_DLOAD= 0x04, + _OP_TAILCALL= 0x05, + _OP_CALL= 0x06, + _OP_PREPCALL= 0x07, + _OP_PREPCALLK= 0x08, + _OP_GETK= 0x09, + _OP_MOVE= 0x0A, + _OP_NEWSLOT= 0x0B, + _OP_DELETE= 0x0C, + _OP_SET= 0x0D, + _OP_GET= 0x0E, + _OP_EQ= 0x0F, + _OP_NE= 0x10, + _OP_ADD= 0x11, + _OP_SUB= 0x12, + _OP_MUL= 0x13, + _OP_DIV= 0x14, + _OP_MOD= 0x15, + _OP_BITW= 0x16, + _OP_RETURN= 0x17, + _OP_LOADNULLS= 0x18, + _OP_LOADROOT= 0x19, + _OP_LOADBOOL= 0x1A, + _OP_DMOVE= 0x1B, + _OP_JMP= 0x1C, + //_OP_JNZ= 0x1D, + _OP_JCMP= 0x1D, + _OP_JZ= 0x1E, + _OP_SETOUTER= 0x1F, + _OP_GETOUTER= 0x20, + _OP_NEWOBJ= 0x21, + _OP_APPENDARRAY= 0x22, + _OP_COMPARITH= 0x23, + _OP_INC= 0x24, + _OP_INCL= 0x25, + _OP_PINC= 0x26, + _OP_PINCL= 0x27, + _OP_CMP= 0x28, + _OP_EXISTS= 0x29, + _OP_INSTANCEOF= 0x2A, + _OP_AND= 0x2B, + _OP_OR= 0x2C, + _OP_NEG= 0x2D, + _OP_NOT= 0x2E, + _OP_BWNOT= 0x2F, + _OP_CLOSURE= 0x30, + _OP_YIELD= 0x31, + _OP_RESUME= 0x32, + _OP_FOREACH= 0x33, + _OP_POSTFOREACH= 0x34, + _OP_CLONE= 0x35, + _OP_TYPEOF= 0x36, + _OP_PUSHTRAP= 0x37, + _OP_POPTRAP= 0x38, + _OP_THROW= 0x39, + _OP_NEWSLOTA= 0x3A, + _OP_GETBASE= 0x3B, + _OP_CLOSE= 0x3C, +}; + +struct SQInstructionDesc { + const SQChar *name; +}; + +struct SQInstruction +{ + SQInstruction(){}; + SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0) + { op = _op; + _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1; + _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3; + } + + + SQInt32 _arg1; + unsigned char op; + unsigned char _arg0; + unsigned char _arg2; + unsigned char _arg3; +}; + +#include "squtils.h" +typedef sqvector<SQInstruction> SQInstructionVec; + +#define NEW_SLOT_ATTRIBUTES_FLAG 0x01 +#define NEW_SLOT_STATIC_FLAG 0x02 + +#endif // _SQOPCODES_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqpcheader.h b/squirrel_3_0_1_stable/squirrel/sqpcheader.h index f0e5cf2df..a3fb037e4 100644 --- a/squirrel_3_0_1_stable/squirrel/sqpcheader.h +++ b/squirrel_3_0_1_stable/squirrel/sqpcheader.h @@ -1,19 +1,19 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQPCHEADER_H_
-#define _SQPCHEADER_H_
-
-#if defined(_MSC_VER) && defined(_DEBUG)
-#include <crtdbg.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <new>
-//squirrel stuff
-#include <squirrel.h>
-#include "sqobject.h"
-#include "sqstate.h"
-
-#endif //_SQPCHEADER_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQPCHEADER_H_ +#define _SQPCHEADER_H_ + +#if defined(_MSC_VER) && defined(_DEBUG) +#include <crtdbg.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <new> +//squirrel stuff +#include <squirrel.h> +#include "sqobject.h" +#include "sqstate.h" + +#endif //_SQPCHEADER_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqstate.cpp b/squirrel_3_0_1_stable/squirrel/sqstate.cpp index 0bee40661..8e77900f3 100644 --- a/squirrel_3_0_1_stable/squirrel/sqstate.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqstate.cpp @@ -1,648 +1,648 @@ -/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqopcodes.h"
-#include "sqvm.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "squserdata.h"
-#include "sqclass.h"
-
-//SQObjectPtr _null_;
-//SQObjectPtr _true_(true);
-//SQObjectPtr _false_(false);
-//SQObjectPtr _one_((SQInteger)1);
-//SQObjectPtr _minusone_((SQInteger)-1);
-
-SQSharedState::SQSharedState()
-{
- _compilererrorhandler = NULL;
- _printfunc = NULL;
- _errorfunc = NULL;
- _debuginfo = false;
- _notifyallexceptions = false;
-}
-
-#define newsysstring(s) { \
- _systemstrings->push_back(SQString::Create(this,s)); \
- }
-
-#define newmetamethod(s) { \
- _metamethods->push_back(SQString::Create(this,s)); \
- _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \
- }
-
-bool CompileTypemask(SQIntVec &res,const SQChar *typemask)
-{
- SQInteger i = 0;
-
- SQInteger mask = 0;
- while(typemask[i] != 0) {
-
- switch(typemask[i]){
- case 'o': mask |= _RT_NULL; break;
- case 'i': mask |= _RT_INTEGER; break;
- case 'f': mask |= _RT_FLOAT; break;
- case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break;
- case 's': mask |= _RT_STRING; break;
- case 't': mask |= _RT_TABLE; break;
- case 'a': mask |= _RT_ARRAY; break;
- case 'u': mask |= _RT_USERDATA; break;
- case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break;
- case 'b': mask |= _RT_BOOL; break;
- case 'g': mask |= _RT_GENERATOR; break;
- case 'p': mask |= _RT_USERPOINTER; break;
- case 'v': mask |= _RT_THREAD; break;
- case 'x': mask |= _RT_INSTANCE; break;
- case 'y': mask |= _RT_CLASS; break;
- case 'r': mask |= _RT_WEAKREF; break;
- case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue;
- case ' ': i++; continue; //ignores spaces
- default:
- return false;
- }
- i++;
- if(typemask[i] == '|') {
- i++;
- if(typemask[i] == 0)
- return false;
- continue;
- }
- res.push_back(mask);
- mask = 0;
-
- }
- return true;
-}
-
-SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
-{
- SQInteger i=0;
- SQTable *t=SQTable::Create(ss,0);
- while(funcz[i].name!=0){
- SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f,0);
- nc->_nparamscheck = funcz[i].nparamscheck;
- nc->_name = SQString::Create(ss,funcz[i].name);
- if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))
- return NULL;
- t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
- i++;
- }
- return t;
-}
-
-void SQSharedState::Init()
-{
- _scratchpad=NULL;
- _scratchpadsize=0;
-#ifndef NO_GARBAGE_COLLECTOR
- _gc_chain=NULL;
-#endif
- _stringtable = (SQStringTable*)SQ_MALLOC(sizeof(SQStringTable));
- new (_stringtable) SQStringTable(this);
- sq_new(_metamethods,SQObjectPtrVec);
- sq_new(_systemstrings,SQObjectPtrVec);
- sq_new(_types,SQObjectPtrVec);
- _metamethodsmap = SQTable::Create(this,MT_LAST-1);
- //adding type strings to avoid memory trashing
- //types names
- newsysstring(_SC("null"));
- newsysstring(_SC("table"));
- newsysstring(_SC("array"));
- newsysstring(_SC("closure"));
- newsysstring(_SC("string"));
- newsysstring(_SC("userdata"));
- newsysstring(_SC("integer"));
- newsysstring(_SC("float"));
- newsysstring(_SC("userpointer"));
- newsysstring(_SC("function"));
- newsysstring(_SC("generator"));
- newsysstring(_SC("thread"));
- newsysstring(_SC("class"));
- newsysstring(_SC("instance"));
- newsysstring(_SC("bool"));
- //meta methods
- newmetamethod(MM_ADD);
- newmetamethod(MM_SUB);
- newmetamethod(MM_MUL);
- newmetamethod(MM_DIV);
- newmetamethod(MM_UNM);
- newmetamethod(MM_MODULO);
- newmetamethod(MM_SET);
- newmetamethod(MM_GET);
- newmetamethod(MM_TYPEOF);
- newmetamethod(MM_NEXTI);
- newmetamethod(MM_CMP);
- newmetamethod(MM_CALL);
- newmetamethod(MM_CLONED);
- newmetamethod(MM_NEWSLOT);
- newmetamethod(MM_DELSLOT);
- newmetamethod(MM_TOSTRING);
- newmetamethod(MM_NEWMEMBER);
- newmetamethod(MM_INHERITED);
-
- _constructoridx = SQString::Create(this,_SC("constructor"));
- _registry = SQTable::Create(this,0);
- _consts = SQTable::Create(this,0);
- _table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz);
- _array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz);
- _string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz);
- _number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz);
- _closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz);
- _generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz);
- _thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz);
- _class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz);
- _instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz);
- _weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz);
-
-}
-
-SQSharedState::~SQSharedState()
-{
- _constructoridx.Null();
- _table(_registry)->Finalize();
- _table(_consts)->Finalize();
- _table(_metamethodsmap)->Finalize();
- _registry.Null();
- _consts.Null();
- _metamethodsmap.Null();
- while(!_systemstrings->empty()) {
- _systemstrings->back().Null();
- _systemstrings->pop_back();
- }
- _thread(_root_vm)->Finalize();
- _root_vm.Null();
- _table_default_delegate.Null();
- _array_default_delegate.Null();
- _string_default_delegate.Null();
- _number_default_delegate.Null();
- _closure_default_delegate.Null();
- _generator_default_delegate.Null();
- _thread_default_delegate.Null();
- _class_default_delegate.Null();
- _instance_default_delegate.Null();
- _weakref_default_delegate.Null();
- _refs_table.Finalize();
-#ifndef NO_GARBAGE_COLLECTOR
- SQCollectable *t = _gc_chain;
- SQCollectable *nx = NULL;
- while(t) {
- t->_uiRef++;
- t->Finalize();
- nx = t->_next;
- if(--t->_uiRef == 0)
- t->Release();
- t=nx;
- }
- assert(_gc_chain==NULL); //just to proove a theory
- while(_gc_chain){
- _gc_chain->_uiRef++;
- _gc_chain->Release();
- }
-#endif
-
- sq_delete(_types,SQObjectPtrVec);
- sq_delete(_systemstrings,SQObjectPtrVec);
- sq_delete(_metamethods,SQObjectPtrVec);
- sq_delete(_stringtable,SQStringTable);
- if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize);
-}
-
-
-SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name)
-{
- if(type(name) != OT_STRING)
- return -1;
- SQObjectPtr ret;
- if(_table(_metamethodsmap)->Get(name,ret)) {
- return _integer(ret);
- }
- return -1;
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-
-void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain)
-{
- switch(type(o)){
- case OT_TABLE:_table(o)->Mark(chain);break;
- case OT_ARRAY:_array(o)->Mark(chain);break;
- case OT_USERDATA:_userdata(o)->Mark(chain);break;
- case OT_CLOSURE:_closure(o)->Mark(chain);break;
- case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break;
- case OT_GENERATOR:_generator(o)->Mark(chain);break;
- case OT_THREAD:_thread(o)->Mark(chain);break;
- case OT_CLASS:_class(o)->Mark(chain);break;
- case OT_INSTANCE:_instance(o)->Mark(chain);break;
- case OT_OUTER:_outer(o)->Mark(chain);break;
- case OT_FUNCPROTO:_funcproto(o)->Mark(chain);break;
- default: break; //shutup compiler
- }
-}
-
-
-void SQSharedState::RunMark(SQVM *vm,SQCollectable **tchain)
-{
- SQVM *vms = _thread(_root_vm);
-
- vms->Mark(tchain);
-
- _refs_table.Mark(tchain);
- MarkObject(_registry,tchain);
- MarkObject(_consts,tchain);
- MarkObject(_metamethodsmap,tchain);
- MarkObject(_table_default_delegate,tchain);
- MarkObject(_array_default_delegate,tchain);
- MarkObject(_string_default_delegate,tchain);
- MarkObject(_number_default_delegate,tchain);
- MarkObject(_generator_default_delegate,tchain);
- MarkObject(_thread_default_delegate,tchain);
- MarkObject(_closure_default_delegate,tchain);
- MarkObject(_class_default_delegate,tchain);
- MarkObject(_instance_default_delegate,tchain);
- MarkObject(_weakref_default_delegate,tchain);
-
-}
-
-SQInteger SQSharedState::ResurrectUnreachable(SQVM *vm)
-{
- SQInteger n=0;
- SQCollectable *tchain=NULL;
-
- RunMark(vm,&tchain);
-
- SQCollectable *resurrected = _gc_chain;
- SQCollectable *t = resurrected;
- //SQCollectable *nx = NULL;
-
- _gc_chain = tchain;
-
- SQArray *ret = NULL;
- if(resurrected) {
- ret = SQArray::Create(this,0);
- SQCollectable *rlast = NULL;
- while(t) {
- rlast = t;
- SQObjectType type = t->GetType();
- if(type != OT_FUNCPROTO && type != OT_OUTER) {
- SQObject sqo;
- sqo._type = type;
- sqo._unVal.pRefCounted = t;
- ret->Append(sqo);
- }
- t = t->_next;
- n++;
- }
-
- assert(rlast->_next == NULL);
- rlast->_next = _gc_chain;
- if(_gc_chain)
- {
- _gc_chain->_prev = rlast;
- }
- _gc_chain = resurrected;
- }
-
- t = _gc_chain;
- while(t) {
- t->UnMark();
- t = t->_next;
- }
-
- if(ret) {
- SQObjectPtr temp = ret;
- vm->Push(temp);
- }
- else {
- vm->PushNull();
- }
- return n;
-}
-
-SQInteger SQSharedState::CollectGarbage(SQVM *vm)
-{
- SQInteger n=0;
- SQCollectable *tchain=NULL;
-
- RunMark(vm,&tchain);
-
- SQCollectable *t = _gc_chain;
- SQCollectable *nx = NULL;
- while(t) {
- t->_uiRef++;
- t->Finalize();
- nx = t->_next;
- if(--t->_uiRef == 0)
- t->Release();
- t = nx;
- n++;
- }
-
- t = tchain;
- while(t) {
- t->UnMark();
- t = t->_next;
- }
- _gc_chain = tchain;
-
- return n;
-}
-#endif
-
-#ifndef NO_GARBAGE_COLLECTOR
-void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)
-{
- c->_prev = NULL;
- c->_next = *chain;
- if(*chain) (*chain)->_prev = c;
- *chain = c;
-}
-
-void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)
-{
- if(c->_prev) c->_prev->_next = c->_next;
- else *chain = c->_next;
- if(c->_next)
- c->_next->_prev = c->_prev;
- c->_next = NULL;
- c->_prev = NULL;
-}
-#endif
-
-SQChar* SQSharedState::GetScratchPad(SQInteger size)
-{
- SQInteger newsize;
- if(size>0) {
- if(_scratchpadsize < size) {
- newsize = size + (size>>1);
- _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
- _scratchpadsize = newsize;
-
- }else if(_scratchpadsize >= (size<<5)) {
- newsize = _scratchpadsize >> 1;
- _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
- _scratchpadsize = newsize;
- }
- }
- return _scratchpad;
-}
-
-RefTable::RefTable()
-{
- AllocNodes(4);
-}
-
-void RefTable::Finalize()
-{
- RefNode *nodes = _nodes;
- for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
- nodes->obj.Null();
- nodes++;
- }
-}
-
-RefTable::~RefTable()
-{
- SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode)));
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-void RefTable::Mark(SQCollectable **chain)
-{
- RefNode *nodes = (RefNode *)_nodes;
- for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
- if(type(nodes->obj) != OT_NULL) {
- SQSharedState::MarkObject(nodes->obj,chain);
- }
- nodes++;
- }
-}
-#endif
-
-void RefTable::AddRef(SQObject &obj)
-{
- SQHash mainpos;
- RefNode *prev;
- RefNode *ref = Get(obj,mainpos,&prev,true);
- ref->refs++;
-}
-
-SQUnsignedInteger RefTable::GetRefCount(SQObject &obj)
-{
- SQHash mainpos;
- RefNode *prev;
- RefNode *ref = Get(obj,mainpos,&prev,true);
- return ref->refs;
-}
-
-
-SQBool RefTable::Release(SQObject &obj)
-{
- SQHash mainpos;
- RefNode *prev;
- RefNode *ref = Get(obj,mainpos,&prev,false);
- if(ref) {
- if(--ref->refs == 0) {
- SQObjectPtr o = ref->obj;
- if(prev) {
- prev->next = ref->next;
- }
- else {
- _buckets[mainpos] = ref->next;
- }
- ref->next = _freelist;
- _freelist = ref;
- _slotused--;
- ref->obj.Null();
- //<<FIXME>>test for shrink?
- return SQTrue;
- }
- }
- else {
- assert(0);
- }
- return SQFalse;
-}
-
-void RefTable::Resize(SQUnsignedInteger size)
-{
- RefNode **oldbucks = _buckets;
- RefNode *t = _nodes;
- SQUnsignedInteger oldnumofslots = _numofslots;
- AllocNodes(size);
- //rehash
- SQUnsignedInteger nfound = 0;
- for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) {
- if(type(t->obj) != OT_NULL) {
- //add back;
- assert(t->refs != 0);
- RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj);
- nn->refs = t->refs;
- t->obj.Null();
- nfound++;
- }
- t++;
- }
- assert(nfound == oldnumofslots);
- SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode)));
-}
-
-RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj)
-{
- RefNode *t = _buckets[mainpos];
- RefNode *newnode = _freelist;
- newnode->obj = obj;
- _buckets[mainpos] = newnode;
- _freelist = _freelist->next;
- newnode->next = t;
- assert(newnode->refs == 0);
- _slotused++;
- return newnode;
-}
-
-RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add)
-{
- RefNode *ref;
- mainpos = ::HashObj(obj)&(_numofslots-1);
- *prev = NULL;
- for (ref = _buckets[mainpos]; ref; ) {
- if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj))
- break;
- *prev = ref;
- ref = ref->next;
- }
- if(ref == NULL && add) {
- if(_numofslots == _slotused) {
- assert(_freelist == 0);
- Resize(_numofslots*2);
- mainpos = ::HashObj(obj)&(_numofslots-1);
- }
- ref = Add(mainpos,obj);
- }
- return ref;
-}
-
-void RefTable::AllocNodes(SQUnsignedInteger size)
-{
- RefNode **bucks;
- RefNode *nodes;
- bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode)));
- nodes = (RefNode *)&bucks[size];
- RefNode *temp = nodes;
- SQUnsignedInteger n;
- for(n = 0; n < size - 1; n++) {
- bucks[n] = NULL;
- temp->refs = 0;
- new (&temp->obj) SQObjectPtr;
- temp->next = temp+1;
- temp++;
- }
- bucks[n] = NULL;
- temp->refs = 0;
- new (&temp->obj) SQObjectPtr;
- temp->next = NULL;
- _freelist = nodes;
- _nodes = nodes;
- _buckets = bucks;
- _slotused = 0;
- _numofslots = size;
-}
-//////////////////////////////////////////////////////////////////////////
-//SQStringTable
-/*
-* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
-* http://www.lua.org/copyright.html#4
-* http://www.lua.org/source/4.0.1/src_lstring.c.html
-*/
-
-SQStringTable::SQStringTable(SQSharedState *ss)
-{
- _sharedstate = ss;
- AllocNodes(4);
- _slotused = 0;
-}
-
-SQStringTable::~SQStringTable()
-{
- SQ_FREE(_strings,sizeof(SQString*)*_numofslots);
- _strings = NULL;
-}
-
-void SQStringTable::AllocNodes(SQInteger size)
-{
- _numofslots = size;
- _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots);
- memset(_strings,0,sizeof(SQString*)*_numofslots);
-}
-
-SQString *SQStringTable::Add(const SQChar *news,SQInteger len)
-{
- if(len<0)
- len = (SQInteger)scstrlen(news);
- SQHash h = ::_hashstr(news,len)&(_numofslots-1);
- SQString *s;
- for (s = _strings[h]; s; s = s->_next){
- if(s->_len == len && (!memcmp(news,s->_val,rsl(len))))
- return s; //found
- }
-
- SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString));
- new (t) SQString;
- t->_sharedstate = _sharedstate;
- memcpy(t->_val,news,rsl(len));
- t->_val[len] = _SC('\0');
- t->_len = len;
- t->_hash = ::_hashstr(news,len);
- t->_next = _strings[h];
- _strings[h] = t;
- _slotused++;
- if (_slotused > _numofslots) /* too crowded? */
- Resize(_numofslots*2);
- return t;
-}
-
-void SQStringTable::Resize(SQInteger size)
-{
- SQInteger oldsize=_numofslots;
- SQString **oldtable=_strings;
- AllocNodes(size);
- for (SQInteger i=0; i<oldsize; i++){
- SQString *p = oldtable[i];
- while(p){
- SQString *next = p->_next;
- SQHash h = p->_hash&(_numofslots-1);
- p->_next = _strings[h];
- _strings[h] = p;
- p = next;
- }
- }
- SQ_FREE(oldtable,oldsize*sizeof(SQString*));
-}
-
-void SQStringTable::Remove(SQString *bs)
-{
- SQString *s;
- SQString *prev=NULL;
- SQHash h = bs->_hash&(_numofslots - 1);
-
- for (s = _strings[h]; s; ){
- if(s == bs){
- if(prev)
- prev->_next = s->_next;
- else
- _strings[h] = s->_next;
- _slotused--;
- SQInteger slen = s->_len;
- s->~SQString();
- SQ_FREE(s,sizeof(SQString) + rsl(slen));
- return;
- }
- prev = s;
- s = s->_next;
- }
- assert(0);//if this fail something is wrong
-}
+/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqopcodes.h" +#include "sqvm.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqstring.h" +#include "sqtable.h" +#include "sqarray.h" +#include "squserdata.h" +#include "sqclass.h" + +//SQObjectPtr _null_; +//SQObjectPtr _true_(true); +//SQObjectPtr _false_(false); +//SQObjectPtr _one_((SQInteger)1); +//SQObjectPtr _minusone_((SQInteger)-1); + +SQSharedState::SQSharedState() +{ + _compilererrorhandler = NULL; + _printfunc = NULL; + _errorfunc = NULL; + _debuginfo = false; + _notifyallexceptions = false; +} + +#define newsysstring(s) { \ + _systemstrings->push_back(SQString::Create(this,s)); \ + } + +#define newmetamethod(s) { \ + _metamethods->push_back(SQString::Create(this,s)); \ + _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \ + } + +bool CompileTypemask(SQIntVec &res,const SQChar *typemask) +{ + SQInteger i = 0; + + SQInteger mask = 0; + while(typemask[i] != 0) { + + switch(typemask[i]){ + case 'o': mask |= _RT_NULL; break; + case 'i': mask |= _RT_INTEGER; break; + case 'f': mask |= _RT_FLOAT; break; + case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break; + case 's': mask |= _RT_STRING; break; + case 't': mask |= _RT_TABLE; break; + case 'a': mask |= _RT_ARRAY; break; + case 'u': mask |= _RT_USERDATA; break; + case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break; + case 'b': mask |= _RT_BOOL; break; + case 'g': mask |= _RT_GENERATOR; break; + case 'p': mask |= _RT_USERPOINTER; break; + case 'v': mask |= _RT_THREAD; break; + case 'x': mask |= _RT_INSTANCE; break; + case 'y': mask |= _RT_CLASS; break; + case 'r': mask |= _RT_WEAKREF; break; + case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue; + case ' ': i++; continue; //ignores spaces + default: + return false; + } + i++; + if(typemask[i] == '|') { + i++; + if(typemask[i] == 0) + return false; + continue; + } + res.push_back(mask); + mask = 0; + + } + return true; +} + +SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz) +{ + SQInteger i=0; + SQTable *t=SQTable::Create(ss,0); + while(funcz[i].name!=0){ + SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f,0); + nc->_nparamscheck = funcz[i].nparamscheck; + nc->_name = SQString::Create(ss,funcz[i].name); + if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask)) + return NULL; + t->NewSlot(SQString::Create(ss,funcz[i].name),nc); + i++; + } + return t; +} + +void SQSharedState::Init() +{ + _scratchpad=NULL; + _scratchpadsize=0; +#ifndef NO_GARBAGE_COLLECTOR + _gc_chain=NULL; +#endif + _stringtable = (SQStringTable*)SQ_MALLOC(sizeof(SQStringTable)); + new (_stringtable) SQStringTable(this); + sq_new(_metamethods,SQObjectPtrVec); + sq_new(_systemstrings,SQObjectPtrVec); + sq_new(_types,SQObjectPtrVec); + _metamethodsmap = SQTable::Create(this,MT_LAST-1); + //adding type strings to avoid memory trashing + //types names + newsysstring(_SC("null")); + newsysstring(_SC("table")); + newsysstring(_SC("array")); + newsysstring(_SC("closure")); + newsysstring(_SC("string")); + newsysstring(_SC("userdata")); + newsysstring(_SC("integer")); + newsysstring(_SC("float")); + newsysstring(_SC("userpointer")); + newsysstring(_SC("function")); + newsysstring(_SC("generator")); + newsysstring(_SC("thread")); + newsysstring(_SC("class")); + newsysstring(_SC("instance")); + newsysstring(_SC("bool")); + //meta methods + newmetamethod(MM_ADD); + newmetamethod(MM_SUB); + newmetamethod(MM_MUL); + newmetamethod(MM_DIV); + newmetamethod(MM_UNM); + newmetamethod(MM_MODULO); + newmetamethod(MM_SET); + newmetamethod(MM_GET); + newmetamethod(MM_TYPEOF); + newmetamethod(MM_NEXTI); + newmetamethod(MM_CMP); + newmetamethod(MM_CALL); + newmetamethod(MM_CLONED); + newmetamethod(MM_NEWSLOT); + newmetamethod(MM_DELSLOT); + newmetamethod(MM_TOSTRING); + newmetamethod(MM_NEWMEMBER); + newmetamethod(MM_INHERITED); + + _constructoridx = SQString::Create(this,_SC("constructor")); + _registry = SQTable::Create(this,0); + _consts = SQTable::Create(this,0); + _table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz); + _array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz); + _string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz); + _number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz); + _closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz); + _generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz); + _thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz); + _class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz); + _instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz); + _weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz); + +} + +SQSharedState::~SQSharedState() +{ + _constructoridx.Null(); + _table(_registry)->Finalize(); + _table(_consts)->Finalize(); + _table(_metamethodsmap)->Finalize(); + _registry.Null(); + _consts.Null(); + _metamethodsmap.Null(); + while(!_systemstrings->empty()) { + _systemstrings->back().Null(); + _systemstrings->pop_back(); + } + _thread(_root_vm)->Finalize(); + _root_vm.Null(); + _table_default_delegate.Null(); + _array_default_delegate.Null(); + _string_default_delegate.Null(); + _number_default_delegate.Null(); + _closure_default_delegate.Null(); + _generator_default_delegate.Null(); + _thread_default_delegate.Null(); + _class_default_delegate.Null(); + _instance_default_delegate.Null(); + _weakref_default_delegate.Null(); + _refs_table.Finalize(); +#ifndef NO_GARBAGE_COLLECTOR + SQCollectable *t = _gc_chain; + SQCollectable *nx = NULL; + while(t) { + t->_uiRef++; + t->Finalize(); + nx = t->_next; + if(--t->_uiRef == 0) + t->Release(); + t=nx; + } + assert(_gc_chain==NULL); //just to proove a theory + while(_gc_chain){ + _gc_chain->_uiRef++; + _gc_chain->Release(); + } +#endif + + sq_delete(_types,SQObjectPtrVec); + sq_delete(_systemstrings,SQObjectPtrVec); + sq_delete(_metamethods,SQObjectPtrVec); + sq_delete(_stringtable,SQStringTable); + if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize); +} + + +SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name) +{ + if(type(name) != OT_STRING) + return -1; + SQObjectPtr ret; + if(_table(_metamethodsmap)->Get(name,ret)) { + return _integer(ret); + } + return -1; +} + +#ifndef NO_GARBAGE_COLLECTOR + +void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain) +{ + switch(type(o)){ + case OT_TABLE:_table(o)->Mark(chain);break; + case OT_ARRAY:_array(o)->Mark(chain);break; + case OT_USERDATA:_userdata(o)->Mark(chain);break; + case OT_CLOSURE:_closure(o)->Mark(chain);break; + case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break; + case OT_GENERATOR:_generator(o)->Mark(chain);break; + case OT_THREAD:_thread(o)->Mark(chain);break; + case OT_CLASS:_class(o)->Mark(chain);break; + case OT_INSTANCE:_instance(o)->Mark(chain);break; + case OT_OUTER:_outer(o)->Mark(chain);break; + case OT_FUNCPROTO:_funcproto(o)->Mark(chain);break; + default: break; //shutup compiler + } +} + + +void SQSharedState::RunMark(SQVM *vm,SQCollectable **tchain) +{ + SQVM *vms = _thread(_root_vm); + + vms->Mark(tchain); + + _refs_table.Mark(tchain); + MarkObject(_registry,tchain); + MarkObject(_consts,tchain); + MarkObject(_metamethodsmap,tchain); + MarkObject(_table_default_delegate,tchain); + MarkObject(_array_default_delegate,tchain); + MarkObject(_string_default_delegate,tchain); + MarkObject(_number_default_delegate,tchain); + MarkObject(_generator_default_delegate,tchain); + MarkObject(_thread_default_delegate,tchain); + MarkObject(_closure_default_delegate,tchain); + MarkObject(_class_default_delegate,tchain); + MarkObject(_instance_default_delegate,tchain); + MarkObject(_weakref_default_delegate,tchain); + +} + +SQInteger SQSharedState::ResurrectUnreachable(SQVM *vm) +{ + SQInteger n=0; + SQCollectable *tchain=NULL; + + RunMark(vm,&tchain); + + SQCollectable *resurrected = _gc_chain; + SQCollectable *t = resurrected; + //SQCollectable *nx = NULL; + + _gc_chain = tchain; + + SQArray *ret = NULL; + if(resurrected) { + ret = SQArray::Create(this,0); + SQCollectable *rlast = NULL; + while(t) { + rlast = t; + SQObjectType type = t->GetType(); + if(type != OT_FUNCPROTO && type != OT_OUTER) { + SQObject sqo; + sqo._type = type; + sqo._unVal.pRefCounted = t; + ret->Append(sqo); + } + t = t->_next; + n++; + } + + assert(rlast->_next == NULL); + rlast->_next = _gc_chain; + if(_gc_chain) + { + _gc_chain->_prev = rlast; + } + _gc_chain = resurrected; + } + + t = _gc_chain; + while(t) { + t->UnMark(); + t = t->_next; + } + + if(ret) { + SQObjectPtr temp = ret; + vm->Push(temp); + } + else { + vm->PushNull(); + } + return n; +} + +SQInteger SQSharedState::CollectGarbage(SQVM *vm) +{ + SQInteger n=0; + SQCollectable *tchain=NULL; + + RunMark(vm,&tchain); + + SQCollectable *t = _gc_chain; + SQCollectable *nx = NULL; + while(t) { + t->_uiRef++; + t->Finalize(); + nx = t->_next; + if(--t->_uiRef == 0) + t->Release(); + t = nx; + n++; + } + + t = tchain; + while(t) { + t->UnMark(); + t = t->_next; + } + _gc_chain = tchain; + + return n; +} +#endif + +#ifndef NO_GARBAGE_COLLECTOR +void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c) +{ + c->_prev = NULL; + c->_next = *chain; + if(*chain) (*chain)->_prev = c; + *chain = c; +} + +void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c) +{ + if(c->_prev) c->_prev->_next = c->_next; + else *chain = c->_next; + if(c->_next) + c->_next->_prev = c->_prev; + c->_next = NULL; + c->_prev = NULL; +} +#endif + +SQChar* SQSharedState::GetScratchPad(SQInteger size) +{ + SQInteger newsize; + if(size>0) { + if(_scratchpadsize < size) { + newsize = size + (size>>1); + _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); + _scratchpadsize = newsize; + + }else if(_scratchpadsize >= (size<<5)) { + newsize = _scratchpadsize >> 1; + _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); + _scratchpadsize = newsize; + } + } + return _scratchpad; +} + +RefTable::RefTable() +{ + AllocNodes(4); +} + +void RefTable::Finalize() +{ + RefNode *nodes = _nodes; + for(SQUnsignedInteger n = 0; n < _numofslots; n++) { + nodes->obj.Null(); + nodes++; + } +} + +RefTable::~RefTable() +{ + SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode))); +} + +#ifndef NO_GARBAGE_COLLECTOR +void RefTable::Mark(SQCollectable **chain) +{ + RefNode *nodes = (RefNode *)_nodes; + for(SQUnsignedInteger n = 0; n < _numofslots; n++) { + if(type(nodes->obj) != OT_NULL) { + SQSharedState::MarkObject(nodes->obj,chain); + } + nodes++; + } +} +#endif + +void RefTable::AddRef(SQObject &obj) +{ + SQHash mainpos; + RefNode *prev; + RefNode *ref = Get(obj,mainpos,&prev,true); + ref->refs++; +} + +SQUnsignedInteger RefTable::GetRefCount(SQObject &obj) +{ + SQHash mainpos; + RefNode *prev; + RefNode *ref = Get(obj,mainpos,&prev,true); + return ref->refs; +} + + +SQBool RefTable::Release(SQObject &obj) +{ + SQHash mainpos; + RefNode *prev; + RefNode *ref = Get(obj,mainpos,&prev,false); + if(ref) { + if(--ref->refs == 0) { + SQObjectPtr o = ref->obj; + if(prev) { + prev->next = ref->next; + } + else { + _buckets[mainpos] = ref->next; + } + ref->next = _freelist; + _freelist = ref; + _slotused--; + ref->obj.Null(); + //<<FIXME>>test for shrink? + return SQTrue; + } + } + else { + assert(0); + } + return SQFalse; +} + +void RefTable::Resize(SQUnsignedInteger size) +{ + RefNode **oldbucks = _buckets; + RefNode *t = _nodes; + SQUnsignedInteger oldnumofslots = _numofslots; + AllocNodes(size); + //rehash + SQUnsignedInteger nfound = 0; + for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) { + if(type(t->obj) != OT_NULL) { + //add back; + assert(t->refs != 0); + RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj); + nn->refs = t->refs; + t->obj.Null(); + nfound++; + } + t++; + } + assert(nfound == oldnumofslots); + SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode))); +} + +RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj) +{ + RefNode *t = _buckets[mainpos]; + RefNode *newnode = _freelist; + newnode->obj = obj; + _buckets[mainpos] = newnode; + _freelist = _freelist->next; + newnode->next = t; + assert(newnode->refs == 0); + _slotused++; + return newnode; +} + +RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add) +{ + RefNode *ref; + mainpos = ::HashObj(obj)&(_numofslots-1); + *prev = NULL; + for (ref = _buckets[mainpos]; ref; ) { + if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj)) + break; + *prev = ref; + ref = ref->next; + } + if(ref == NULL && add) { + if(_numofslots == _slotused) { + assert(_freelist == 0); + Resize(_numofslots*2); + mainpos = ::HashObj(obj)&(_numofslots-1); + } + ref = Add(mainpos,obj); + } + return ref; +} + +void RefTable::AllocNodes(SQUnsignedInteger size) +{ + RefNode **bucks; + RefNode *nodes; + bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode))); + nodes = (RefNode *)&bucks[size]; + RefNode *temp = nodes; + SQUnsignedInteger n; + for(n = 0; n < size - 1; n++) { + bucks[n] = NULL; + temp->refs = 0; + new (&temp->obj) SQObjectPtr; + temp->next = temp+1; + temp++; + } + bucks[n] = NULL; + temp->refs = 0; + new (&temp->obj) SQObjectPtr; + temp->next = NULL; + _freelist = nodes; + _nodes = nodes; + _buckets = bucks; + _slotused = 0; + _numofslots = size; +} +////////////////////////////////////////////////////////////////////////// +//SQStringTable +/* +* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) +* http://www.lua.org/copyright.html#4 +* http://www.lua.org/source/4.0.1/src_lstring.c.html +*/ + +SQStringTable::SQStringTable(SQSharedState *ss) +{ + _sharedstate = ss; + AllocNodes(4); + _slotused = 0; +} + +SQStringTable::~SQStringTable() +{ + SQ_FREE(_strings,sizeof(SQString*)*_numofslots); + _strings = NULL; +} + +void SQStringTable::AllocNodes(SQInteger size) +{ + _numofslots = size; + _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots); + memset(_strings,0,sizeof(SQString*)*_numofslots); +} + +SQString *SQStringTable::Add(const SQChar *news,SQInteger len) +{ + if(len<0) + len = (SQInteger)scstrlen(news); + SQHash h = ::_hashstr(news,len)&(_numofslots-1); + SQString *s; + for (s = _strings[h]; s; s = s->_next){ + if(s->_len == len && (!memcmp(news,s->_val,rsl(len)))) + return s; //found + } + + SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString)); + new (t) SQString; + t->_sharedstate = _sharedstate; + memcpy(t->_val,news,rsl(len)); + t->_val[len] = _SC('\0'); + t->_len = len; + t->_hash = ::_hashstr(news,len); + t->_next = _strings[h]; + _strings[h] = t; + _slotused++; + if (_slotused > _numofslots) /* too crowded? */ + Resize(_numofslots*2); + return t; +} + +void SQStringTable::Resize(SQInteger size) +{ + SQInteger oldsize=_numofslots; + SQString **oldtable=_strings; + AllocNodes(size); + for (SQInteger i=0; i<oldsize; i++){ + SQString *p = oldtable[i]; + while(p){ + SQString *next = p->_next; + SQHash h = p->_hash&(_numofslots-1); + p->_next = _strings[h]; + _strings[h] = p; + p = next; + } + } + SQ_FREE(oldtable,oldsize*sizeof(SQString*)); +} + +void SQStringTable::Remove(SQString *bs) +{ + SQString *s; + SQString *prev=NULL; + SQHash h = bs->_hash&(_numofslots - 1); + + for (s = _strings[h]; s; ){ + if(s == bs){ + if(prev) + prev->_next = s->_next; + else + _strings[h] = s->_next; + _slotused--; + SQInteger slen = s->_len; + s->~SQString(); + SQ_FREE(s,sizeof(SQString) + rsl(slen)); + return; + } + prev = s; + s = s->_next; + } + assert(0);//if this fail something is wrong +} diff --git a/squirrel_3_0_1_stable/squirrel/sqstate.h b/squirrel_3_0_1_stable/squirrel/sqstate.h index 3ed3307d7..ee652e786 100644 --- a/squirrel_3_0_1_stable/squirrel/sqstate.h +++ b/squirrel_3_0_1_stable/squirrel/sqstate.h @@ -1,144 +1,144 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQSTATE_H_
-#define _SQSTATE_H_
-
-#include "squtils.h"
-#include "sqobject.h"
-struct SQString;
-struct SQTable;
-//max number of character for a printed number
-#define NUMBER_MAX_CHAR 50
-
-struct SQStringTable
-{
- SQStringTable(SQSharedState*ss);
- ~SQStringTable();
- SQString *Add(const SQChar *,SQInteger len);
- void Remove(SQString *);
-private:
- void Resize(SQInteger size);
- void AllocNodes(SQInteger size);
- SQString **_strings;
- SQUnsignedInteger _numofslots;
- SQUnsignedInteger _slotused;
- SQSharedState *_sharedstate;
-};
-
-struct RefTable {
- struct RefNode {
- SQObjectPtr obj;
- SQUnsignedInteger refs;
- struct RefNode *next;
- };
- RefTable();
- ~RefTable();
- void AddRef(SQObject &obj);
- SQBool Release(SQObject &obj);
- SQUnsignedInteger GetRefCount(SQObject &obj);
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
-#endif
- void Finalize();
-private:
- RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add);
- RefNode *Add(SQHash mainpos,SQObject &obj);
- void Resize(SQUnsignedInteger size);
- void AllocNodes(SQUnsignedInteger size);
- SQUnsignedInteger _numofslots;
- SQUnsignedInteger _slotused;
- RefNode *_nodes;
- RefNode *_freelist;
- RefNode **_buckets;
-};
-
-#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len)
-#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr)
-
-struct SQObjectPtr;
-
-struct SQSharedState
-{
- SQSharedState();
- ~SQSharedState();
- void Init();
-public:
- SQChar* GetScratchPad(SQInteger size);
- SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);
-#ifndef NO_GARBAGE_COLLECTOR
- SQInteger CollectGarbage(SQVM *vm);
- void RunMark(SQVM *vm,SQCollectable **tchain);
- SQInteger ResurrectUnreachable(SQVM *vm);
- static void MarkObject(SQObjectPtr &o,SQCollectable **chain);
-#endif
- SQObjectPtrVec *_metamethods;
- SQObjectPtr _metamethodsmap;
- SQObjectPtrVec *_systemstrings;
- SQObjectPtrVec *_types;
- SQStringTable *_stringtable;
- RefTable _refs_table;
- SQObjectPtr _registry;
- SQObjectPtr _consts;
- SQObjectPtr _constructoridx;
-#ifndef NO_GARBAGE_COLLECTOR
- SQCollectable *_gc_chain;
-#endif
- SQObjectPtr _root_vm;
- SQObjectPtr _table_default_delegate;
- static SQRegFunction _table_default_delegate_funcz[];
- SQObjectPtr _array_default_delegate;
- static SQRegFunction _array_default_delegate_funcz[];
- SQObjectPtr _string_default_delegate;
- static SQRegFunction _string_default_delegate_funcz[];
- SQObjectPtr _number_default_delegate;
- static SQRegFunction _number_default_delegate_funcz[];
- SQObjectPtr _generator_default_delegate;
- static SQRegFunction _generator_default_delegate_funcz[];
- SQObjectPtr _closure_default_delegate;
- static SQRegFunction _closure_default_delegate_funcz[];
- SQObjectPtr _thread_default_delegate;
- static SQRegFunction _thread_default_delegate_funcz[];
- SQObjectPtr _class_default_delegate;
- static SQRegFunction _class_default_delegate_funcz[];
- SQObjectPtr _instance_default_delegate;
- static SQRegFunction _instance_default_delegate_funcz[];
- SQObjectPtr _weakref_default_delegate;
- static SQRegFunction _weakref_default_delegate_funcz[];
-
- SQCOMPILERERROR _compilererrorhandler;
- SQPRINTFUNCTION _printfunc;
- SQPRINTFUNCTION _errorfunc;
- bool _debuginfo;
- bool _notifyallexceptions;
-private:
- SQChar *_scratchpad;
- SQInteger _scratchpadsize;
-};
-
-#define _sp(s) (_sharedstate->GetScratchPad(s))
-#define _spval (_sharedstate->GetScratchPad(-1))
-
-#define _table_ddel _table(_sharedstate->_table_default_delegate)
-#define _array_ddel _table(_sharedstate->_array_default_delegate)
-#define _string_ddel _table(_sharedstate->_string_default_delegate)
-#define _number_ddel _table(_sharedstate->_number_default_delegate)
-#define _generator_ddel _table(_sharedstate->_generator_default_delegate)
-#define _closure_ddel _table(_sharedstate->_closure_default_delegate)
-#define _thread_ddel _table(_sharedstate->_thread_default_delegate)
-#define _class_ddel _table(_sharedstate->_class_default_delegate)
-#define _instance_ddel _table(_sharedstate->_instance_default_delegate)
-#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate)
-
-#ifdef SQUNICODE //rsl REAL STRING LEN
-#define rsl(l) ((l)<<1)
-#else
-#define rsl(l) (l)
-#endif
-
-//extern SQObjectPtr _null_;
-
-bool CompileTypemask(SQIntVec &res,const SQChar *typemask);
-
-void *sq_vm_malloc(SQUnsignedInteger size);
-void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size);
-void sq_vm_free(void *p,SQUnsignedInteger size);
-#endif //_SQSTATE_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQSTATE_H_ +#define _SQSTATE_H_ + +#include "squtils.h" +#include "sqobject.h" +struct SQString; +struct SQTable; +//max number of character for a printed number +#define NUMBER_MAX_CHAR 50 + +struct SQStringTable +{ + SQStringTable(SQSharedState*ss); + ~SQStringTable(); + SQString *Add(const SQChar *,SQInteger len); + void Remove(SQString *); +private: + void Resize(SQInteger size); + void AllocNodes(SQInteger size); + SQString **_strings; + SQUnsignedInteger _numofslots; + SQUnsignedInteger _slotused; + SQSharedState *_sharedstate; +}; + +struct RefTable { + struct RefNode { + SQObjectPtr obj; + SQUnsignedInteger refs; + struct RefNode *next; + }; + RefTable(); + ~RefTable(); + void AddRef(SQObject &obj); + SQBool Release(SQObject &obj); + SQUnsignedInteger GetRefCount(SQObject &obj); +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); +#endif + void Finalize(); +private: + RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add); + RefNode *Add(SQHash mainpos,SQObject &obj); + void Resize(SQUnsignedInteger size); + void AllocNodes(SQUnsignedInteger size); + SQUnsignedInteger _numofslots; + SQUnsignedInteger _slotused; + RefNode *_nodes; + RefNode *_freelist; + RefNode **_buckets; +}; + +#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len) +#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr) + +struct SQObjectPtr; + +struct SQSharedState +{ + SQSharedState(); + ~SQSharedState(); + void Init(); +public: + SQChar* GetScratchPad(SQInteger size); + SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name); +#ifndef NO_GARBAGE_COLLECTOR + SQInteger CollectGarbage(SQVM *vm); + void RunMark(SQVM *vm,SQCollectable **tchain); + SQInteger ResurrectUnreachable(SQVM *vm); + static void MarkObject(SQObjectPtr &o,SQCollectable **chain); +#endif + SQObjectPtrVec *_metamethods; + SQObjectPtr _metamethodsmap; + SQObjectPtrVec *_systemstrings; + SQObjectPtrVec *_types; + SQStringTable *_stringtable; + RefTable _refs_table; + SQObjectPtr _registry; + SQObjectPtr _consts; + SQObjectPtr _constructoridx; +#ifndef NO_GARBAGE_COLLECTOR + SQCollectable *_gc_chain; +#endif + SQObjectPtr _root_vm; + SQObjectPtr _table_default_delegate; + static SQRegFunction _table_default_delegate_funcz[]; + SQObjectPtr _array_default_delegate; + static SQRegFunction _array_default_delegate_funcz[]; + SQObjectPtr _string_default_delegate; + static SQRegFunction _string_default_delegate_funcz[]; + SQObjectPtr _number_default_delegate; + static SQRegFunction _number_default_delegate_funcz[]; + SQObjectPtr _generator_default_delegate; + static SQRegFunction _generator_default_delegate_funcz[]; + SQObjectPtr _closure_default_delegate; + static SQRegFunction _closure_default_delegate_funcz[]; + SQObjectPtr _thread_default_delegate; + static SQRegFunction _thread_default_delegate_funcz[]; + SQObjectPtr _class_default_delegate; + static SQRegFunction _class_default_delegate_funcz[]; + SQObjectPtr _instance_default_delegate; + static SQRegFunction _instance_default_delegate_funcz[]; + SQObjectPtr _weakref_default_delegate; + static SQRegFunction _weakref_default_delegate_funcz[]; + + SQCOMPILERERROR _compilererrorhandler; + SQPRINTFUNCTION _printfunc; + SQPRINTFUNCTION _errorfunc; + bool _debuginfo; + bool _notifyallexceptions; +private: + SQChar *_scratchpad; + SQInteger _scratchpadsize; +}; + +#define _sp(s) (_sharedstate->GetScratchPad(s)) +#define _spval (_sharedstate->GetScratchPad(-1)) + +#define _table_ddel _table(_sharedstate->_table_default_delegate) +#define _array_ddel _table(_sharedstate->_array_default_delegate) +#define _string_ddel _table(_sharedstate->_string_default_delegate) +#define _number_ddel _table(_sharedstate->_number_default_delegate) +#define _generator_ddel _table(_sharedstate->_generator_default_delegate) +#define _closure_ddel _table(_sharedstate->_closure_default_delegate) +#define _thread_ddel _table(_sharedstate->_thread_default_delegate) +#define _class_ddel _table(_sharedstate->_class_default_delegate) +#define _instance_ddel _table(_sharedstate->_instance_default_delegate) +#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate) + +#ifdef SQUNICODE //rsl REAL STRING LEN +#define rsl(l) ((l)<<1) +#else +#define rsl(l) (l) +#endif + +//extern SQObjectPtr _null_; + +bool CompileTypemask(SQIntVec &res,const SQChar *typemask); + +void *sq_vm_malloc(SQUnsignedInteger size); +void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size); +void sq_vm_free(void *p,SQUnsignedInteger size); +#endif //_SQSTATE_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqstring.h b/squirrel_3_0_1_stable/squirrel/sqstring.h index 235d19059..14f09e1b0 100644 --- a/squirrel_3_0_1_stable/squirrel/sqstring.h +++ b/squirrel_3_0_1_stable/squirrel/sqstring.h @@ -1,31 +1,31 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQSTRING_H_
-#define _SQSTRING_H_
-
-inline SQHash _hashstr (const SQChar *s, size_t l)
-{
- SQHash h = (SQHash)l; /* seed */
- size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */
- for (; l>=step; l-=step)
- h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));
- return h;
-}
-
-struct SQString : public SQRefCounted
-{
- SQString(){}
- ~SQString(){}
-public:
- static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 );
- SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
- void Release();
- SQSharedState *_sharedstate;
- SQString *_next; //chain for the string table
- SQInteger _len;
- SQHash _hash;
- SQChar _val[1];
-};
-
-
-
-#endif //_SQSTRING_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQSTRING_H_ +#define _SQSTRING_H_ + +inline SQHash _hashstr (const SQChar *s, size_t l) +{ + SQHash h = (SQHash)l; /* seed */ + size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */ + for (; l>=step; l-=step) + h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++)); + return h; +} + +struct SQString : public SQRefCounted +{ + SQString(){} + ~SQString(){} +public: + static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 ); + SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); + void Release(); + SQSharedState *_sharedstate; + SQString *_next; //chain for the string table + SQInteger _len; + SQHash _hash; + SQChar _val[1]; +}; + + + +#endif //_SQSTRING_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqtable.cpp b/squirrel_3_0_1_stable/squirrel/sqtable.cpp index fe3d5f2a1..bc43124a3 100644 --- a/squirrel_3_0_1_stable/squirrel/sqtable.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqtable.cpp @@ -1,220 +1,220 @@ -/*
-see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqtable.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-
-SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)
-{
- SQInteger pow2size=MINPOWER2;
- while(nInitialSize>pow2size)pow2size=pow2size<<1;
- AllocNodes(pow2size);
- _usednodes = 0;
- _delegate = NULL;
- INIT_CHAIN();
- ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
-}
-
-void SQTable::Remove(const SQObjectPtr &key)
-{
-
- _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
- if (n) {
- n->val.Null();
- n->key.Null();
- _usednodes--;
- Rehash(false);
- }
-}
-
-void SQTable::AllocNodes(SQInteger nSize)
-{
- _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
- for(SQInteger i=0;i<nSize;i++){
- _HashNode &n = nodes[i];
- new (&n) _HashNode;
- n.next=NULL;
- }
- _numofnodes=nSize;
- _nodes=nodes;
- _firstfree=&_nodes[_numofnodes-1];
-}
-
-void SQTable::Rehash(bool force)
-{
- SQInteger oldsize=_numofnodes;
- //prevent problems with the integer division
- if(oldsize<4)oldsize=4;
- _HashNode *nold=_nodes;
- SQInteger nelems=CountUsed();
- if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */
- AllocNodes(oldsize*2);
- else if (nelems <= oldsize/4 && /* less than 1/4? */
- oldsize > MINPOWER2)
- AllocNodes(oldsize/2);
- else if(force)
- AllocNodes(oldsize);
- else
- return;
- _usednodes = 0;
- for (SQInteger i=0; i<oldsize; i++) {
- _HashNode *old = nold+i;
- if (type(old->key) != OT_NULL)
- NewSlot(old->key,old->val);
- }
- for(SQInteger k=0;k<oldsize;k++)
- nold[k].~_HashNode();
- SQ_FREE(nold,oldsize*sizeof(_HashNode));
-}
-
-SQTable *SQTable::Clone()
-{
- SQTable *nt=Create(_opt_ss(this),_numofnodes);
-#ifdef _FAST_CLONE
- _HashNode *basesrc = _nodes;
- _HashNode *basedst = nt->_nodes;
- _HashNode *src = _nodes;
- _HashNode *dst = nt->_nodes;
- SQInteger n = 0;
- for(n = 0; n < _numofnodes; n++) {
- dst->key = src->key;
- dst->val = src->val;
- if(src->next) {
- assert(src->next > basesrc);
- dst->next = basedst + (src->next - basesrc);
- assert(dst != dst->next);
- }
- dst++;
- src++;
- }
- assert(_firstfree > basesrc);
- assert(_firstfree != NULL);
- nt->_firstfree = basedst + (_firstfree - basesrc);
-#else
- SQInteger ridx=0;
- SQObjectPtr key,val;
- while((ridx=Next(true,ridx,key,val))!=-1){
- nt->NewSlot(key,val);
- }
-#endif
- nt->SetDelegate(_delegate);
- return nt;
-}
-
-bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val)
-{
- if(type(key) == OT_NULL)
- return false;
- _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
- if (n) {
- val = _realval(n->val);
- return true;
- }
- return false;
-}
-bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
-{
- assert(type(key) != OT_NULL);
- SQHash h = HashObj(key) & (_numofnodes - 1);
- _HashNode *n = _Get(key, h);
- if (n) {
- n->val = val;
- return false;
- }
- _HashNode *mp = &_nodes[h];
- n = mp;
-
-
- //key not found I'll insert it
- //main pos is not free
-
- if(type(mp->key) != OT_NULL) {
- n = _firstfree; /* get a free place */
- SQHash mph = HashObj(mp->key) & (_numofnodes - 1);
- _HashNode *othern; /* main position of colliding node */
-
- if (mp > n && (othern = &_nodes[mph]) != mp){
- /* yes; move colliding node into free position */
- while (othern->next != mp){
- assert(othern->next != NULL);
- othern = othern->next; /* find previous */
- }
- othern->next = n; /* redo the chain with `n' in place of `mp' */
- n->key = mp->key;
- n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */
- n->next = mp->next;
- mp->key.Null();
- mp->val.Null();
- mp->next = NULL; /* now `mp' is free */
- }
- else{
- /* new node will go into free position */
- n->next = mp->next; /* chain new position */
- mp->next = n;
- mp = n;
- }
- }
- mp->key = key;
-
- for (;;) { /* correct `firstfree' */
- if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {
- mp->val = val;
- _usednodes++;
- return true; /* OK; table still has a free place */
- }
- else if (_firstfree == _nodes) break; /* cannot decrement from here */
- else (_firstfree)--;
- }
- Rehash(true);
- return NewSlot(key, val);
-}
-
-SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
- SQInteger idx = (SQInteger)TranslateIndex(refpos);
- while (idx < _numofnodes) {
- if(type(_nodes[idx].key) != OT_NULL) {
- //first found
- _HashNode &n = _nodes[idx];
- outkey = n.key;
- outval = getweakrefs?(SQObject)n.val:_realval(n.val);
- //return idx for the next iteration
- return ++idx;
- }
- ++idx;
- }
- //nothing to iterate anymore
- return -1;
-}
-
-
-bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val)
-{
- _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
- if (n) {
- n->val = val;
- return true;
- }
- return false;
-}
-
-void SQTable::_ClearNodes()
-{
- for(SQInteger i = 0;i < _numofnodes; i++) { _HashNode &n = _nodes[i]; n.key.Null(); n.val.Null(); }
-}
-
-void SQTable::Finalize()
-{
- _ClearNodes();
- SetDelegate(NULL);
-}
-
-void SQTable::Clear()
-{
- _ClearNodes();
- _usednodes = 0;
- Rehash(true);
-}
+/* +see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include "sqvm.h" +#include "sqtable.h" +#include "sqfuncproto.h" +#include "sqclosure.h" + +SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize) +{ + SQInteger pow2size=MINPOWER2; + while(nInitialSize>pow2size)pow2size=pow2size<<1; + AllocNodes(pow2size); + _usednodes = 0; + _delegate = NULL; + INIT_CHAIN(); + ADD_TO_CHAIN(&_sharedstate->_gc_chain,this); +} + +void SQTable::Remove(const SQObjectPtr &key) +{ + + _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); + if (n) { + n->val.Null(); + n->key.Null(); + _usednodes--; + Rehash(false); + } +} + +void SQTable::AllocNodes(SQInteger nSize) +{ + _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize); + for(SQInteger i=0;i<nSize;i++){ + _HashNode &n = nodes[i]; + new (&n) _HashNode; + n.next=NULL; + } + _numofnodes=nSize; + _nodes=nodes; + _firstfree=&_nodes[_numofnodes-1]; +} + +void SQTable::Rehash(bool force) +{ + SQInteger oldsize=_numofnodes; + //prevent problems with the integer division + if(oldsize<4)oldsize=4; + _HashNode *nold=_nodes; + SQInteger nelems=CountUsed(); + if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */ + AllocNodes(oldsize*2); + else if (nelems <= oldsize/4 && /* less than 1/4? */ + oldsize > MINPOWER2) + AllocNodes(oldsize/2); + else if(force) + AllocNodes(oldsize); + else + return; + _usednodes = 0; + for (SQInteger i=0; i<oldsize; i++) { + _HashNode *old = nold+i; + if (type(old->key) != OT_NULL) + NewSlot(old->key,old->val); + } + for(SQInteger k=0;k<oldsize;k++) + nold[k].~_HashNode(); + SQ_FREE(nold,oldsize*sizeof(_HashNode)); +} + +SQTable *SQTable::Clone() +{ + SQTable *nt=Create(_opt_ss(this),_numofnodes); +#ifdef _FAST_CLONE + _HashNode *basesrc = _nodes; + _HashNode *basedst = nt->_nodes; + _HashNode *src = _nodes; + _HashNode *dst = nt->_nodes; + SQInteger n = 0; + for(n = 0; n < _numofnodes; n++) { + dst->key = src->key; + dst->val = src->val; + if(src->next) { + assert(src->next > basesrc); + dst->next = basedst + (src->next - basesrc); + assert(dst != dst->next); + } + dst++; + src++; + } + assert(_firstfree > basesrc); + assert(_firstfree != NULL); + nt->_firstfree = basedst + (_firstfree - basesrc); +#else + SQInteger ridx=0; + SQObjectPtr key,val; + while((ridx=Next(true,ridx,key,val))!=-1){ + nt->NewSlot(key,val); + } +#endif + nt->SetDelegate(_delegate); + return nt; +} + +bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val) +{ + if(type(key) == OT_NULL) + return false; + _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); + if (n) { + val = _realval(n->val); + return true; + } + return false; +} +bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val) +{ + assert(type(key) != OT_NULL); + SQHash h = HashObj(key) & (_numofnodes - 1); + _HashNode *n = _Get(key, h); + if (n) { + n->val = val; + return false; + } + _HashNode *mp = &_nodes[h]; + n = mp; + + + //key not found I'll insert it + //main pos is not free + + if(type(mp->key) != OT_NULL) { + n = _firstfree; /* get a free place */ + SQHash mph = HashObj(mp->key) & (_numofnodes - 1); + _HashNode *othern; /* main position of colliding node */ + + if (mp > n && (othern = &_nodes[mph]) != mp){ + /* yes; move colliding node into free position */ + while (othern->next != mp){ + assert(othern->next != NULL); + othern = othern->next; /* find previous */ + } + othern->next = n; /* redo the chain with `n' in place of `mp' */ + n->key = mp->key; + n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */ + n->next = mp->next; + mp->key.Null(); + mp->val.Null(); + mp->next = NULL; /* now `mp' is free */ + } + else{ + /* new node will go into free position */ + n->next = mp->next; /* chain new position */ + mp->next = n; + mp = n; + } + } + mp->key = key; + + for (;;) { /* correct `firstfree' */ + if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) { + mp->val = val; + _usednodes++; + return true; /* OK; table still has a free place */ + } + else if (_firstfree == _nodes) break; /* cannot decrement from here */ + else (_firstfree)--; + } + Rehash(true); + return NewSlot(key, val); +} + +SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) +{ + SQInteger idx = (SQInteger)TranslateIndex(refpos); + while (idx < _numofnodes) { + if(type(_nodes[idx].key) != OT_NULL) { + //first found + _HashNode &n = _nodes[idx]; + outkey = n.key; + outval = getweakrefs?(SQObject)n.val:_realval(n.val); + //return idx for the next iteration + return ++idx; + } + ++idx; + } + //nothing to iterate anymore + return -1; +} + + +bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val) +{ + _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); + if (n) { + n->val = val; + return true; + } + return false; +} + +void SQTable::_ClearNodes() +{ + for(SQInteger i = 0;i < _numofnodes; i++) { _HashNode &n = _nodes[i]; n.key.Null(); n.val.Null(); } +} + +void SQTable::Finalize() +{ + _ClearNodes(); + SetDelegate(NULL); +} + +void SQTable::Clear() +{ + _ClearNodes(); + _usednodes = 0; + Rehash(true); +} diff --git a/squirrel_3_0_1_stable/squirrel/sqtable.h b/squirrel_3_0_1_stable/squirrel/sqtable.h index 2f6487023..b2ba0ba98 100644 --- a/squirrel_3_0_1_stable/squirrel/sqtable.h +++ b/squirrel_3_0_1_stable/squirrel/sqtable.h @@ -1,92 +1,92 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQTABLE_H_
-#define _SQTABLE_H_
-/*
-* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
-* http://www.lua.org/copyright.html#4
-* http://www.lua.org/source/4.0.1/src_ltable.c.html
-*/
-
-#include "sqstring.h"
-
-
-#define hashptr(p) ((SQHash)(((SQInteger)p) >> 3))
-
-inline SQHash HashObj(const SQObjectPtr &key)
-{
- switch(type(key)) {
- case OT_STRING: return _string(key)->_hash;
- case OT_FLOAT: return (SQHash)((SQInteger)_float(key));
- case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key));
- default: return hashptr(key._unVal.pRefCounted);
- }
-}
-
-struct SQTable : public SQDelegable
-{
-private:
- struct _HashNode
- {
- _HashNode() { next = NULL; }
- SQObjectPtr val;
- SQObjectPtr key;
- _HashNode *next;
- };
- _HashNode *_firstfree;
- _HashNode *_nodes;
- SQInteger _numofnodes;
- SQInteger _usednodes;
-
-///////////////////////////
- void AllocNodes(SQInteger nSize);
- void Rehash(bool force);
- SQTable(SQSharedState *ss, SQInteger nInitialSize);
- void _ClearNodes();
-public:
- static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)
- {
- SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
- new (newtable) SQTable(ss, nInitialSize);
- newtable->_delegate = NULL;
- return newtable;
- }
- void Finalize();
- SQTable *Clone();
- ~SQTable()
- {
- SetDelegate(NULL);
- REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
- for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
- SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- SQObjectType GetType() {return OT_TABLE;}
-#endif
- inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)
- {
- _HashNode *n = &_nodes[hash];
- do{
- if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){
- return n;
- }
- }while((n = n->next));
- return NULL;
- }
- bool Get(const SQObjectPtr &key,SQObjectPtr &val);
- void Remove(const SQObjectPtr &key);
- bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
- //returns true if a new slot has been created false if it was already present
- bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
- SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
-
- SQInteger CountUsed(){ return _usednodes;}
- void Clear();
- void Release()
- {
- sq_delete(this, SQTable);
- }
-
-};
-
-#endif //_SQTABLE_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQTABLE_H_ +#define _SQTABLE_H_ +/* +* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) +* http://www.lua.org/copyright.html#4 +* http://www.lua.org/source/4.0.1/src_ltable.c.html +*/ + +#include "sqstring.h" + + +#define hashptr(p) ((SQHash)(((SQInteger)p) >> 3)) + +inline SQHash HashObj(const SQObjectPtr &key) +{ + switch(type(key)) { + case OT_STRING: return _string(key)->_hash; + case OT_FLOAT: return (SQHash)((SQInteger)_float(key)); + case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key)); + default: return hashptr(key._unVal.pRefCounted); + } +} + +struct SQTable : public SQDelegable +{ +private: + struct _HashNode + { + _HashNode() { next = NULL; } + SQObjectPtr val; + SQObjectPtr key; + _HashNode *next; + }; + _HashNode *_firstfree; + _HashNode *_nodes; + SQInteger _numofnodes; + SQInteger _usednodes; + +/////////////////////////// + void AllocNodes(SQInteger nSize); + void Rehash(bool force); + SQTable(SQSharedState *ss, SQInteger nInitialSize); + void _ClearNodes(); +public: + static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize) + { + SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable)); + new (newtable) SQTable(ss, nInitialSize); + newtable->_delegate = NULL; + return newtable; + } + void Finalize(); + SQTable *Clone(); + ~SQTable() + { + SetDelegate(NULL); + REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); + for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode(); + SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode)); + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + SQObjectType GetType() {return OT_TABLE;} +#endif + inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash) + { + _HashNode *n = &_nodes[hash]; + do{ + if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){ + return n; + } + }while((n = n->next)); + return NULL; + } + bool Get(const SQObjectPtr &key,SQObjectPtr &val); + void Remove(const SQObjectPtr &key); + bool Set(const SQObjectPtr &key, const SQObjectPtr &val); + //returns true if a new slot has been created false if it was already present + bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val); + SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); + + SQInteger CountUsed(){ return _usednodes;} + void Clear(); + void Release() + { + sq_delete(this, SQTable); + } + +}; + +#endif //_SQTABLE_H_ diff --git a/squirrel_3_0_1_stable/squirrel/squserdata.h b/squirrel_3_0_1_stable/squirrel/squserdata.h index dea27ae78..2bf1b0709 100644 --- a/squirrel_3_0_1_stable/squirrel/squserdata.h +++ b/squirrel_3_0_1_stable/squirrel/squserdata.h @@ -1,40 +1,40 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQUSERDATA_H_
-#define _SQUSERDATA_H_
-
-struct SQUserData : SQDelegable
-{
- SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); }
- ~SQUserData()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);
- SetDelegate(NULL);
- }
- static SQUserData* Create(SQSharedState *ss, SQInteger size)
- {
- SQUserData* ud = (SQUserData*)SQ_MALLOC(sq_aligning(sizeof(SQUserData))+size);
- new (ud) SQUserData(ss);
- ud->_size = size;
- ud->_typetag = 0;
- return ud;
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){SetDelegate(NULL);}
- SQObjectType GetType(){ return OT_USERDATA;}
-#endif
- void Release() {
- if (_hook) _hook((SQUserPointer)sq_aligning(this + 1),_size);
- SQInteger tsize = _size;
- this->~SQUserData();
- SQ_FREE(this, sq_aligning(sizeof(SQUserData)) + tsize);
- }
-
-
- SQInteger _size;
- SQRELEASEHOOK _hook;
- SQUserPointer _typetag;
- //SQChar _val[1];
-};
-
-#endif //_SQUSERDATA_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQUSERDATA_H_ +#define _SQUSERDATA_H_ + +struct SQUserData : SQDelegable +{ + SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); } + ~SQUserData() + { + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this); + SetDelegate(NULL); + } + static SQUserData* Create(SQSharedState *ss, SQInteger size) + { + SQUserData* ud = (SQUserData*)SQ_MALLOC(sq_aligning(sizeof(SQUserData))+size); + new (ud) SQUserData(ss); + ud->_size = size; + ud->_typetag = 0; + return ud; + } +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + void Finalize(){SetDelegate(NULL);} + SQObjectType GetType(){ return OT_USERDATA;} +#endif + void Release() { + if (_hook) _hook((SQUserPointer)sq_aligning(this + 1),_size); + SQInteger tsize = _size; + this->~SQUserData(); + SQ_FREE(this, sq_aligning(sizeof(SQUserData)) + tsize); + } + + + SQInteger _size; + SQRELEASEHOOK _hook; + SQUserPointer _typetag; + //SQChar _val[1]; +}; + +#endif //_SQUSERDATA_H_ diff --git a/squirrel_3_0_1_stable/squirrel/squtils.h b/squirrel_3_0_1_stable/squirrel/squtils.h index bff7d24bb..f3510beea 100644 --- a/squirrel_3_0_1_stable/squirrel/squtils.h +++ b/squirrel_3_0_1_stable/squirrel/squtils.h @@ -1,112 +1,112 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQUTILS_H_
-#define _SQUTILS_H_
-
-#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;}
-#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));}
-#define SQ_MALLOC(__size) sq_vm_malloc((__size));
-#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size));
-#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size));
-
-#define sq_aligning(v) (((size_t)(v) + (SQ_ALIGNMENT-1)) & (~(SQ_ALIGNMENT-1)))
-
-//sqvector mini vector class, supports objects by value
-template<typename T> class sqvector
-{
-public:
- sqvector()
- {
- _vals = NULL;
- _size = 0;
- _allocated = 0;
- }
- sqvector(const sqvector<T>& v)
- {
- copy(v);
- }
- void copy(const sqvector<T>& v)
- {
- if(_size) {
- resize(0); //destroys all previous stuff
- }
- //resize(v._size);
- if(v._size > _allocated) {
- _realloc(v._size);
- }
- for(SQUnsignedInteger i = 0; i < v._size; i++) {
- new ((void *)&_vals[i]) T(v._vals[i]);
- }
- _size = v._size;
- }
- ~sqvector()
- {
- if(_allocated) {
- for(SQUnsignedInteger i = 0; i < _size; i++)
- _vals[i].~T();
- SQ_FREE(_vals, (_allocated * sizeof(T)));
- }
- }
- void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }
- void resize(SQUnsignedInteger newsize, const T& fill = T())
- {
- if(newsize > _allocated)
- _realloc(newsize);
- if(newsize > _size) {
- while(_size < newsize) {
- new ((void *)&_vals[_size]) T(fill);
- _size++;
- }
- }
- else{
- for(SQUnsignedInteger i = newsize; i < _size; i++) {
- _vals[i].~T();
- }
- _size = newsize;
- }
- }
- void shrinktofit() { if(_size > 4) { _realloc(_size); } }
- T& top() const { return _vals[_size - 1]; }
- inline SQUnsignedInteger size() const { return _size; }
- bool empty() const { return (_size <= 0); }
- inline T &push_back(const T& val = T())
- {
- if(_allocated <= _size)
- _realloc(_size * 2);
- return *(new ((void *)&_vals[_size++]) T(val));
- }
- inline void pop_back()
- {
- _size--; _vals[_size].~T();
- }
- void insert(SQUnsignedInteger idx, const T& val)
- {
- resize(_size + 1);
- for(SQUnsignedInteger i = _size - 1; i > idx; i--) {
- _vals[i] = _vals[i - 1];
- }
- _vals[idx] = val;
- }
- void remove(SQUnsignedInteger idx)
- {
- _vals[idx].~T();
- if(idx < (_size - 1)) {
- memcpy(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
- }
- _size--;
- }
- SQUnsignedInteger capacity() { return _allocated; }
- inline T &back() const { return _vals[_size - 1]; }
- inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }
- T* _vals;
-private:
- void _realloc(SQUnsignedInteger newsize)
- {
- newsize = (newsize > 0)?newsize:4;
- _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
- _allocated = newsize;
- }
- SQUnsignedInteger _size;
- SQUnsignedInteger _allocated;
-};
-
-#endif //_SQUTILS_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQUTILS_H_ +#define _SQUTILS_H_ + +#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;} +#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));} +#define SQ_MALLOC(__size) sq_vm_malloc((__size)); +#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size)); +#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size)); + +#define sq_aligning(v) (((size_t)(v) + (SQ_ALIGNMENT-1)) & (~(SQ_ALIGNMENT-1))) + +//sqvector mini vector class, supports objects by value +template<typename T> class sqvector +{ +public: + sqvector() + { + _vals = NULL; + _size = 0; + _allocated = 0; + } + sqvector(const sqvector<T>& v) + { + copy(v); + } + void copy(const sqvector<T>& v) + { + if(_size) { + resize(0); //destroys all previous stuff + } + //resize(v._size); + if(v._size > _allocated) { + _realloc(v._size); + } + for(SQUnsignedInteger i = 0; i < v._size; i++) { + new ((void *)&_vals[i]) T(v._vals[i]); + } + _size = v._size; + } + ~sqvector() + { + if(_allocated) { + for(SQUnsignedInteger i = 0; i < _size; i++) + _vals[i].~T(); + SQ_FREE(_vals, (_allocated * sizeof(T))); + } + } + void reserve(SQUnsignedInteger newsize) { _realloc(newsize); } + void resize(SQUnsignedInteger newsize, const T& fill = T()) + { + if(newsize > _allocated) + _realloc(newsize); + if(newsize > _size) { + while(_size < newsize) { + new ((void *)&_vals[_size]) T(fill); + _size++; + } + } + else{ + for(SQUnsignedInteger i = newsize; i < _size; i++) { + _vals[i].~T(); + } + _size = newsize; + } + } + void shrinktofit() { if(_size > 4) { _realloc(_size); } } + T& top() const { return _vals[_size - 1]; } + inline SQUnsignedInteger size() const { return _size; } + bool empty() const { return (_size <= 0); } + inline T &push_back(const T& val = T()) + { + if(_allocated <= _size) + _realloc(_size * 2); + return *(new ((void *)&_vals[_size++]) T(val)); + } + inline void pop_back() + { + _size--; _vals[_size].~T(); + } + void insert(SQUnsignedInteger idx, const T& val) + { + resize(_size + 1); + for(SQUnsignedInteger i = _size - 1; i > idx; i--) { + _vals[i] = _vals[i - 1]; + } + _vals[idx] = val; + } + void remove(SQUnsignedInteger idx) + { + _vals[idx].~T(); + if(idx < (_size - 1)) { + memcpy(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1)); + } + _size--; + } + SQUnsignedInteger capacity() { return _allocated; } + inline T &back() const { return _vals[_size - 1]; } + inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; } + T* _vals; +private: + void _realloc(SQUnsignedInteger newsize) + { + newsize = (newsize > 0)?newsize:4; + _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T)); + _allocated = newsize; + } + SQUnsignedInteger _size; + SQUnsignedInteger _allocated; +}; + +#endif //_SQUTILS_H_ diff --git a/squirrel_3_0_1_stable/squirrel/sqvm.cpp b/squirrel_3_0_1_stable/squirrel/sqvm.cpp index bd8ebcc1a..b6ad21836 100644 --- a/squirrel_3_0_1_stable/squirrel/sqvm.cpp +++ b/squirrel_3_0_1_stable/squirrel/sqvm.cpp @@ -1,1714 +1,1714 @@ -/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <math.h>
-#include <stdlib.h>
-#include "sqopcodes.h"
-#include "sqvm.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "squserdata.h"
-#include "sqarray.h"
-#include "sqclass.h"
-
-#define TOP() (_stack._vals[_top-1])
-
-bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
-{
- SQInteger res;
- if((type(o1)|type(o2)) == OT_INTEGER)
- {
- SQInteger i1 = _integer(o1), i2 = _integer(o2);
- switch(op) {
- case BW_AND: res = i1 & i2; break;
- case BW_OR: res = i1 | i2; break;
- case BW_XOR: res = i1 ^ i2; break;
- case BW_SHIFTL: res = i1 << i2; break;
- case BW_SHIFTR: res = i1 >> i2; break;
- case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break;
- default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; }
- }
- }
- else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;}
- trg = res;
- return true;
-}
-
-#define _ARITH_(op,trg,o1,o2) \
-{ \
- SQInteger tmask = type(o1)|type(o2); \
- switch(tmask) { \
- case OT_INTEGER: trg = _integer(o1) op _integer(o2);break; \
- case (OT_FLOAT|OT_INTEGER): \
- case (OT_FLOAT): trg = tofloat(o1) op tofloat(o2); break;\
- default: _GUARD(ARITH_OP((#op)[0],trg,o1,o2)); break;\
- } \
-}
-
-#define _ARITH_NOZERO(op,trg,o1,o2,err) \
-{ \
- SQInteger tmask = type(o1)|type(o2); \
- switch(tmask) { \
- case OT_INTEGER: { SQInteger i2 = _integer(o2); if(i2 == 0) { Raise_Error(err); SQ_THROW(); } trg = _integer(o1) op i2; } break;\
- case (OT_FLOAT|OT_INTEGER): \
- case (OT_FLOAT): trg = tofloat(o1) op tofloat(o2); break;\
- default: _GUARD(ARITH_OP((#op)[0],trg,o1,o2)); break;\
- } \
-}
-
-bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
-{
- SQInteger tmask = type(o1)|type(o2);
- switch(tmask) {
- case OT_INTEGER:{
- SQInteger res, i1 = _integer(o1), i2 = _integer(o2);
- switch(op) {
- case '+': res = i1 + i2; break;
- case '-': res = i1 - i2; break;
- case '/': if(i2 == 0) { Raise_Error(_SC("division by zero")); return false; }
- res = i1 / i2;
- break;
- case '*': res = i1 * i2; break;
- case '%': if(i2 == 0) { Raise_Error(_SC("modulo by zero")); return false; }
- res = i1 % i2;
- break;
- default: res = 0xDEADBEEF;
- }
- trg = res; }
- break;
- case (OT_FLOAT|OT_INTEGER):
- case (OT_FLOAT):{
- SQFloat res, f1 = tofloat(o1), f2 = tofloat(o2);
- switch(op) {
- case '+': res = f1 + f2; break;
- case '-': res = f1 - f2; break;
- case '/': res = f1 / f2; break;
- case '*': res = f1 * f2; break;
- case '%': res = SQFloat(fmod((double)f1,(double)f2)); break;
- default: res = 0x0f;
- }
- trg = res; }
- break;
- default:
- if(op == '+' && (tmask & _RT_STRING)){
- if(!StringCat(o1, o2, trg)) return false;
- }
- else if(!ArithMetaMethod(op,o1,o2,trg)) {
- return false;
- }
- }
- return true;
-}
-
-SQVM::SQVM(SQSharedState *ss)
-{
- _sharedstate=ss;
- _suspended = SQFalse;
- _suspended_target = -1;
- _suspended_root = SQFalse;
- _suspended_traps = -1;
- _foreignptr = NULL;
- _nnativecalls = 0;
- _nmetamethodscall = 0;
- _lasterror.Null();
- _errorhandler.Null();
- _debughook = false;
- _debughook_native = NULL;
- _debughook_closure.Null();
- _openouters = NULL;
- ci = NULL;
- INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
-}
-
-void SQVM::Finalize()
-{
- if(_openouters) CloseOuters(&_stack._vals[0]);
- _roottable.Null();
- _lasterror.Null();
- _errorhandler.Null();
- _debughook = false;
- _debughook_native = NULL;
- _debughook_closure.Null();
- temp_reg.Null();
- _callstackdata.resize(0);
- SQInteger size=_stack.size();
- for(SQInteger i=0;i<size;i++)
- _stack[i].Null();
-}
-
-SQVM::~SQVM()
-{
- Finalize();
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
-}
-
-bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest)
-{
- SQMetaMethod mm;
- switch(op){
- case _SC('+'): mm=MT_ADD; break;
- case _SC('-'): mm=MT_SUB; break;
- case _SC('/'): mm=MT_DIV; break;
- case _SC('*'): mm=MT_MUL; break;
- case _SC('%'): mm=MT_MODULO; break;
- default: mm = MT_ADD; assert(0); break; //shutup compiler
- }
- if(is_delegable(o1) && _delegable(o1)->_delegate) {
-
- SQObjectPtr closure;
- if(_delegable(o1)->GetMetaMethod(this, mm, closure)) {
- Push(o1);Push(o2);
- return CallMetaMethod(closure,mm,2,dest);
- }
- }
- Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2));
- return false;
-}
-
-bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o)
-{
-
- switch(type(o)) {
- case OT_INTEGER:
- trg = -_integer(o);
- return true;
- case OT_FLOAT:
- trg = -_float(o);
- return true;
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o)->_delegate) {
- SQObjectPtr closure;
- if(_delegable(o)->GetMetaMethod(this, MT_UNM, closure)) {
- Push(o);
- if(!CallMetaMethod(closure, MT_UNM, 1, temp_reg)) return false;
- _Swap(trg,temp_reg);
- return true;
-
- }
- }
- default:break; //shutup compiler
- }
- Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o));
- return false;
-}
-
-#define _RET_SUCCEED(exp) { result = (exp); return true; }
-bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result)
-{
- SQObjectType t1 = type(o1), t2 = type(o2);
- if(t1 == t2){
- if(_rawval(o1)==_rawval(o2))_RET_SUCCEED(0);
- SQObjectPtr res;
- switch(t1){
- case OT_STRING:
- _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2)));
- case OT_INTEGER:
- _RET_SUCCEED(_integer(o1)-_integer(o2));
- case OT_FLOAT:
- _RET_SUCCEED((_float(o1)<_float(o2))?-1:1);
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o1)->_delegate) {
- SQObjectPtr closure;
- if(_delegable(o1)->GetMetaMethod(this, MT_CMP, closure)) {
- Push(o1);Push(o2);
- if(!CallMetaMethod(closure,MT_CMP,2,res)) return false;
- }
- break;
- }
- //continues through (no break needed)
- default:
- _RET_SUCCEED( _userpointer(o1) < _userpointer(o2)?-1:1 );
- }
- if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; }
- _RET_SUCCEED(_integer(res));
-
- }
- else{
- if(sq_isnumeric(o1) && sq_isnumeric(o2)){
- if((t1==OT_INTEGER) && (t2==OT_FLOAT)) {
- if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); }
- else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); }
- _RET_SUCCEED(1);
- }
- else{
- if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); }
- else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); }
- _RET_SUCCEED(1);
- }
- }
- else if(t1==OT_NULL) {_RET_SUCCEED(-1);}
- else if(t2==OT_NULL) {_RET_SUCCEED(1);}
- else { Raise_CompareError(o1,o2); return false; }
-
- }
- assert(0);
- _RET_SUCCEED(0); //cannot happen
-}
-
-bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res)
-{
- SQInteger r;
- if(ObjCmp(o1,o2,r)) {
- switch(op) {
- case CMP_G: res = (r > 0); return true;
- case CMP_GE: res = (r >= 0); return true;
- case CMP_L: res = (r < 0); return true;
- case CMP_LE: res = (r <= 0); return true;
- case CMP_3W: res = r; return true;
- }
- assert(0);
- }
- return false;
-}
-
-bool SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res)
-{
- switch(type(o)) {
- case OT_STRING:
- res = o;
- return true;
- case OT_FLOAT:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%g"),_float(o));
- break;
- case OT_INTEGER:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_PRINT_INT_FMT,_integer(o));
- break;
- case OT_BOOL:
- scsprintf(_sp(rsl(6)),_integer(o)?_SC("true"):_SC("false"));
- break;
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o)->_delegate) {
- SQObjectPtr closure;
- if(_delegable(o)->GetMetaMethod(this, MT_TOSTRING, closure)) {
- Push(o);
- if(CallMetaMethod(closure,MT_TOSTRING,1,res)) {;
- if(type(res) == OT_STRING)
- return true;
- }
- else {
- return false;
- }
- }
- }
- default:
- scsprintf(_sp(rsl(sizeof(void*)+20)),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o));
- }
- res = SQString::Create(_ss(this),_spval);
- return true;
-}
-
-
-bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest)
-{
- SQObjectPtr a, b;
- if(!ToString(str, a)) return false;
- if(!ToString(obj, b)) return false;
- SQInteger l = _string(a)->_len , ol = _string(b)->_len;
- SQChar *s = _sp(rsl(l + ol + 1));
- memcpy(s, _stringval(a), rsl(l));
- memcpy(s + l, _stringval(b), rsl(ol));
- dest = SQString::Create(_ss(this), _spval, l + ol);
- return true;
-}
-
-bool SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest)
-{
- if(is_delegable(obj1) && _delegable(obj1)->_delegate) {
- SQObjectPtr closure;
- if(_delegable(obj1)->GetMetaMethod(this, MT_TYPEOF, closure)) {
- Push(obj1);
- return CallMetaMethod(closure,MT_TYPEOF,1,dest);
- }
- }
- dest = SQString::Create(_ss(this),GetTypeName(obj1));
- return true;
-}
-
-bool SQVM::Init(SQVM *friendvm, SQInteger stacksize)
-{
- _stack.resize(stacksize);
- _alloccallsstacksize = 4;
- _callstackdata.resize(_alloccallsstacksize);
- _callsstacksize = 0;
- _callsstack = &_callstackdata[0];
- _stackbase = 0;
- _top = 0;
- if(!friendvm)
- _roottable = SQTable::Create(_ss(this), 0);
- else {
- _roottable = friendvm->_roottable;
- _errorhandler = friendvm->_errorhandler;
- _debughook = friendvm->_debughook;
- _debughook_native = friendvm->_debughook_native;
- _debughook_closure = friendvm->_debughook_closure;
- }
-
- sq_base_register(this);
- return true;
-}
-
-
-bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQInteger stackbase,bool tailcall)
-{
- SQFunctionProto *func = closure->_function;
-
- SQInteger paramssize = func->_nparameters;
- const SQInteger newtop = stackbase + func->_stacksize;
- SQInteger nargs = args;
- if(func->_varparams)
- {
- paramssize--;
- if (nargs < paramssize) {
- Raise_Error(_SC("wrong number of parameters"));
- return false;
- }
-
- //dumpstack(stackbase);
- SQInteger nvargs = nargs - paramssize;
- SQArray *arr = SQArray::Create(_ss(this),nvargs);
- SQInteger pbase = stackbase+paramssize;
- for(SQInteger n = 0; n < nvargs; n++) {
- arr->_values[n] = _stack._vals[pbase];
- _stack._vals[pbase].Null();
- pbase++;
-
- }
- _stack._vals[stackbase+paramssize] = arr;
- //dumpstack(stackbase);
- }
- else if (paramssize != nargs) {
- SQInteger ndef = func->_ndefaultparams;
- SQInteger diff;
- if(ndef && nargs < paramssize && (diff = paramssize - nargs) <= ndef) {
- for(SQInteger n = ndef - diff; n < ndef; n++) {
- _stack._vals[stackbase + (nargs++)] = closure->_defaultparams[n];
- }
- }
- else {
- Raise_Error(_SC("wrong number of parameters"));
- return false;
- }
- }
-
- if(closure->_env) {
- _stack._vals[stackbase] = closure->_env->_obj;
- }
-
- if(!EnterFrame(stackbase, newtop, tailcall)) return false;
-
- ci->_closure = closure;
- ci->_literals = func->_literals;
- ci->_ip = func->_instructions;
- ci->_target = (SQInt32)target;
-
- if (_debughook) {
- CallDebugHook(_SC('c'));
- }
-
- if (closure->_function->_bgenerator) {
- SQFunctionProto *f = closure->_function;
- SQGenerator *gen = SQGenerator::Create(_ss(this), closure);
- if(!gen->Yield(this,f->_stacksize))
- return false;
- SQObjectPtr temp;
- Return(1, target, temp);
- STK(target) = gen;
- }
-
-
- return true;
-}
-
-bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval)
-{
- SQBool _isroot = ci->_root;
- SQInteger callerbase = _stackbase - ci->_prevstkbase;
-
- if (_debughook) {
- for(SQInteger i=0; i<ci->_ncalls; i++) {
- CallDebugHook(_SC('r'));
- }
- }
-
- SQObjectPtr *dest;
- if (_isroot) {
- dest = &(retval);
- } else if (ci->_target == -1) {
- dest = NULL;
- } else {
- dest = &_stack._vals[callerbase + ci->_target];
- }
- if (dest) {
- if(_arg0 != 0xFF) {
- *dest = _stack._vals[_stackbase+_arg1];
- }
- else {
- dest->Null();
- }
- //*dest = (_arg0 != 0xFF) ? _stack._vals[_stackbase+_arg1] : _null_;
- }
- LeaveFrame();
- return _isroot ? true : false;
-}
-
-#define _RET_ON_FAIL(exp) { if(!exp) return false; }
-
-bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)
-{
- SQObjectPtr trg;
- _RET_ON_FAIL(ARITH_OP( op , trg, a, incr));
- target = a;
- a = trg;
- return true;
-}
-
-bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger selfidx)
-{
- SQObjectPtr tmp, tself = self, tkey = key;
- if (!Get(tself, tkey, tmp, false, selfidx)) { return false; }
- _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr))
- if (!Set(tself, tkey, target,selfidx)) { return false; }
- if (postfix) target = tmp;
- return true;
-}
-
-#define arg0 (_i_._arg0)
-#define sarg0 ((SQInteger)*((signed char *)&_i_._arg0))
-#define arg1 (_i_._arg1)
-#define sarg1 (*((SQInt32 *)&_i_._arg1))
-#define arg2 (_i_._arg2)
-#define arg3 (_i_._arg3)
-#define sarg3 ((SQInteger)*((signed char *)&_i_._arg3))
-
-SQRESULT SQVM::Suspend()
-{
- if (_suspended)
- return sq_throwerror(this, _SC("cannot suspend an already suspended vm"));
- if (_nnativecalls!=2)
- return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods"));
- return SQ_SUSPEND_FLAG;
-}
-
-
-#define _FINISH(howmuchtojump) {jump = howmuchtojump; return true; }
-bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr
-&o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump)
-{
- SQInteger nrefidx;
- switch(type(o1)) {
- case OT_TABLE:
- if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(exitpos);
- o4 = (SQInteger)nrefidx; _FINISH(1);
- case OT_ARRAY:
- if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(exitpos);
- o4 = (SQInteger) nrefidx; _FINISH(1);
- case OT_STRING:
- if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos);
- o4 = (SQInteger)nrefidx; _FINISH(1);
- case OT_CLASS:
- if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos);
- o4 = (SQInteger)nrefidx; _FINISH(1);
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o1)->_delegate) {
- SQObjectPtr itr;
- SQObjectPtr closure;
- if(_delegable(o1)->GetMetaMethod(this, MT_NEXTI, closure)) {
- Push(o1);
- Push(o4);
- if(CallMetaMethod(closure, MT_NEXTI, 2, itr)) {
- o4 = o2 = itr;
- if(type(itr) == OT_NULL) _FINISH(exitpos);
- if(!Get(o1, itr, o3, false, DONT_FALL_BACK)) {
- Raise_Error(_SC("_nexti returned an invalid idx")); // cloud be changed
- return false;
- }
- _FINISH(1);
- }
- else {
- return false;
- }
- }
- Raise_Error(_SC("_nexti failed"));
- return false;
- }
- break;
- case OT_GENERATOR:
- if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(exitpos);
- if(_generator(o1)->_state == SQGenerator::eSuspended) {
- SQInteger idx = 0;
- if(type(o4) == OT_INTEGER) {
- idx = _integer(o4) + 1;
- }
- o2 = idx;
- o4 = idx;
- _generator(o1)->Resume(this, o3);
- _FINISH(0);
- }
- default:
- Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1));
- }
- return false; //cannot be hit(just to avoid warnings)
-}
-
-#define COND_LITERAL (arg3!=0?ci->_literals[arg1]:STK(arg1))
-
-#define SQ_THROW() { goto exception_trap; }
-
-#define _GUARD(exp) { if(!exp) { SQ_THROW();} }
-
-bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func)
-{
- SQInteger nouters;
- SQClosure *closure = SQClosure::Create(_ss(this), func);
- if((nouters = func->_noutervalues)) {
- for(SQInteger i = 0; i<nouters; i++) {
- SQOuterVar &v = func->_outervalues[i];
- switch(v._type){
- case otLOCAL:
- FindOuter(closure->_outervalues[i], &STK(_integer(v._src)));
- break;
- case otOUTER:
- closure->_outervalues[i] = _closure(ci->_closure)->_outervalues[_integer(v._src)];
- break;
- }
- }
- }
- SQInteger ndefparams;
- if((ndefparams = func->_ndefaultparams)) {
- for(SQInteger i = 0; i < ndefparams; i++) {
- SQInteger spos = func->_defaultparams[i];
- closure->_defaultparams[i] = _stack._vals[_stackbase + spos];
- }
- }
- target = closure;
- return true;
-
-}
-
-
-bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes)
-{
- SQClass *base = NULL;
- SQObjectPtr attrs;
- if(baseclass != -1) {
- if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; }
- base = _class(_stack._vals[_stackbase + baseclass]);
- }
- if(attributes != MAX_FUNC_STACKSIZE) {
- attrs = _stack._vals[_stackbase+attributes];
- }
- target = SQClass::Create(_ss(this),base);
- if(type(_class(target)->_metamethods[MT_INHERITED]) != OT_NULL) {
- int nparams = 2;
- SQObjectPtr ret;
- Push(target); Push(attrs);
- Call(_class(target)->_metamethods[MT_INHERITED],nparams,_top - nparams, ret, false);
- Pop(nparams);
- }
- _class(target)->_attributes = attrs;
- return true;
-}
-
-bool SQVM::IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res)
-{
- if(type(o1) == type(o2)) {
- res = (_rawval(o1) == _rawval(o2));
- }
- else {
- if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
- res = (tofloat(o1) == tofloat(o2));
- }
- else {
- res = false;
- }
- }
- return true;
-}
-
-bool SQVM::IsFalse(SQObjectPtr &o)
-{
- if(((type(o) & SQOBJECT_CANBEFALSE)
- && ( ((type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0))) ))
-#if !defined(SQUSEDOUBLE) || (defined(SQUSEDOUBLE) && defined(_SQ64))
- || (_integer(o) == 0) ) //OT_NULL|OT_INTEGER|OT_BOOL
-#else
- || (((type(o) != OT_FLOAT) && (_integer(o) == 0))) ) //OT_NULL|OT_INTEGER|OT_BOOL
-#endif
- {
- return true;
- }
- return false;
-}
-
-bool SQVM::Execute(SQObjectPtr &closure, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, SQBool raiseerror,ExecutionType et)
-{
- if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }
- _nnativecalls++;
- AutoDec ad(&_nnativecalls);
- SQInteger traps = 0;
- CallInfo *prevci = ci;
-
- switch(et) {
- case ET_CALL: {
- temp_reg = closure;
- if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) {
- //call the handler if there are no calls in the stack, if not relies on the previous node
- if(ci == NULL) CallErrorHandler(_lasterror);
- return false;
- }
- if(ci == prevci) {
- outres = STK(_top-nargs);
- return true;
- }
- ci->_root = SQTrue;
- }
- break;
- case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, outres); ci->_root = SQTrue; traps += ci->_etraps; break;
- case ET_RESUME_VM:
- case ET_RESUME_THROW_VM:
- traps = _suspended_traps;
- ci->_root = _suspended_root;
- _suspended = SQFalse;
- if(et == ET_RESUME_THROW_VM) { SQ_THROW(); }
- break;
- }
-
-exception_restore:
- //
- {
- for(;;)
- {
- const SQInstruction &_i_ = *ci->_ip++;
- //dumpstack(_stackbase);
- //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-ci->_iv->_vals,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3);
- switch(_i_.op)
- {
- case _OP_LINE: if (_debughook) CallDebugHook(_SC('l'),arg1); continue;
- case _OP_LOAD: TARGET = ci->_literals[arg1]; continue;
- case _OP_LOADINT:
-#ifndef _SQ64
- TARGET = (SQInteger)arg1; continue;
-#else
- TARGET = (SQInteger)((SQUnsignedInteger32)arg1); continue;
-#endif
- case _OP_LOADFLOAT: TARGET = *((SQFloat *)&arg1); continue;
- case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;
- case _OP_TAILCALL:{
- SQObjectPtr &t = STK(arg1);
- if (type(t) == OT_CLOSURE
- && (!_closure(t)->_function->_bgenerator)){
- SQObjectPtr clo = t;
- if(_openouters) CloseOuters(&(_stack._vals[_stackbase]));
- for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i);
- _GUARD(StartCall(_closure(clo), ci->_target, arg3, _stackbase, true));
- continue;
- }
- }
- case _OP_CALL: {
- SQObjectPtr clo = STK(arg1);
- switch (type(clo)) {
- case OT_CLOSURE:
- _GUARD(StartCall(_closure(clo), sarg0, arg3, _stackbase+arg2, false));
- continue;
- case OT_NATIVECLOSURE: {
- bool suspend;
- _GUARD(CallNative(_nativeclosure(clo), arg3, _stackbase+arg2, clo,suspend));
- if(suspend){
- _suspended = SQTrue;
- _suspended_target = sarg0;
- _suspended_root = ci->_root;
- _suspended_traps = traps;
- outres = clo;
- return true;
- }
- if(sarg0 != -1) {
- STK(arg0) = clo;
- }
- }
- continue;
- case OT_CLASS:{
- SQObjectPtr inst;
- _GUARD(CreateClassInstance(_class(clo),inst,clo));
- if(sarg0 != -1) {
- STK(arg0) = inst;
- }
- SQInteger stkbase;
- switch(type(clo)) {
- case OT_CLOSURE:
- stkbase = _stackbase+arg2;
- _stack._vals[stkbase] = inst;
- _GUARD(StartCall(_closure(clo), -1, arg3, stkbase, false));
- break;
- case OT_NATIVECLOSURE:
- bool suspend;
- stkbase = _stackbase+arg2;
- _stack._vals[stkbase] = inst;
- _GUARD(CallNative(_nativeclosure(clo), arg3, stkbase, clo,suspend));
- break;
- default: break; //shutup GCC 4.x
- }
- }
- break;
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:{
- SQObjectPtr closure;
- if(_delegable(clo)->_delegate && _delegable(clo)->GetMetaMethod(this,MT_CALL,closure)) {
- Push(clo);
- for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i));
- if(!CallMetaMethod(closure, MT_CALL, arg3+1, clo)) SQ_THROW();
- if(sarg0 != -1) {
- STK(arg0) = clo;
- }
- break;
- }
-
- //Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo));
- //SQ_THROW();
- }
- default:
- Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo));
- SQ_THROW();
- }
- }
- continue;
- case _OP_PREPCALL:
- case _OP_PREPCALLK: {
- SQObjectPtr &key = _i_.op == _OP_PREPCALLK?(ci->_literals)[arg1]:STK(arg1);
- SQObjectPtr &o = STK(arg2);
- if (!Get(o, key, temp_reg,false,arg2)) {
- SQ_THROW();
- }
- STK(arg3) = o;
- _Swap(TARGET,temp_reg);//TARGET = temp_reg;
- }
- continue;
- case _OP_GETK:
- if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, false,arg2)) { SQ_THROW();}
- _Swap(TARGET,temp_reg);//TARGET = temp_reg;
- continue;
- case _OP_MOVE: TARGET = STK(arg1); continue;
- case _OP_NEWSLOT:
- _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),false));
- if(arg0 != 0xFF) TARGET = STK(arg3);
- continue;
- case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue;
- case _OP_SET:
- if (!Set(STK(arg1), STK(arg2), STK(arg3),arg1)) { SQ_THROW(); }
- if (arg0 != 0xFF) TARGET = STK(arg3);
- continue;
- case _OP_GET:
- if (!Get(STK(arg1), STK(arg2), temp_reg, false,arg1)) { SQ_THROW(); }
- _Swap(TARGET,temp_reg);//TARGET = temp_reg;
- continue;
- case _OP_EQ:{
- bool res;
- if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
- TARGET = res?true:false;
- }continue;
- case _OP_NE:{
- bool res;
- if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
- TARGET = (!res)?true:false;
- } continue;
- case _OP_ADD: _ARITH_(+,TARGET,STK(arg2),STK(arg1)); continue;
- case _OP_SUB: _ARITH_(-,TARGET,STK(arg2),STK(arg1)); continue;
- case _OP_MUL: _ARITH_(*,TARGET,STK(arg2),STK(arg1)); continue;
- case _OP_DIV: _ARITH_NOZERO(/,TARGET,STK(arg2),STK(arg1),_SC("division by zero")); continue;
- case _OP_MOD: ARITH_OP('%',TARGET,STK(arg2),STK(arg1)); continue;
- case _OP_BITW: _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue;
- case _OP_RETURN:
- if((ci)->_generator) {
- (ci)->_generator->Kill();
- }
- if(Return(arg0, arg1, temp_reg)){
- assert(traps==0);
- //outres = temp_reg;
- _Swap(outres,temp_reg);
- return true;
- }
- continue;
- case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n).Null(); }continue;
- case _OP_LOADROOT: TARGET = _roottable; continue;
- case _OP_LOADBOOL: TARGET = arg1?true:false; continue;
- case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue;
- case _OP_JMP: ci->_ip += (sarg1); continue;
- //case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;
- case _OP_JCMP:
- _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg0),temp_reg));
- if(IsFalse(temp_reg)) ci->_ip+=(sarg1);
- continue;
- case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;
- case _OP_GETOUTER: {
- SQClosure *cur_cls = _closure(ci->_closure);
- SQOuter *otr = _outer(cur_cls->_outervalues[arg1]);
- TARGET = *(otr->_valptr);
- }
- continue;
- case _OP_SETOUTER: {
- SQClosure *cur_cls = _closure(ci->_closure);
- SQOuter *otr = _outer(cur_cls->_outervalues[arg1]);
- *(otr->_valptr) = STK(arg2);
- if(arg0 != 0xFF) {
- TARGET = STK(arg2);
- }
- }
- continue;
- case _OP_NEWOBJ:
- switch(arg3) {
- case NOT_TABLE: TARGET = SQTable::Create(_ss(this), arg1); continue;
- case NOT_ARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue;
- case NOT_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue;
- default: assert(0); continue;
- }
- case _OP_APPENDARRAY:
- {
- SQObject val;
- val._unVal.raw = 0;
- switch(arg2) {
- case AAT_STACK:
- val = STK(arg1); break;
- case AAT_LITERAL:
- val = ci->_literals[arg1]; break;
- case AAT_INT:
- val._type = OT_INTEGER;
-#ifndef _SQ64
- val._unVal.nInteger = (SQInteger)arg1;
-#else
- val._unVal.nInteger = (SQInteger)((SQUnsignedInteger32)arg1);
-#endif
- break;
- case AAT_FLOAT:
- val._type = OT_FLOAT;
- val._unVal.fFloat = *((SQFloat *)&arg1);
- break;
- case AAT_BOOL:
- val._type = OT_BOOL;
- val._unVal.nInteger = arg1;
- break;
- default: assert(0); break;
-
- }
- _array(STK(arg0))->Append(val); continue;
- }
- case _OP_COMPARITH: {
- SQInteger selfidx = (((SQUnsignedInteger)arg1&0xFFFF0000)>>16);
- _GUARD(DerefInc(arg3, TARGET, STK(selfidx), STK(arg2), STK(arg1&0x0000FFFF), false, selfidx));
- }
- continue;
- case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false, arg1));} continue;
- case _OP_INCL: {
- SQObjectPtr &a = STK(arg1);
- if(type(a) == OT_INTEGER) {
- a._unVal.nInteger = _integer(a) + sarg3;
- }
- else {
- SQObjectPtr o(sarg3); //_GUARD(LOCAL_INC('+',TARGET, STK(arg1), o));
- _ARITH_(+,a,a,o);
- }
- } continue;
- case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true, arg1));} continue;
- case _OP_PINCL: {
- SQObjectPtr &a = STK(arg1);
- if(type(a) == OT_INTEGER) {
- TARGET = a;
- a._unVal.nInteger = _integer(a) + sarg3;
- }
- else {
- SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o));
- }
-
- } continue;
- case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) continue;
- case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, true,DONT_FALL_BACK)?true:false;continue;
- case _OP_INSTANCEOF:
- if(type(STK(arg1)) != OT_CLASS)
- {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();}
- TARGET = (type(STK(arg2)) == OT_INSTANCE) ? (_instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?true:false) : false;
- continue;
- case _OP_AND:
- if(IsFalse(STK(arg2))) {
- TARGET = STK(arg2);
- ci->_ip += (sarg1);
- }
- continue;
- case _OP_OR:
- if(!IsFalse(STK(arg2))) {
- TARGET = STK(arg2);
- ci->_ip += (sarg1);
- }
- continue;
- case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue;
- case _OP_NOT: TARGET = IsFalse(STK(arg1)); continue;
- case _OP_BWNOT:
- if(type(STK(arg1)) == OT_INTEGER) {
- SQInteger t = _integer(STK(arg1));
- TARGET = SQInteger(~t);
- continue;
- }
- Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1)));
- SQ_THROW();
- case _OP_CLOSURE: {
- SQClosure *c = ci->_closure._unVal.pClosure;
- SQFunctionProto *fp = c->_function;
- if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); }
- continue;
- }
- case _OP_YIELD:{
- if(ci->_generator) {
- if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1);
- _GUARD(ci->_generator->Yield(this,arg2));
- traps -= ci->_etraps;
- if(sarg1 != MAX_FUNC_STACKSIZE) _Swap(STK(arg1),temp_reg);//STK(arg1) = temp_reg;
- }
- else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();}
- if(Return(arg0, arg1, temp_reg)){
- assert(traps == 0);
- outres = temp_reg;
- return true;
- }
-
- }
- continue;
- case _OP_RESUME:
- if(type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();}
- _GUARD(_generator(STK(arg1))->Resume(this, TARGET));
- traps += ci->_etraps;
- continue;
- case _OP_FOREACH:{ int tojump;
- _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,sarg1,tojump));
- ci->_ip += tojump; }
- continue;
- case _OP_POSTFOREACH:
- assert(type(STK(arg0)) == OT_GENERATOR);
- if(_generator(STK(arg0))->_state == SQGenerator::eDead)
- ci->_ip += (sarg1 - 1);
- continue;
- case _OP_CLONE: _GUARD(Clone(STK(arg1), TARGET)); continue;
- case _OP_TYPEOF: _GUARD(TypeOf(STK(arg1), TARGET)) continue;
- case _OP_PUSHTRAP:{
- SQInstruction *_iv = _closure(ci->_closure)->_function->_instructions;
- _etraps.push_back(SQExceptionTrap(_top,_stackbase, &_iv[(ci->_ip-_iv)+arg1], arg0)); traps++;
- ci->_etraps++;
- }
- continue;
- case _OP_POPTRAP: {
- for(SQInteger i = 0; i < arg0; i++) {
- _etraps.pop_back(); traps--;
- ci->_etraps--;
- }
- }
- continue;
- case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue;
- case _OP_NEWSLOTA: {
- bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG)?true:false;
- if(type(STK(arg1)) == OT_CLASS) {
- if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) {
- Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3));
- Push((arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : SQObjectPtr());
- Push(bstatic);
- int nparams = 5;
- if(Call(_class(STK(arg1))->_metamethods[MT_NEWMEMBER], nparams, _top - nparams, temp_reg,SQFalse)) {
- Pop(nparams);
- continue;
- }
- else {
- SQ_THROW();
- }
- }
- }
- _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),bstatic));
- if((arg0&NEW_SLOT_ATTRIBUTES_FLAG)) {
- _class(STK(arg1))->SetAttributes(STK(arg2),STK(arg2-1));
- }
- }
- continue;
- case _OP_GETBASE:{
- SQClosure *clo = _closure(ci->_closure);
- if(clo->_base) {
- TARGET = clo->_base;
- }
- else {
- TARGET.Null();
- }
- continue;
- }
- case _OP_CLOSE:
- if(_openouters) CloseOuters(&(STK(arg1)));
- continue;
- }
-
- }
- }
-exception_trap:
- {
- SQObjectPtr currerror = _lasterror;
-// dumpstack(_stackbase);
-// SQInteger n = 0;
- SQInteger last_top = _top;
-
- if(_ss(this)->_notifyallexceptions || (!traps && raiseerror)) CallErrorHandler(currerror);
-
- while( ci ) {
- if(ci->_etraps > 0) {
- SQExceptionTrap &et = _etraps.top();
- ci->_ip = et._ip;
- _top = et._stacksize;
- _stackbase = et._stackbase;
- _stack._vals[_stackbase + et._extarget] = currerror;
- _etraps.pop_back(); traps--; ci->_etraps--;
- while(last_top >= _top) _stack._vals[last_top--].Null();
- goto exception_restore;
- }
- else if (_debughook) {
- //notify debugger of a "return"
- //even if it really an exception unwinding the stack
- for(SQInteger i = 0; i < ci->_ncalls; i++) {
- CallDebugHook(_SC('r'));
- }
- }
- if(ci->_generator) ci->_generator->Kill();
- bool mustbreak = ci && ci->_root;
- LeaveFrame();
- if(mustbreak) break;
- }
-
- _lasterror = currerror;
- return false;
- }
- assert(0);
-}
-
-bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor)
-{
- inst = theclass->CreateInstance();
- if(!theclass->GetConstructor(constructor)) {
- constructor.Null();
- }
- return true;
-}
-
-void SQVM::CallErrorHandler(SQObjectPtr &error)
-{
- if(type(_errorhandler) != OT_NULL) {
- SQObjectPtr out;
- Push(_roottable); Push(error);
- Call(_errorhandler, 2, _top-2, out,SQFalse);
- Pop(2);
- }
-}
-
-
-void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline)
-{
- _debughook = false;
- SQFunctionProto *func=_closure(ci->_closure)->_function;
- if(_debughook_native) {
- const SQChar *src = type(func->_sourcename) == OT_STRING?_stringval(func->_sourcename):NULL;
- const SQChar *fname = type(func->_name) == OT_STRING?_stringval(func->_name):NULL;
- SQInteger line = forcedline?forcedline:func->GetLine(ci->_ip);
- _debughook_native(this,type,src,line,fname);
- }
- else {
- SQObjectPtr temp_reg;
- SQInteger nparams=5;
- Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name);
- Call(_debughook_closure,nparams,_top-nparams,temp_reg,SQFalse);
- Pop(nparams);
- }
- _debughook = true;
-}
-
-bool SQVM::CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval, bool &suspend)
-{
- SQInteger nparamscheck = nclosure->_nparamscheck;
- SQInteger newtop = newbase + nargs + nclosure->_noutervalues;
-
- if (_nnativecalls + 1 > MAX_NATIVE_CALLS) {
- Raise_Error(_SC("Native stack overflow"));
- return false;
- }
-
- if(nparamscheck && (((nparamscheck > 0) && (nparamscheck != nargs)) ||
- ((nparamscheck < 0) && (nargs < (-nparamscheck)))))
- {
- Raise_Error(_SC("wrong number of parameters"));
- return false;
- }
-
- SQInteger tcs;
- SQIntVec &tc = nclosure->_typecheck;
- if((tcs = tc.size())) {
- for(SQInteger i = 0; i < nargs && i < tcs; i++) {
- if((tc._vals[i] != -1) && !(type(_stack._vals[newbase+i]) & tc._vals[i])) {
- Raise_ParamTypeError(i,tc._vals[i],type(_stack._vals[newbase+i]));
- return false;
- }
- }
- }
-
- if(!EnterFrame(newbase, newtop, false)) return false;
- ci->_closure = nclosure;
-
- SQInteger outers = nclosure->_noutervalues;
- for (SQInteger i = 0; i < outers; i++) {
- _stack._vals[newbase+nargs+i] = nclosure->_outervalues[i];
- }
- if(nclosure->_env) {
- _stack._vals[newbase] = nclosure->_env->_obj;
- }
-
- _nnativecalls++;
- SQInteger ret = (nclosure->_function)(this);
- _nnativecalls--;
-
- suspend = false;
- if (ret == SQ_SUSPEND_FLAG) {
- suspend = true;
- }
- else if (ret < 0) {
- LeaveFrame();
- Raise_Error(_lasterror);
- return false;
- }
- if(ret) {
- retval = _stack._vals[_top-1];
- }
- else {
- retval.Null();
- }
- //retval = ret ? _stack._vals[_top-1] : _null_;
- LeaveFrame();
- return true;
-}
-
-#define FALLBACK_OK 0
-#define FALLBACK_NO_MATCH 1
-#define FALLBACK_ERROR 2
-
-bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw, SQInteger selfidx)
-{
- switch(type(self)){
- case OT_TABLE:
- if(_table(self)->Get(key,dest))return true;
- break;
- case OT_ARRAY:
- if(sq_isnumeric(key)) { if(_array(self)->Get(tointeger(key),dest)) { return true; } Raise_IdxError(key); return false; }
- break;
- case OT_INSTANCE:
- if(_instance(self)->Get(key,dest)) return true;
- break;
- case OT_CLASS:
- if(_class(self)->Get(key,dest)) return true;
- break;
- case OT_STRING:
- if(sq_isnumeric(key)){
- SQInteger n = tointeger(key);
- if(abs((int)n) < _string(self)->_len) {
- if(n < 0) n = _string(self)->_len - n;
- dest = SQInteger(_stringval(self)[n]);
- return true;
- }
- Raise_IdxError(key);
- return false;
- }
- break;
- default:break; //shut up compiler
- }
- if(!raw) {
- switch(FallBackGet(self,key,dest)) {
- case FALLBACK_OK: return true; //okie
- case FALLBACK_NO_MATCH: break; //keep falling back
- case FALLBACK_ERROR: return false; // the metamethod failed
- }
- if(InvokeDefaultDelegate(self,key,dest)) {
- return true;
- }
- }
-//#ifdef ROOT_FALLBACK
- if(selfidx == 0) {
- if(_table(_roottable)->Get(key,dest)) return true;
- }
-//#endif
- Raise_IdxError(key);
- return false;
-}
-
-bool SQVM::InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest)
-{
- SQTable *ddel = NULL;
- switch(type(self)) {
- case OT_CLASS: ddel = _class_ddel; break;
- case OT_TABLE: ddel = _table_ddel; break;
- case OT_ARRAY: ddel = _array_ddel; break;
- case OT_STRING: ddel = _string_ddel; break;
- case OT_INSTANCE: ddel = _instance_ddel; break;
- case OT_INTEGER:case OT_FLOAT:case OT_BOOL: ddel = _number_ddel; break;
- case OT_GENERATOR: ddel = _generator_ddel; break;
- case OT_CLOSURE: case OT_NATIVECLOSURE: ddel = _closure_ddel; break;
- case OT_THREAD: ddel = _thread_ddel; break;
- case OT_WEAKREF: ddel = _weakref_ddel; break;
- default: return false;
- }
- return ddel->Get(key,dest);
-}
-
-
-SQInteger SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest)
-{
- switch(type(self)){
- case OT_TABLE:
- case OT_USERDATA:
- //delegation
- if(_delegable(self)->_delegate) {
- if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,false,DONT_FALL_BACK)) return FALLBACK_OK;
- }
- else {
- return FALLBACK_NO_MATCH;
- }
- //go through
- case OT_INSTANCE: {
- SQObjectPtr closure;
- if(_delegable(self)->GetMetaMethod(this, MT_GET, closure)) {
- Push(self);Push(key);
- _nmetamethodscall++;
- AutoDec ad(&_nmetamethodscall);
- if(Call(closure, 2, _top - 2, dest, SQFalse)) {
- Pop(2);
- return FALLBACK_OK;
- }
- else {
- if(type(_lasterror) != OT_NULL) { //NULL means "clean failure" (not found)
- //error
- Pop(2);
- return FALLBACK_ERROR;
- }
- }
- }
- }
- break;
- default: break;//shutup GCC 4.x
- }
- // no metamethod or no fallback type
- return FALLBACK_NO_MATCH;
-}
-
-bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,SQInteger selfidx)
-{
- switch(type(self)){
- case OT_TABLE:
- if(_table(self)->Set(key,val)) return true;
- break;
- case OT_INSTANCE:
- if(_instance(self)->Set(key,val)) return true;
- break;
- case OT_ARRAY:
- if(!sq_isnumeric(key)) { Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; }
- if(!_array(self)->Set(tointeger(key),val)) {
- Raise_IdxError(key);
- return false;
- }
- return true;
- default:
- Raise_Error(_SC("trying to set '%s'"),GetTypeName(self));
- return false;
- }
-
- switch(FallBackSet(self,key,val)) {
- case FALLBACK_OK: return true; //okie
- case FALLBACK_NO_MATCH: break; //keep falling back
- case FALLBACK_ERROR: return false; // the metamethod failed
- }
- if(selfidx == 0) {
- if(_table(_roottable)->Set(key,val))
- return true;
- }
- Raise_IdxError(key);
- return false;
-}
-
-SQInteger SQVM::FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val)
-{
- switch(type(self)) {
- case OT_TABLE:
- if(_table(self)->_delegate) {
- if(Set(_table(self)->_delegate,key,val,DONT_FALL_BACK)) return FALLBACK_OK;
- }
- //keps on going
- case OT_INSTANCE:
- case OT_USERDATA:{
- SQObjectPtr closure;
- SQObjectPtr t;
- if(_delegable(self)->GetMetaMethod(this, MT_SET, closure)) {
- Push(self);Push(key);Push(val);
- _nmetamethodscall++;
- AutoDec ad(&_nmetamethodscall);
- if(Call(closure, 3, _top - 3, t, SQFalse)) {
- Pop(3);
- return FALLBACK_OK;
- }
- else {
- if(type(_lasterror) != OT_NULL) { //NULL means "clean failure" (not found)
- //error
- Pop(3);
- return FALLBACK_ERROR;
- }
- }
- }
- }
- break;
- default: break;//shutup GCC 4.x
- }
- // no metamethod or no fallback type
- return FALLBACK_NO_MATCH;
-}
-
-bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target)
-{
- SQObjectPtr temp_reg;
- SQObjectPtr newobj;
- switch(type(self)){
- case OT_TABLE:
- newobj = _table(self)->Clone();
- goto cloned_mt;
- case OT_INSTANCE: {
- newobj = _instance(self)->Clone(_ss(this));
-cloned_mt:
- SQObjectPtr closure;
- if(_delegable(newobj)->_delegate && _delegable(newobj)->GetMetaMethod(this,MT_CLONED,closure)) {
- Push(newobj);
- Push(self);
- if(!CallMetaMethod(closure,MT_CLONED,2,temp_reg))
- return false;
- }
- }
- target = newobj;
- return true;
- case OT_ARRAY:
- target = _array(self)->Clone();
- return true;
- default:
- Raise_Error(_SC("cloning a %s"), GetTypeName(self));
- return false;
- }
-}
-
-bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
-{
- if(type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; }
- switch(type(self)) {
- case OT_TABLE: {
- bool rawcall = true;
- if(_table(self)->_delegate) {
- SQObjectPtr res;
- if(!_table(self)->Get(key,res)) {
- SQObjectPtr closure;
- if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_NEWSLOT,closure)) {
- Push(self);Push(key);Push(val);
- if(!CallMetaMethod(closure,MT_NEWSLOT,3,res)) {
- return false;
- }
- rawcall = false;
- }
- else {
- rawcall = true;
- }
- }
- }
- if(rawcall) _table(self)->NewSlot(key,val); //cannot fail
-
- break;}
- case OT_INSTANCE: {
- SQObjectPtr res;
- SQObjectPtr closure;
- if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_NEWSLOT,closure)) {
- Push(self);Push(key);Push(val);
- if(!CallMetaMethod(closure,MT_NEWSLOT,3,res)) {
- return false;
- }
- break;
- }
- Raise_Error(_SC("class instances do not support the new slot operator"));
- return false;
- break;}
- case OT_CLASS:
- if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) {
- if(_class(self)->_locked) {
- Raise_Error(_SC("trying to modify a class that has already been instantiated"));
- return false;
- }
- else {
- SQObjectPtr oval = PrintObjVal(key);
- Raise_Error(_SC("the property '%s' already exists"),_stringval(oval));
- return false;
- }
- }
- break;
- default:
- Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key));
- return false;
- break;
- }
- return true;
-}
-
-
-
-bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res)
-{
- switch(type(self)) {
- case OT_TABLE:
- case OT_INSTANCE:
- case OT_USERDATA: {
- SQObjectPtr t;
- //bool handled = false;
- SQObjectPtr closure;
- if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_DELSLOT,closure)) {
- Push(self);Push(key);
- return CallMetaMethod(closure,MT_DELSLOT,2,res);
- }
- else {
- if(type(self) == OT_TABLE) {
- if(_table(self)->Get(key,t)) {
- _table(self)->Remove(key);
- }
- else {
- Raise_IdxError((SQObject &)key);
- return false;
- }
- }
- else {
- Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self));
- return false;
- }
- }
- res = t;
- }
- break;
- default:
- Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self));
- return false;
- }
- return true;
-}
-
-bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror)
-{
-#ifdef _DEBUG
-SQInteger prevstackbase = _stackbase;
-#endif
- switch(type(closure)) {
- case OT_CLOSURE:
- return Execute(closure, nparams, stackbase, outres, raiseerror);
- break;
- case OT_NATIVECLOSURE:{
- bool suspend;
- return CallNative(_nativeclosure(closure), nparams, stackbase, outres,suspend);
-
- }
- break;
- case OT_CLASS: {
- SQObjectPtr constr;
- SQObjectPtr temp;
- CreateClassInstance(_class(closure),outres,constr);
- if(type(constr) != OT_NULL) {
- _stack[stackbase] = outres;
- return Call(constr,nparams,stackbase,temp,raiseerror);
- }
- return true;
- }
- break;
- default:
- return false;
- }
-#ifdef _DEBUG
- if(!_suspended) {
- assert(_stackbase == prevstackbase);
- }
-#endif
- return true;
-}
-
-bool SQVM::CallMetaMethod(SQObjectPtr &closure,SQMetaMethod mm,SQInteger nparams,SQObjectPtr &outres)
-{
- //SQObjectPtr closure;
-
- _nmetamethodscall++;
- if(Call(closure, nparams, _top - nparams, outres, SQFalse)) {
- _nmetamethodscall--;
- Pop(nparams);
- return true;
- }
- _nmetamethodscall--;
- //}
- Pop(nparams);
- return false;
-}
-
-void SQVM::FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex)
-{
- SQOuter **pp = &_openouters;
- SQOuter *p;
- SQOuter *otr;
-
- while ((p = *pp) != NULL && p->_valptr >= stackindex) {
- if (p->_valptr == stackindex) {
- target = SQObjectPtr(p);
- return;
- }
- pp = &p->_next;
- }
- otr = SQOuter::Create(_ss(this), stackindex);
- otr->_next = *pp;
- otr->_idx = (stackindex - _stack._vals);
- __ObjAddRef(otr);
- *pp = otr;
- target = SQObjectPtr(otr);
-}
-
-bool SQVM::EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall)
-{
- if( !tailcall ) {
- if( _callsstacksize == _alloccallsstacksize ) {
- GrowCallStack();
- }
- ci = &_callsstack[_callsstacksize++];
- ci->_prevstkbase = (SQInt32)(newbase - _stackbase);
- ci->_prevtop = (SQInt32)(_top - _stackbase);
- ci->_etraps = 0;
- ci->_ncalls = 1;
- ci->_generator = NULL;
- ci->_root = SQFalse;
- }
- else {
- ci->_ncalls++;
- }
-
- _stackbase = newbase;
- _top = newtop;
- if(newtop + MIN_STACK_OVERHEAD > (SQInteger)_stack.size()) {
- if(_nmetamethodscall) {
- Raise_Error(_SC("stack overflow, cannot resize stack while in a metamethod"));
- return false;
- }
- _stack.resize(_stack.size() + (MIN_STACK_OVERHEAD << 2));
- RelocateOuters();
- }
- return true;
-}
-
-void SQVM::LeaveFrame() {
- SQInteger last_top = _top;
- SQInteger last_stackbase = _stackbase;
- SQInteger css = --_callsstacksize;
-
- /* First clean out the call stack frame */
- ci->_closure.Null();
- _stackbase -= ci->_prevstkbase;
- _top = _stackbase + ci->_prevtop;
- ci = (css) ? &_callsstack[css-1] : NULL;
-
- if(_openouters) CloseOuters(&(_stack._vals[last_stackbase]));
- while (last_top >= _top) {
- _stack._vals[last_top--].Null();
- }
-}
-
-void SQVM::RelocateOuters()
-{
- SQOuter *p = _openouters;
- while (p) {
- p->_valptr = _stack._vals + p->_idx;
- p = p->_next;
- }
-}
-
-void SQVM::CloseOuters(SQObjectPtr *stackindex) {
- SQOuter *p;
- while ((p = _openouters) != NULL && p->_valptr >= stackindex) {
- p->_value = *(p->_valptr);
- p->_valptr = &p->_value;
- _openouters = p->_next;
- __ObjRelease(p);
- }
-}
-
-void SQVM::Remove(SQInteger n) {
- n = (n >= 0)?n + _stackbase - 1:_top + n;
- for(SQInteger i = n; i < _top; i++){
- _stack[i] = _stack[i+1];
- }
- _stack[_top].Null();
- _top--;
-}
-
-void SQVM::Pop() {
- _stack[--_top].Null();
-}
-
-void SQVM::Pop(SQInteger n) {
- for(SQInteger i = 0; i < n; i++){
- _stack[--_top].Null();
- }
-}
-
-void SQVM::PushNull() { _stack[_top++].Null(); }
-void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; }
-SQObjectPtr &SQVM::Top() { return _stack[_top-1]; }
-SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; }
-SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; }
-SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; }
-
-#ifdef _DEBUG_DUMP
-void SQVM::dumpstack(SQInteger stackbase,bool dumpall)
-{
- SQInteger size=dumpall?_stack.size():_top;
- SQInteger n=0;
- scprintf(_SC("\n>>>>stack dump<<<<\n"));
- CallInfo &ci=_callsstack[_callsstacksize-1];
- scprintf(_SC("IP: %p\n"),ci._ip);
- scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase);
- scprintf(_SC("prev top: %d\n"),ci._prevtop);
- for(SQInteger i=0;i<size;i++){
- SQObjectPtr &obj=_stack[i];
- if(stackbase==i)scprintf(_SC(">"));else scprintf(_SC(" "));
- scprintf(_SC("[%d]:"),n);
- switch(type(obj)){
- case OT_FLOAT: scprintf(_SC("FLOAT %.3f"),_float(obj));break;
- case OT_INTEGER: scprintf(_SC("INTEGER %d"),_integer(obj));break;
- case OT_BOOL: scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break;
- case OT_STRING: scprintf(_SC("STRING %s"),_stringval(obj));break;
- case OT_NULL: scprintf(_SC("NULL")); break;
- case OT_TABLE: scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break;
- case OT_ARRAY: scprintf(_SC("ARRAY %p"),_array(obj));break;
- case OT_CLOSURE: scprintf(_SC("CLOSURE [%p]"),_closure(obj));break;
- case OT_NATIVECLOSURE: scprintf(_SC("NATIVECLOSURE"));break;
- case OT_USERDATA: scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break;
- case OT_GENERATOR: scprintf(_SC("GENERATOR %p"),_generator(obj));break;
- case OT_THREAD: scprintf(_SC("THREAD [%p]"),_thread(obj));break;
- case OT_USERPOINTER: scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break;
- case OT_CLASS: scprintf(_SC("CLASS %p"),_class(obj));break;
- case OT_INSTANCE: scprintf(_SC("INSTANCE %p"),_instance(obj));break;
- case OT_WEAKREF: scprintf(_SC("WEAKERF %p"),_weakref(obj));break;
- default:
- assert(0);
- break;
- };
- scprintf(_SC("\n"));
- ++n;
- }
-}
-
-
-
-#endif
+/* + see copyright notice in squirrel.h +*/ +#include "sqpcheader.h" +#include <math.h> +#include <stdlib.h> +#include "sqopcodes.h" +#include "sqvm.h" +#include "sqfuncproto.h" +#include "sqclosure.h" +#include "sqstring.h" +#include "sqtable.h" +#include "squserdata.h" +#include "sqarray.h" +#include "sqclass.h" + +#define TOP() (_stack._vals[_top-1]) + +bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) +{ + SQInteger res; + if((type(o1)|type(o2)) == OT_INTEGER) + { + SQInteger i1 = _integer(o1), i2 = _integer(o2); + switch(op) { + case BW_AND: res = i1 & i2; break; + case BW_OR: res = i1 | i2; break; + case BW_XOR: res = i1 ^ i2; break; + case BW_SHIFTL: res = i1 << i2; break; + case BW_SHIFTR: res = i1 >> i2; break; + case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break; + default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; } + } + } + else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;} + trg = res; + return true; +} + +#define _ARITH_(op,trg,o1,o2) \ +{ \ + SQInteger tmask = type(o1)|type(o2); \ + switch(tmask) { \ + case OT_INTEGER: trg = _integer(o1) op _integer(o2);break; \ + case (OT_FLOAT|OT_INTEGER): \ + case (OT_FLOAT): trg = tofloat(o1) op tofloat(o2); break;\ + default: _GUARD(ARITH_OP((#op)[0],trg,o1,o2)); break;\ + } \ +} + +#define _ARITH_NOZERO(op,trg,o1,o2,err) \ +{ \ + SQInteger tmask = type(o1)|type(o2); \ + switch(tmask) { \ + case OT_INTEGER: { SQInteger i2 = _integer(o2); if(i2 == 0) { Raise_Error(err); SQ_THROW(); } trg = _integer(o1) op i2; } break;\ + case (OT_FLOAT|OT_INTEGER): \ + case (OT_FLOAT): trg = tofloat(o1) op tofloat(o2); break;\ + default: _GUARD(ARITH_OP((#op)[0],trg,o1,o2)); break;\ + } \ +} + +bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) +{ + SQInteger tmask = type(o1)|type(o2); + switch(tmask) { + case OT_INTEGER:{ + SQInteger res, i1 = _integer(o1), i2 = _integer(o2); + switch(op) { + case '+': res = i1 + i2; break; + case '-': res = i1 - i2; break; + case '/': if(i2 == 0) { Raise_Error(_SC("division by zero")); return false; } + res = i1 / i2; + break; + case '*': res = i1 * i2; break; + case '%': if(i2 == 0) { Raise_Error(_SC("modulo by zero")); return false; } + res = i1 % i2; + break; + default: res = 0xDEADBEEF; + } + trg = res; } + break; + case (OT_FLOAT|OT_INTEGER): + case (OT_FLOAT):{ + SQFloat res, f1 = tofloat(o1), f2 = tofloat(o2); + switch(op) { + case '+': res = f1 + f2; break; + case '-': res = f1 - f2; break; + case '/': res = f1 / f2; break; + case '*': res = f1 * f2; break; + case '%': res = SQFloat(fmod((double)f1,(double)f2)); break; + default: res = 0x0f; + } + trg = res; } + break; + default: + if(op == '+' && (tmask & _RT_STRING)){ + if(!StringCat(o1, o2, trg)) return false; + } + else if(!ArithMetaMethod(op,o1,o2,trg)) { + return false; + } + } + return true; +} + +SQVM::SQVM(SQSharedState *ss) +{ + _sharedstate=ss; + _suspended = SQFalse; + _suspended_target = -1; + _suspended_root = SQFalse; + _suspended_traps = -1; + _foreignptr = NULL; + _nnativecalls = 0; + _nmetamethodscall = 0; + _lasterror.Null(); + _errorhandler.Null(); + _debughook = false; + _debughook_native = NULL; + _debughook_closure.Null(); + _openouters = NULL; + ci = NULL; + INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); +} + +void SQVM::Finalize() +{ + if(_openouters) CloseOuters(&_stack._vals[0]); + _roottable.Null(); + _lasterror.Null(); + _errorhandler.Null(); + _debughook = false; + _debughook_native = NULL; + _debughook_closure.Null(); + temp_reg.Null(); + _callstackdata.resize(0); + SQInteger size=_stack.size(); + for(SQInteger i=0;i<size;i++) + _stack[i].Null(); +} + +SQVM::~SQVM() +{ + Finalize(); + REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); +} + +bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest) +{ + SQMetaMethod mm; + switch(op){ + case _SC('+'): mm=MT_ADD; break; + case _SC('-'): mm=MT_SUB; break; + case _SC('/'): mm=MT_DIV; break; + case _SC('*'): mm=MT_MUL; break; + case _SC('%'): mm=MT_MODULO; break; + default: mm = MT_ADD; assert(0); break; //shutup compiler + } + if(is_delegable(o1) && _delegable(o1)->_delegate) { + + SQObjectPtr closure; + if(_delegable(o1)->GetMetaMethod(this, mm, closure)) { + Push(o1);Push(o2); + return CallMetaMethod(closure,mm,2,dest); + } + } + Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); + return false; +} + +bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o) +{ + + switch(type(o)) { + case OT_INTEGER: + trg = -_integer(o); + return true; + case OT_FLOAT: + trg = -_float(o); + return true; + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o)->_delegate) { + SQObjectPtr closure; + if(_delegable(o)->GetMetaMethod(this, MT_UNM, closure)) { + Push(o); + if(!CallMetaMethod(closure, MT_UNM, 1, temp_reg)) return false; + _Swap(trg,temp_reg); + return true; + + } + } + default:break; //shutup compiler + } + Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o)); + return false; +} + +#define _RET_SUCCEED(exp) { result = (exp); return true; } +bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result) +{ + SQObjectType t1 = type(o1), t2 = type(o2); + if(t1 == t2){ + if(_rawval(o1)==_rawval(o2))_RET_SUCCEED(0); + SQObjectPtr res; + switch(t1){ + case OT_STRING: + _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2))); + case OT_INTEGER: + _RET_SUCCEED(_integer(o1)-_integer(o2)); + case OT_FLOAT: + _RET_SUCCEED((_float(o1)<_float(o2))?-1:1); + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o1)->_delegate) { + SQObjectPtr closure; + if(_delegable(o1)->GetMetaMethod(this, MT_CMP, closure)) { + Push(o1);Push(o2); + if(!CallMetaMethod(closure,MT_CMP,2,res)) return false; + } + break; + } + //continues through (no break needed) + default: + _RET_SUCCEED( _userpointer(o1) < _userpointer(o2)?-1:1 ); + } + if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; } + _RET_SUCCEED(_integer(res)); + + } + else{ + if(sq_isnumeric(o1) && sq_isnumeric(o2)){ + if((t1==OT_INTEGER) && (t2==OT_FLOAT)) { + if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); } + else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); } + _RET_SUCCEED(1); + } + else{ + if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); } + else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); } + _RET_SUCCEED(1); + } + } + else if(t1==OT_NULL) {_RET_SUCCEED(-1);} + else if(t2==OT_NULL) {_RET_SUCCEED(1);} + else { Raise_CompareError(o1,o2); return false; } + + } + assert(0); + _RET_SUCCEED(0); //cannot happen +} + +bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res) +{ + SQInteger r; + if(ObjCmp(o1,o2,r)) { + switch(op) { + case CMP_G: res = (r > 0); return true; + case CMP_GE: res = (r >= 0); return true; + case CMP_L: res = (r < 0); return true; + case CMP_LE: res = (r <= 0); return true; + case CMP_3W: res = r; return true; + } + assert(0); + } + return false; +} + +bool SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res) +{ + switch(type(o)) { + case OT_STRING: + res = o; + return true; + case OT_FLOAT: + scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%g"),_float(o)); + break; + case OT_INTEGER: + scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_PRINT_INT_FMT,_integer(o)); + break; + case OT_BOOL: + scsprintf(_sp(rsl(6)),_integer(o)?_SC("true"):_SC("false")); + break; + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o)->_delegate) { + SQObjectPtr closure; + if(_delegable(o)->GetMetaMethod(this, MT_TOSTRING, closure)) { + Push(o); + if(CallMetaMethod(closure,MT_TOSTRING,1,res)) {; + if(type(res) == OT_STRING) + return true; + } + else { + return false; + } + } + } + default: + scsprintf(_sp(rsl(sizeof(void*)+20)),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o)); + } + res = SQString::Create(_ss(this),_spval); + return true; +} + + +bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest) +{ + SQObjectPtr a, b; + if(!ToString(str, a)) return false; + if(!ToString(obj, b)) return false; + SQInteger l = _string(a)->_len , ol = _string(b)->_len; + SQChar *s = _sp(rsl(l + ol + 1)); + memcpy(s, _stringval(a), rsl(l)); + memcpy(s + l, _stringval(b), rsl(ol)); + dest = SQString::Create(_ss(this), _spval, l + ol); + return true; +} + +bool SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest) +{ + if(is_delegable(obj1) && _delegable(obj1)->_delegate) { + SQObjectPtr closure; + if(_delegable(obj1)->GetMetaMethod(this, MT_TYPEOF, closure)) { + Push(obj1); + return CallMetaMethod(closure,MT_TYPEOF,1,dest); + } + } + dest = SQString::Create(_ss(this),GetTypeName(obj1)); + return true; +} + +bool SQVM::Init(SQVM *friendvm, SQInteger stacksize) +{ + _stack.resize(stacksize); + _alloccallsstacksize = 4; + _callstackdata.resize(_alloccallsstacksize); + _callsstacksize = 0; + _callsstack = &_callstackdata[0]; + _stackbase = 0; + _top = 0; + if(!friendvm) + _roottable = SQTable::Create(_ss(this), 0); + else { + _roottable = friendvm->_roottable; + _errorhandler = friendvm->_errorhandler; + _debughook = friendvm->_debughook; + _debughook_native = friendvm->_debughook_native; + _debughook_closure = friendvm->_debughook_closure; + } + + sq_base_register(this); + return true; +} + + +bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQInteger stackbase,bool tailcall) +{ + SQFunctionProto *func = closure->_function; + + SQInteger paramssize = func->_nparameters; + const SQInteger newtop = stackbase + func->_stacksize; + SQInteger nargs = args; + if(func->_varparams) + { + paramssize--; + if (nargs < paramssize) { + Raise_Error(_SC("wrong number of parameters")); + return false; + } + + //dumpstack(stackbase); + SQInteger nvargs = nargs - paramssize; + SQArray *arr = SQArray::Create(_ss(this),nvargs); + SQInteger pbase = stackbase+paramssize; + for(SQInteger n = 0; n < nvargs; n++) { + arr->_values[n] = _stack._vals[pbase]; + _stack._vals[pbase].Null(); + pbase++; + + } + _stack._vals[stackbase+paramssize] = arr; + //dumpstack(stackbase); + } + else if (paramssize != nargs) { + SQInteger ndef = func->_ndefaultparams; + SQInteger diff; + if(ndef && nargs < paramssize && (diff = paramssize - nargs) <= ndef) { + for(SQInteger n = ndef - diff; n < ndef; n++) { + _stack._vals[stackbase + (nargs++)] = closure->_defaultparams[n]; + } + } + else { + Raise_Error(_SC("wrong number of parameters")); + return false; + } + } + + if(closure->_env) { + _stack._vals[stackbase] = closure->_env->_obj; + } + + if(!EnterFrame(stackbase, newtop, tailcall)) return false; + + ci->_closure = closure; + ci->_literals = func->_literals; + ci->_ip = func->_instructions; + ci->_target = (SQInt32)target; + + if (_debughook) { + CallDebugHook(_SC('c')); + } + + if (closure->_function->_bgenerator) { + SQFunctionProto *f = closure->_function; + SQGenerator *gen = SQGenerator::Create(_ss(this), closure); + if(!gen->Yield(this,f->_stacksize)) + return false; + SQObjectPtr temp; + Return(1, target, temp); + STK(target) = gen; + } + + + return true; +} + +bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval) +{ + SQBool _isroot = ci->_root; + SQInteger callerbase = _stackbase - ci->_prevstkbase; + + if (_debughook) { + for(SQInteger i=0; i<ci->_ncalls; i++) { + CallDebugHook(_SC('r')); + } + } + + SQObjectPtr *dest; + if (_isroot) { + dest = &(retval); + } else if (ci->_target == -1) { + dest = NULL; + } else { + dest = &_stack._vals[callerbase + ci->_target]; + } + if (dest) { + if(_arg0 != 0xFF) { + *dest = _stack._vals[_stackbase+_arg1]; + } + else { + dest->Null(); + } + //*dest = (_arg0 != 0xFF) ? _stack._vals[_stackbase+_arg1] : _null_; + } + LeaveFrame(); + return _isroot ? true : false; +} + +#define _RET_ON_FAIL(exp) { if(!exp) return false; } + +bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr) +{ + SQObjectPtr trg; + _RET_ON_FAIL(ARITH_OP( op , trg, a, incr)); + target = a; + a = trg; + return true; +} + +bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger selfidx) +{ + SQObjectPtr tmp, tself = self, tkey = key; + if (!Get(tself, tkey, tmp, false, selfidx)) { return false; } + _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr)) + if (!Set(tself, tkey, target,selfidx)) { return false; } + if (postfix) target = tmp; + return true; +} + +#define arg0 (_i_._arg0) +#define sarg0 ((SQInteger)*((signed char *)&_i_._arg0)) +#define arg1 (_i_._arg1) +#define sarg1 (*((SQInt32 *)&_i_._arg1)) +#define arg2 (_i_._arg2) +#define arg3 (_i_._arg3) +#define sarg3 ((SQInteger)*((signed char *)&_i_._arg3)) + +SQRESULT SQVM::Suspend() +{ + if (_suspended) + return sq_throwerror(this, _SC("cannot suspend an already suspended vm")); + if (_nnativecalls!=2) + return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods")); + return SQ_SUSPEND_FLAG; +} + + +#define _FINISH(howmuchtojump) {jump = howmuchtojump; return true; } +bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr +&o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump) +{ + SQInteger nrefidx; + switch(type(o1)) { + case OT_TABLE: + if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_ARRAY: + if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(exitpos); + o4 = (SQInteger) nrefidx; _FINISH(1); + case OT_STRING: + if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_CLASS: + if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); + o4 = (SQInteger)nrefidx; _FINISH(1); + case OT_USERDATA: + case OT_INSTANCE: + if(_delegable(o1)->_delegate) { + SQObjectPtr itr; + SQObjectPtr closure; + if(_delegable(o1)->GetMetaMethod(this, MT_NEXTI, closure)) { + Push(o1); + Push(o4); + if(CallMetaMethod(closure, MT_NEXTI, 2, itr)) { + o4 = o2 = itr; + if(type(itr) == OT_NULL) _FINISH(exitpos); + if(!Get(o1, itr, o3, false, DONT_FALL_BACK)) { + Raise_Error(_SC("_nexti returned an invalid idx")); // cloud be changed + return false; + } + _FINISH(1); + } + else { + return false; + } + } + Raise_Error(_SC("_nexti failed")); + return false; + } + break; + case OT_GENERATOR: + if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(exitpos); + if(_generator(o1)->_state == SQGenerator::eSuspended) { + SQInteger idx = 0; + if(type(o4) == OT_INTEGER) { + idx = _integer(o4) + 1; + } + o2 = idx; + o4 = idx; + _generator(o1)->Resume(this, o3); + _FINISH(0); + } + default: + Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1)); + } + return false; //cannot be hit(just to avoid warnings) +} + +#define COND_LITERAL (arg3!=0?ci->_literals[arg1]:STK(arg1)) + +#define SQ_THROW() { goto exception_trap; } + +#define _GUARD(exp) { if(!exp) { SQ_THROW();} } + +bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func) +{ + SQInteger nouters; + SQClosure *closure = SQClosure::Create(_ss(this), func); + if((nouters = func->_noutervalues)) { + for(SQInteger i = 0; i<nouters; i++) { + SQOuterVar &v = func->_outervalues[i]; + switch(v._type){ + case otLOCAL: + FindOuter(closure->_outervalues[i], &STK(_integer(v._src))); + break; + case otOUTER: + closure->_outervalues[i] = _closure(ci->_closure)->_outervalues[_integer(v._src)]; + break; + } + } + } + SQInteger ndefparams; + if((ndefparams = func->_ndefaultparams)) { + for(SQInteger i = 0; i < ndefparams; i++) { + SQInteger spos = func->_defaultparams[i]; + closure->_defaultparams[i] = _stack._vals[_stackbase + spos]; + } + } + target = closure; + return true; + +} + + +bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes) +{ + SQClass *base = NULL; + SQObjectPtr attrs; + if(baseclass != -1) { + if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; } + base = _class(_stack._vals[_stackbase + baseclass]); + } + if(attributes != MAX_FUNC_STACKSIZE) { + attrs = _stack._vals[_stackbase+attributes]; + } + target = SQClass::Create(_ss(this),base); + if(type(_class(target)->_metamethods[MT_INHERITED]) != OT_NULL) { + int nparams = 2; + SQObjectPtr ret; + Push(target); Push(attrs); + Call(_class(target)->_metamethods[MT_INHERITED],nparams,_top - nparams, ret, false); + Pop(nparams); + } + _class(target)->_attributes = attrs; + return true; +} + +bool SQVM::IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res) +{ + if(type(o1) == type(o2)) { + res = (_rawval(o1) == _rawval(o2)); + } + else { + if(sq_isnumeric(o1) && sq_isnumeric(o2)) { + res = (tofloat(o1) == tofloat(o2)); + } + else { + res = false; + } + } + return true; +} + +bool SQVM::IsFalse(SQObjectPtr &o) +{ + if(((type(o) & SQOBJECT_CANBEFALSE) + && ( ((type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0))) )) +#if !defined(SQUSEDOUBLE) || (defined(SQUSEDOUBLE) && defined(_SQ64)) + || (_integer(o) == 0) ) //OT_NULL|OT_INTEGER|OT_BOOL +#else + || (((type(o) != OT_FLOAT) && (_integer(o) == 0))) ) //OT_NULL|OT_INTEGER|OT_BOOL +#endif + { + return true; + } + return false; +} + +bool SQVM::Execute(SQObjectPtr &closure, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, SQBool raiseerror,ExecutionType et) +{ + if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; } + _nnativecalls++; + AutoDec ad(&_nnativecalls); + SQInteger traps = 0; + CallInfo *prevci = ci; + + switch(et) { + case ET_CALL: { + temp_reg = closure; + if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) { + //call the handler if there are no calls in the stack, if not relies on the previous node + if(ci == NULL) CallErrorHandler(_lasterror); + return false; + } + if(ci == prevci) { + outres = STK(_top-nargs); + return true; + } + ci->_root = SQTrue; + } + break; + case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, outres); ci->_root = SQTrue; traps += ci->_etraps; break; + case ET_RESUME_VM: + case ET_RESUME_THROW_VM: + traps = _suspended_traps; + ci->_root = _suspended_root; + _suspended = SQFalse; + if(et == ET_RESUME_THROW_VM) { SQ_THROW(); } + break; + } + +exception_restore: + // + { + for(;;) + { + const SQInstruction &_i_ = *ci->_ip++; + //dumpstack(_stackbase); + //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-ci->_iv->_vals,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3); + switch(_i_.op) + { + case _OP_LINE: if (_debughook) CallDebugHook(_SC('l'),arg1); continue; + case _OP_LOAD: TARGET = ci->_literals[arg1]; continue; + case _OP_LOADINT: +#ifndef _SQ64 + TARGET = (SQInteger)arg1; continue; +#else + TARGET = (SQInteger)((SQUnsignedInteger32)arg1); continue; +#endif + case _OP_LOADFLOAT: TARGET = *((SQFloat *)&arg1); continue; + case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue; + case _OP_TAILCALL:{ + SQObjectPtr &t = STK(arg1); + if (type(t) == OT_CLOSURE + && (!_closure(t)->_function->_bgenerator)){ + SQObjectPtr clo = t; + if(_openouters) CloseOuters(&(_stack._vals[_stackbase])); + for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i); + _GUARD(StartCall(_closure(clo), ci->_target, arg3, _stackbase, true)); + continue; + } + } + case _OP_CALL: { + SQObjectPtr clo = STK(arg1); + switch (type(clo)) { + case OT_CLOSURE: + _GUARD(StartCall(_closure(clo), sarg0, arg3, _stackbase+arg2, false)); + continue; + case OT_NATIVECLOSURE: { + bool suspend; + _GUARD(CallNative(_nativeclosure(clo), arg3, _stackbase+arg2, clo,suspend)); + if(suspend){ + _suspended = SQTrue; + _suspended_target = sarg0; + _suspended_root = ci->_root; + _suspended_traps = traps; + outres = clo; + return true; + } + if(sarg0 != -1) { + STK(arg0) = clo; + } + } + continue; + case OT_CLASS:{ + SQObjectPtr inst; + _GUARD(CreateClassInstance(_class(clo),inst,clo)); + if(sarg0 != -1) { + STK(arg0) = inst; + } + SQInteger stkbase; + switch(type(clo)) { + case OT_CLOSURE: + stkbase = _stackbase+arg2; + _stack._vals[stkbase] = inst; + _GUARD(StartCall(_closure(clo), -1, arg3, stkbase, false)); + break; + case OT_NATIVECLOSURE: + bool suspend; + stkbase = _stackbase+arg2; + _stack._vals[stkbase] = inst; + _GUARD(CallNative(_nativeclosure(clo), arg3, stkbase, clo,suspend)); + break; + default: break; //shutup GCC 4.x + } + } + break; + case OT_TABLE: + case OT_USERDATA: + case OT_INSTANCE:{ + SQObjectPtr closure; + if(_delegable(clo)->_delegate && _delegable(clo)->GetMetaMethod(this,MT_CALL,closure)) { + Push(clo); + for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i)); + if(!CallMetaMethod(closure, MT_CALL, arg3+1, clo)) SQ_THROW(); + if(sarg0 != -1) { + STK(arg0) = clo; + } + break; + } + + //Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); + //SQ_THROW(); + } + default: + Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); + SQ_THROW(); + } + } + continue; + case _OP_PREPCALL: + case _OP_PREPCALLK: { + SQObjectPtr &key = _i_.op == _OP_PREPCALLK?(ci->_literals)[arg1]:STK(arg1); + SQObjectPtr &o = STK(arg2); + if (!Get(o, key, temp_reg,false,arg2)) { + SQ_THROW(); + } + STK(arg3) = o; + _Swap(TARGET,temp_reg);//TARGET = temp_reg; + } + continue; + case _OP_GETK: + if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, false,arg2)) { SQ_THROW();} + _Swap(TARGET,temp_reg);//TARGET = temp_reg; + continue; + case _OP_MOVE: TARGET = STK(arg1); continue; + case _OP_NEWSLOT: + _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),false)); + if(arg0 != 0xFF) TARGET = STK(arg3); + continue; + case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue; + case _OP_SET: + if (!Set(STK(arg1), STK(arg2), STK(arg3),arg1)) { SQ_THROW(); } + if (arg0 != 0xFF) TARGET = STK(arg3); + continue; + case _OP_GET: + if (!Get(STK(arg1), STK(arg2), temp_reg, false,arg1)) { SQ_THROW(); } + _Swap(TARGET,temp_reg);//TARGET = temp_reg; + continue; + case _OP_EQ:{ + bool res; + if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } + TARGET = res?true:false; + }continue; + case _OP_NE:{ + bool res; + if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } + TARGET = (!res)?true:false; + } continue; + case _OP_ADD: _ARITH_(+,TARGET,STK(arg2),STK(arg1)); continue; + case _OP_SUB: _ARITH_(-,TARGET,STK(arg2),STK(arg1)); continue; + case _OP_MUL: _ARITH_(*,TARGET,STK(arg2),STK(arg1)); continue; + case _OP_DIV: _ARITH_NOZERO(/,TARGET,STK(arg2),STK(arg1),_SC("division by zero")); continue; + case _OP_MOD: ARITH_OP('%',TARGET,STK(arg2),STK(arg1)); continue; + case _OP_BITW: _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue; + case _OP_RETURN: + if((ci)->_generator) { + (ci)->_generator->Kill(); + } + if(Return(arg0, arg1, temp_reg)){ + assert(traps==0); + //outres = temp_reg; + _Swap(outres,temp_reg); + return true; + } + continue; + case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n).Null(); }continue; + case _OP_LOADROOT: TARGET = _roottable; continue; + case _OP_LOADBOOL: TARGET = arg1?true:false; continue; + case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue; + case _OP_JMP: ci->_ip += (sarg1); continue; + //case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue; + case _OP_JCMP: + _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg0),temp_reg)); + if(IsFalse(temp_reg)) ci->_ip+=(sarg1); + continue; + case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue; + case _OP_GETOUTER: { + SQClosure *cur_cls = _closure(ci->_closure); + SQOuter *otr = _outer(cur_cls->_outervalues[arg1]); + TARGET = *(otr->_valptr); + } + continue; + case _OP_SETOUTER: { + SQClosure *cur_cls = _closure(ci->_closure); + SQOuter *otr = _outer(cur_cls->_outervalues[arg1]); + *(otr->_valptr) = STK(arg2); + if(arg0 != 0xFF) { + TARGET = STK(arg2); + } + } + continue; + case _OP_NEWOBJ: + switch(arg3) { + case NOT_TABLE: TARGET = SQTable::Create(_ss(this), arg1); continue; + case NOT_ARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue; + case NOT_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue; + default: assert(0); continue; + } + case _OP_APPENDARRAY: + { + SQObject val; + val._unVal.raw = 0; + switch(arg2) { + case AAT_STACK: + val = STK(arg1); break; + case AAT_LITERAL: + val = ci->_literals[arg1]; break; + case AAT_INT: + val._type = OT_INTEGER; +#ifndef _SQ64 + val._unVal.nInteger = (SQInteger)arg1; +#else + val._unVal.nInteger = (SQInteger)((SQUnsignedInteger32)arg1); +#endif + break; + case AAT_FLOAT: + val._type = OT_FLOAT; + val._unVal.fFloat = *((SQFloat *)&arg1); + break; + case AAT_BOOL: + val._type = OT_BOOL; + val._unVal.nInteger = arg1; + break; + default: assert(0); break; + + } + _array(STK(arg0))->Append(val); continue; + } + case _OP_COMPARITH: { + SQInteger selfidx = (((SQUnsignedInteger)arg1&0xFFFF0000)>>16); + _GUARD(DerefInc(arg3, TARGET, STK(selfidx), STK(arg2), STK(arg1&0x0000FFFF), false, selfidx)); + } + continue; + case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false, arg1));} continue; + case _OP_INCL: { + SQObjectPtr &a = STK(arg1); + if(type(a) == OT_INTEGER) { + a._unVal.nInteger = _integer(a) + sarg3; + } + else { + SQObjectPtr o(sarg3); //_GUARD(LOCAL_INC('+',TARGET, STK(arg1), o)); + _ARITH_(+,a,a,o); + } + } continue; + case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true, arg1));} continue; + case _OP_PINCL: { + SQObjectPtr &a = STK(arg1); + if(type(a) == OT_INTEGER) { + TARGET = a; + a._unVal.nInteger = _integer(a) + sarg3; + } + else { + SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o)); + } + + } continue; + case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) continue; + case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, true,DONT_FALL_BACK)?true:false;continue; + case _OP_INSTANCEOF: + if(type(STK(arg1)) != OT_CLASS) + {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();} + TARGET = (type(STK(arg2)) == OT_INSTANCE) ? (_instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?true:false) : false; + continue; + case _OP_AND: + if(IsFalse(STK(arg2))) { + TARGET = STK(arg2); + ci->_ip += (sarg1); + } + continue; + case _OP_OR: + if(!IsFalse(STK(arg2))) { + TARGET = STK(arg2); + ci->_ip += (sarg1); + } + continue; + case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue; + case _OP_NOT: TARGET = IsFalse(STK(arg1)); continue; + case _OP_BWNOT: + if(type(STK(arg1)) == OT_INTEGER) { + SQInteger t = _integer(STK(arg1)); + TARGET = SQInteger(~t); + continue; + } + Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1))); + SQ_THROW(); + case _OP_CLOSURE: { + SQClosure *c = ci->_closure._unVal.pClosure; + SQFunctionProto *fp = c->_function; + if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); } + continue; + } + case _OP_YIELD:{ + if(ci->_generator) { + if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1); + _GUARD(ci->_generator->Yield(this,arg2)); + traps -= ci->_etraps; + if(sarg1 != MAX_FUNC_STACKSIZE) _Swap(STK(arg1),temp_reg);//STK(arg1) = temp_reg; + } + else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();} + if(Return(arg0, arg1, temp_reg)){ + assert(traps == 0); + outres = temp_reg; + return true; + } + + } + continue; + case _OP_RESUME: + if(type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();} + _GUARD(_generator(STK(arg1))->Resume(this, TARGET)); + traps += ci->_etraps; + continue; + case _OP_FOREACH:{ int tojump; + _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,sarg1,tojump)); + ci->_ip += tojump; } + continue; + case _OP_POSTFOREACH: + assert(type(STK(arg0)) == OT_GENERATOR); + if(_generator(STK(arg0))->_state == SQGenerator::eDead) + ci->_ip += (sarg1 - 1); + continue; + case _OP_CLONE: _GUARD(Clone(STK(arg1), TARGET)); continue; + case _OP_TYPEOF: _GUARD(TypeOf(STK(arg1), TARGET)) continue; + case _OP_PUSHTRAP:{ + SQInstruction *_iv = _closure(ci->_closure)->_function->_instructions; + _etraps.push_back(SQExceptionTrap(_top,_stackbase, &_iv[(ci->_ip-_iv)+arg1], arg0)); traps++; + ci->_etraps++; + } + continue; + case _OP_POPTRAP: { + for(SQInteger i = 0; i < arg0; i++) { + _etraps.pop_back(); traps--; + ci->_etraps--; + } + } + continue; + case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue; + case _OP_NEWSLOTA: { + bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG)?true:false; + if(type(STK(arg1)) == OT_CLASS) { + if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) { + Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3)); + Push((arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : SQObjectPtr()); + Push(bstatic); + int nparams = 5; + if(Call(_class(STK(arg1))->_metamethods[MT_NEWMEMBER], nparams, _top - nparams, temp_reg,SQFalse)) { + Pop(nparams); + continue; + } + else { + SQ_THROW(); + } + } + } + _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),bstatic)); + if((arg0&NEW_SLOT_ATTRIBUTES_FLAG)) { + _class(STK(arg1))->SetAttributes(STK(arg2),STK(arg2-1)); + } + } + continue; + case _OP_GETBASE:{ + SQClosure *clo = _closure(ci->_closure); + if(clo->_base) { + TARGET = clo->_base; + } + else { + TARGET.Null(); + } + continue; + } + case _OP_CLOSE: + if(_openouters) CloseOuters(&(STK(arg1))); + continue; + } + + } + } +exception_trap: + { + SQObjectPtr currerror = _lasterror; +// dumpstack(_stackbase); +// SQInteger n = 0; + SQInteger last_top = _top; + + if(_ss(this)->_notifyallexceptions || (!traps && raiseerror)) CallErrorHandler(currerror); + + while( ci ) { + if(ci->_etraps > 0) { + SQExceptionTrap &et = _etraps.top(); + ci->_ip = et._ip; + _top = et._stacksize; + _stackbase = et._stackbase; + _stack._vals[_stackbase + et._extarget] = currerror; + _etraps.pop_back(); traps--; ci->_etraps--; + while(last_top >= _top) _stack._vals[last_top--].Null(); + goto exception_restore; + } + else if (_debughook) { + //notify debugger of a "return" + //even if it really an exception unwinding the stack + for(SQInteger i = 0; i < ci->_ncalls; i++) { + CallDebugHook(_SC('r')); + } + } + if(ci->_generator) ci->_generator->Kill(); + bool mustbreak = ci && ci->_root; + LeaveFrame(); + if(mustbreak) break; + } + + _lasterror = currerror; + return false; + } + assert(0); +} + +bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor) +{ + inst = theclass->CreateInstance(); + if(!theclass->GetConstructor(constructor)) { + constructor.Null(); + } + return true; +} + +void SQVM::CallErrorHandler(SQObjectPtr &error) +{ + if(type(_errorhandler) != OT_NULL) { + SQObjectPtr out; + Push(_roottable); Push(error); + Call(_errorhandler, 2, _top-2, out,SQFalse); + Pop(2); + } +} + + +void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline) +{ + _debughook = false; + SQFunctionProto *func=_closure(ci->_closure)->_function; + if(_debughook_native) { + const SQChar *src = type(func->_sourcename) == OT_STRING?_stringval(func->_sourcename):NULL; + const SQChar *fname = type(func->_name) == OT_STRING?_stringval(func->_name):NULL; + SQInteger line = forcedline?forcedline:func->GetLine(ci->_ip); + _debughook_native(this,type,src,line,fname); + } + else { + SQObjectPtr temp_reg; + SQInteger nparams=5; + Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name); + Call(_debughook_closure,nparams,_top-nparams,temp_reg,SQFalse); + Pop(nparams); + } + _debughook = true; +} + +bool SQVM::CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval, bool &suspend) +{ + SQInteger nparamscheck = nclosure->_nparamscheck; + SQInteger newtop = newbase + nargs + nclosure->_noutervalues; + + if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { + Raise_Error(_SC("Native stack overflow")); + return false; + } + + if(nparamscheck && (((nparamscheck > 0) && (nparamscheck != nargs)) || + ((nparamscheck < 0) && (nargs < (-nparamscheck))))) + { + Raise_Error(_SC("wrong number of parameters")); + return false; + } + + SQInteger tcs; + SQIntVec &tc = nclosure->_typecheck; + if((tcs = tc.size())) { + for(SQInteger i = 0; i < nargs && i < tcs; i++) { + if((tc._vals[i] != -1) && !(type(_stack._vals[newbase+i]) & tc._vals[i])) { + Raise_ParamTypeError(i,tc._vals[i],type(_stack._vals[newbase+i])); + return false; + } + } + } + + if(!EnterFrame(newbase, newtop, false)) return false; + ci->_closure = nclosure; + + SQInteger outers = nclosure->_noutervalues; + for (SQInteger i = 0; i < outers; i++) { + _stack._vals[newbase+nargs+i] = nclosure->_outervalues[i]; + } + if(nclosure->_env) { + _stack._vals[newbase] = nclosure->_env->_obj; + } + + _nnativecalls++; + SQInteger ret = (nclosure->_function)(this); + _nnativecalls--; + + suspend = false; + if (ret == SQ_SUSPEND_FLAG) { + suspend = true; + } + else if (ret < 0) { + LeaveFrame(); + Raise_Error(_lasterror); + return false; + } + if(ret) { + retval = _stack._vals[_top-1]; + } + else { + retval.Null(); + } + //retval = ret ? _stack._vals[_top-1] : _null_; + LeaveFrame(); + return true; +} + +#define FALLBACK_OK 0 +#define FALLBACK_NO_MATCH 1 +#define FALLBACK_ERROR 2 + +bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw, SQInteger selfidx) +{ + switch(type(self)){ + case OT_TABLE: + if(_table(self)->Get(key,dest))return true; + break; + case OT_ARRAY: + if(sq_isnumeric(key)) { if(_array(self)->Get(tointeger(key),dest)) { return true; } Raise_IdxError(key); return false; } + break; + case OT_INSTANCE: + if(_instance(self)->Get(key,dest)) return true; + break; + case OT_CLASS: + if(_class(self)->Get(key,dest)) return true; + break; + case OT_STRING: + if(sq_isnumeric(key)){ + SQInteger n = tointeger(key); + if(abs((int)n) < _string(self)->_len) { + if(n < 0) n = _string(self)->_len - n; + dest = SQInteger(_stringval(self)[n]); + return true; + } + Raise_IdxError(key); + return false; + } + break; + default:break; //shut up compiler + } + if(!raw) { + switch(FallBackGet(self,key,dest)) { + case FALLBACK_OK: return true; //okie + case FALLBACK_NO_MATCH: break; //keep falling back + case FALLBACK_ERROR: return false; // the metamethod failed + } + if(InvokeDefaultDelegate(self,key,dest)) { + return true; + } + } +//#ifdef ROOT_FALLBACK + if(selfidx == 0) { + if(_table(_roottable)->Get(key,dest)) return true; + } +//#endif + Raise_IdxError(key); + return false; +} + +bool SQVM::InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest) +{ + SQTable *ddel = NULL; + switch(type(self)) { + case OT_CLASS: ddel = _class_ddel; break; + case OT_TABLE: ddel = _table_ddel; break; + case OT_ARRAY: ddel = _array_ddel; break; + case OT_STRING: ddel = _string_ddel; break; + case OT_INSTANCE: ddel = _instance_ddel; break; + case OT_INTEGER:case OT_FLOAT:case OT_BOOL: ddel = _number_ddel; break; + case OT_GENERATOR: ddel = _generator_ddel; break; + case OT_CLOSURE: case OT_NATIVECLOSURE: ddel = _closure_ddel; break; + case OT_THREAD: ddel = _thread_ddel; break; + case OT_WEAKREF: ddel = _weakref_ddel; break; + default: return false; + } + return ddel->Get(key,dest); +} + + +SQInteger SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest) +{ + switch(type(self)){ + case OT_TABLE: + case OT_USERDATA: + //delegation + if(_delegable(self)->_delegate) { + if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,false,DONT_FALL_BACK)) return FALLBACK_OK; + } + else { + return FALLBACK_NO_MATCH; + } + //go through + case OT_INSTANCE: { + SQObjectPtr closure; + if(_delegable(self)->GetMetaMethod(this, MT_GET, closure)) { + Push(self);Push(key); + _nmetamethodscall++; + AutoDec ad(&_nmetamethodscall); + if(Call(closure, 2, _top - 2, dest, SQFalse)) { + Pop(2); + return FALLBACK_OK; + } + else { + if(type(_lasterror) != OT_NULL) { //NULL means "clean failure" (not found) + //error + Pop(2); + return FALLBACK_ERROR; + } + } + } + } + break; + default: break;//shutup GCC 4.x + } + // no metamethod or no fallback type + return FALLBACK_NO_MATCH; +} + +bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,SQInteger selfidx) +{ + switch(type(self)){ + case OT_TABLE: + if(_table(self)->Set(key,val)) return true; + break; + case OT_INSTANCE: + if(_instance(self)->Set(key,val)) return true; + break; + case OT_ARRAY: + if(!sq_isnumeric(key)) { Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; } + if(!_array(self)->Set(tointeger(key),val)) { + Raise_IdxError(key); + return false; + } + return true; + default: + Raise_Error(_SC("trying to set '%s'"),GetTypeName(self)); + return false; + } + + switch(FallBackSet(self,key,val)) { + case FALLBACK_OK: return true; //okie + case FALLBACK_NO_MATCH: break; //keep falling back + case FALLBACK_ERROR: return false; // the metamethod failed + } + if(selfidx == 0) { + if(_table(_roottable)->Set(key,val)) + return true; + } + Raise_IdxError(key); + return false; +} + +SQInteger SQVM::FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val) +{ + switch(type(self)) { + case OT_TABLE: + if(_table(self)->_delegate) { + if(Set(_table(self)->_delegate,key,val,DONT_FALL_BACK)) return FALLBACK_OK; + } + //keps on going + case OT_INSTANCE: + case OT_USERDATA:{ + SQObjectPtr closure; + SQObjectPtr t; + if(_delegable(self)->GetMetaMethod(this, MT_SET, closure)) { + Push(self);Push(key);Push(val); + _nmetamethodscall++; + AutoDec ad(&_nmetamethodscall); + if(Call(closure, 3, _top - 3, t, SQFalse)) { + Pop(3); + return FALLBACK_OK; + } + else { + if(type(_lasterror) != OT_NULL) { //NULL means "clean failure" (not found) + //error + Pop(3); + return FALLBACK_ERROR; + } + } + } + } + break; + default: break;//shutup GCC 4.x + } + // no metamethod or no fallback type + return FALLBACK_NO_MATCH; +} + +bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target) +{ + SQObjectPtr temp_reg; + SQObjectPtr newobj; + switch(type(self)){ + case OT_TABLE: + newobj = _table(self)->Clone(); + goto cloned_mt; + case OT_INSTANCE: { + newobj = _instance(self)->Clone(_ss(this)); +cloned_mt: + SQObjectPtr closure; + if(_delegable(newobj)->_delegate && _delegable(newobj)->GetMetaMethod(this,MT_CLONED,closure)) { + Push(newobj); + Push(self); + if(!CallMetaMethod(closure,MT_CLONED,2,temp_reg)) + return false; + } + } + target = newobj; + return true; + case OT_ARRAY: + target = _array(self)->Clone(); + return true; + default: + Raise_Error(_SC("cloning a %s"), GetTypeName(self)); + return false; + } +} + +bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) +{ + if(type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; } + switch(type(self)) { + case OT_TABLE: { + bool rawcall = true; + if(_table(self)->_delegate) { + SQObjectPtr res; + if(!_table(self)->Get(key,res)) { + SQObjectPtr closure; + if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_NEWSLOT,closure)) { + Push(self);Push(key);Push(val); + if(!CallMetaMethod(closure,MT_NEWSLOT,3,res)) { + return false; + } + rawcall = false; + } + else { + rawcall = true; + } + } + } + if(rawcall) _table(self)->NewSlot(key,val); //cannot fail + + break;} + case OT_INSTANCE: { + SQObjectPtr res; + SQObjectPtr closure; + if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_NEWSLOT,closure)) { + Push(self);Push(key);Push(val); + if(!CallMetaMethod(closure,MT_NEWSLOT,3,res)) { + return false; + } + break; + } + Raise_Error(_SC("class instances do not support the new slot operator")); + return false; + break;} + case OT_CLASS: + if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) { + if(_class(self)->_locked) { + Raise_Error(_SC("trying to modify a class that has already been instantiated")); + return false; + } + else { + SQObjectPtr oval = PrintObjVal(key); + Raise_Error(_SC("the property '%s' already exists"),_stringval(oval)); + return false; + } + } + break; + default: + Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); + return false; + break; + } + return true; +} + + + +bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res) +{ + switch(type(self)) { + case OT_TABLE: + case OT_INSTANCE: + case OT_USERDATA: { + SQObjectPtr t; + //bool handled = false; + SQObjectPtr closure; + if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_DELSLOT,closure)) { + Push(self);Push(key); + return CallMetaMethod(closure,MT_DELSLOT,2,res); + } + else { + if(type(self) == OT_TABLE) { + if(_table(self)->Get(key,t)) { + _table(self)->Remove(key); + } + else { + Raise_IdxError((SQObject &)key); + return false; + } + } + else { + Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self)); + return false; + } + } + res = t; + } + break; + default: + Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self)); + return false; + } + return true; +} + +bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror) +{ +#ifdef _DEBUG +SQInteger prevstackbase = _stackbase; +#endif + switch(type(closure)) { + case OT_CLOSURE: + return Execute(closure, nparams, stackbase, outres, raiseerror); + break; + case OT_NATIVECLOSURE:{ + bool suspend; + return CallNative(_nativeclosure(closure), nparams, stackbase, outres,suspend); + + } + break; + case OT_CLASS: { + SQObjectPtr constr; + SQObjectPtr temp; + CreateClassInstance(_class(closure),outres,constr); + if(type(constr) != OT_NULL) { + _stack[stackbase] = outres; + return Call(constr,nparams,stackbase,temp,raiseerror); + } + return true; + } + break; + default: + return false; + } +#ifdef _DEBUG + if(!_suspended) { + assert(_stackbase == prevstackbase); + } +#endif + return true; +} + +bool SQVM::CallMetaMethod(SQObjectPtr &closure,SQMetaMethod mm,SQInteger nparams,SQObjectPtr &outres) +{ + //SQObjectPtr closure; + + _nmetamethodscall++; + if(Call(closure, nparams, _top - nparams, outres, SQFalse)) { + _nmetamethodscall--; + Pop(nparams); + return true; + } + _nmetamethodscall--; + //} + Pop(nparams); + return false; +} + +void SQVM::FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex) +{ + SQOuter **pp = &_openouters; + SQOuter *p; + SQOuter *otr; + + while ((p = *pp) != NULL && p->_valptr >= stackindex) { + if (p->_valptr == stackindex) { + target = SQObjectPtr(p); + return; + } + pp = &p->_next; + } + otr = SQOuter::Create(_ss(this), stackindex); + otr->_next = *pp; + otr->_idx = (stackindex - _stack._vals); + __ObjAddRef(otr); + *pp = otr; + target = SQObjectPtr(otr); +} + +bool SQVM::EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall) +{ + if( !tailcall ) { + if( _callsstacksize == _alloccallsstacksize ) { + GrowCallStack(); + } + ci = &_callsstack[_callsstacksize++]; + ci->_prevstkbase = (SQInt32)(newbase - _stackbase); + ci->_prevtop = (SQInt32)(_top - _stackbase); + ci->_etraps = 0; + ci->_ncalls = 1; + ci->_generator = NULL; + ci->_root = SQFalse; + } + else { + ci->_ncalls++; + } + + _stackbase = newbase; + _top = newtop; + if(newtop + MIN_STACK_OVERHEAD > (SQInteger)_stack.size()) { + if(_nmetamethodscall) { + Raise_Error(_SC("stack overflow, cannot resize stack while in a metamethod")); + return false; + } + _stack.resize(_stack.size() + (MIN_STACK_OVERHEAD << 2)); + RelocateOuters(); + } + return true; +} + +void SQVM::LeaveFrame() { + SQInteger last_top = _top; + SQInteger last_stackbase = _stackbase; + SQInteger css = --_callsstacksize; + + /* First clean out the call stack frame */ + ci->_closure.Null(); + _stackbase -= ci->_prevstkbase; + _top = _stackbase + ci->_prevtop; + ci = (css) ? &_callsstack[css-1] : NULL; + + if(_openouters) CloseOuters(&(_stack._vals[last_stackbase])); + while (last_top >= _top) { + _stack._vals[last_top--].Null(); + } +} + +void SQVM::RelocateOuters() +{ + SQOuter *p = _openouters; + while (p) { + p->_valptr = _stack._vals + p->_idx; + p = p->_next; + } +} + +void SQVM::CloseOuters(SQObjectPtr *stackindex) { + SQOuter *p; + while ((p = _openouters) != NULL && p->_valptr >= stackindex) { + p->_value = *(p->_valptr); + p->_valptr = &p->_value; + _openouters = p->_next; + __ObjRelease(p); + } +} + +void SQVM::Remove(SQInteger n) { + n = (n >= 0)?n + _stackbase - 1:_top + n; + for(SQInteger i = n; i < _top; i++){ + _stack[i] = _stack[i+1]; + } + _stack[_top].Null(); + _top--; +} + +void SQVM::Pop() { + _stack[--_top].Null(); +} + +void SQVM::Pop(SQInteger n) { + for(SQInteger i = 0; i < n; i++){ + _stack[--_top].Null(); + } +} + +void SQVM::PushNull() { _stack[_top++].Null(); } +void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; } +SQObjectPtr &SQVM::Top() { return _stack[_top-1]; } +SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; } +SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; } +SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; } + +#ifdef _DEBUG_DUMP +void SQVM::dumpstack(SQInteger stackbase,bool dumpall) +{ + SQInteger size=dumpall?_stack.size():_top; + SQInteger n=0; + scprintf(_SC("\n>>>>stack dump<<<<\n")); + CallInfo &ci=_callsstack[_callsstacksize-1]; + scprintf(_SC("IP: %p\n"),ci._ip); + scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase); + scprintf(_SC("prev top: %d\n"),ci._prevtop); + for(SQInteger i=0;i<size;i++){ + SQObjectPtr &obj=_stack[i]; + if(stackbase==i)scprintf(_SC(">"));else scprintf(_SC(" ")); + scprintf(_SC("[%d]:"),n); + switch(type(obj)){ + case OT_FLOAT: scprintf(_SC("FLOAT %.3f"),_float(obj));break; + case OT_INTEGER: scprintf(_SC("INTEGER %d"),_integer(obj));break; + case OT_BOOL: scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break; + case OT_STRING: scprintf(_SC("STRING %s"),_stringval(obj));break; + case OT_NULL: scprintf(_SC("NULL")); break; + case OT_TABLE: scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break; + case OT_ARRAY: scprintf(_SC("ARRAY %p"),_array(obj));break; + case OT_CLOSURE: scprintf(_SC("CLOSURE [%p]"),_closure(obj));break; + case OT_NATIVECLOSURE: scprintf(_SC("NATIVECLOSURE"));break; + case OT_USERDATA: scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break; + case OT_GENERATOR: scprintf(_SC("GENERATOR %p"),_generator(obj));break; + case OT_THREAD: scprintf(_SC("THREAD [%p]"),_thread(obj));break; + case OT_USERPOINTER: scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break; + case OT_CLASS: scprintf(_SC("CLASS %p"),_class(obj));break; + case OT_INSTANCE: scprintf(_SC("INSTANCE %p"),_instance(obj));break; + case OT_WEAKREF: scprintf(_SC("WEAKERF %p"),_weakref(obj));break; + default: + assert(0); + break; + }; + scprintf(_SC("\n")); + ++n; + } +} + + + +#endif diff --git a/squirrel_3_0_1_stable/squirrel/sqvm.h b/squirrel_3_0_1_stable/squirrel/sqvm.h index 397dcd9c1..a21be543d 100644 --- a/squirrel_3_0_1_stable/squirrel/sqvm.h +++ b/squirrel_3_0_1_stable/squirrel/sqvm.h @@ -1,208 +1,208 @@ -/* see copyright notice in squirrel.h */
-#ifndef _SQVM_H_
-#define _SQVM_H_
-
-#include "sqopcodes.h"
-#include "sqobject.h"
-#define MAX_NATIVE_CALLS 100
-#define MIN_STACK_OVERHEAD 15
-
-#define SQ_SUSPEND_FLAG -666
-#define DONT_FALL_BACK 666
-//base lib
-void sq_base_register(HSQUIRRELVM v);
-
-struct SQExceptionTrap{
- SQExceptionTrap() {}
- SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
- SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; }
- SQInteger _stackbase;
- SQInteger _stacksize;
- SQInstruction *_ip;
- SQInteger _extarget;
-};
-
-#define _INLINE
-
-#define STK(a) _stack._vals[_stackbase+(a)]
-#define TARGET _stack._vals[_stackbase+arg0]
-
-typedef sqvector<SQExceptionTrap> ExceptionsTraps;
-
-struct SQVM : public CHAINABLE_OBJ
-{
- struct CallInfo{
- //CallInfo() { _generator = NULL;}
- SQInstruction *_ip;
- SQObjectPtr *_literals;
- SQObjectPtr _closure;
- SQGenerator *_generator;
- SQInt32 _etraps;
- SQInt32 _prevstkbase;
- SQInt32 _prevtop;
- SQInt32 _target;
- SQInt32 _ncalls;
- SQBool _root;
- };
-
-typedef sqvector<CallInfo> CallInfoVec;
-public:
- void DebugHookProxy(SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname);
- static void _DebugHookProxy(HSQUIRRELVM v, SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname);
- enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM,ET_RESUME_THROW_VM };
- SQVM(SQSharedState *ss);
- ~SQVM();
- bool Init(SQVM *friendvm, SQInteger stacksize);
- bool Execute(SQObjectPtr &func, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);
- //starts a native call return when the NATIVE closure returns
- bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval,bool &suspend);
- //starts a SQUIRREL call in the same "Execution loop"
- bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);
- bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);
- //call a generic closure pure SQUIRREL or NATIVE
- bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);
- SQRESULT Suspend();
-
- void CallDebugHook(SQInteger type,SQInteger forcedline=0);
- void CallErrorHandler(SQObjectPtr &e);
- bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, SQInteger selfidx);
- SQInteger FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
- bool InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
- bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, SQInteger selfidx);
- SQInteger FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val);
- bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);
- bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
- bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
- bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
- bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
- static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res);
- bool ToString(const SQObjectPtr &o,SQObjectPtr &res);
- SQString *PrintObjVal(const SQObjectPtr &o);
-
-
- void Raise_Error(const SQChar *s, ...);
- void Raise_Error(const SQObjectPtr &desc);
- void Raise_IdxError(const SQObjectPtr &o);
- void Raise_CompareError(const SQObject &o1, const SQObject &o2);
- void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);
-
- void FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex);
- void RelocateOuters();
- void CloseOuters(SQObjectPtr *stackindex);
-
- bool TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
- bool CallMetaMethod(SQObjectPtr &closure, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);
- bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
- bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);
- //new stuff
- _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
- _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
- _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
- _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
- bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
- bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);
- //return true if the loop is finished
- bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump);
- //_INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
- _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
- _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger arg0);
-#ifdef _DEBUG_DUMP
- void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
-#endif
-
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- SQObjectType GetType() {return OT_THREAD;}
-#endif
- void Finalize();
- void GrowCallStack() {
- SQInteger newsize = _alloccallsstacksize*2;
- _callstackdata.resize(newsize);
- _callsstack = &_callstackdata[0];
- _alloccallsstacksize = newsize;
- }
- bool EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall);
- void LeaveFrame();
- void Release(){ sq_delete(this,SQVM); }
-////////////////////////////////////////////////////////////////////////////
- //stack functions for the api
- void Remove(SQInteger n);
-
- static bool IsFalse(SQObjectPtr &o);
-
- void Pop();
- void Pop(SQInteger n);
- void Push(const SQObjectPtr &o);
- void PushNull();
- SQObjectPtr &Top();
- SQObjectPtr &PopGet();
- SQObjectPtr &GetUp(SQInteger n);
- SQObjectPtr &GetAt(SQInteger n);
-
- SQObjectPtrVec _stack;
-
- SQInteger _top;
- SQInteger _stackbase;
- SQOuter *_openouters;
- SQObjectPtr _roottable;
- SQObjectPtr _lasterror;
- SQObjectPtr _errorhandler;
-
- bool _debughook;
- SQDEBUGHOOK _debughook_native;
- SQObjectPtr _debughook_closure;
-
- SQObjectPtr temp_reg;
-
-
- CallInfo* _callsstack;
- SQInteger _callsstacksize;
- SQInteger _alloccallsstacksize;
- sqvector<CallInfo> _callstackdata;
-
- ExceptionsTraps _etraps;
- CallInfo *ci;
- void *_foreignptr;
- //VMs sharing the same state
- SQSharedState *_sharedstate;
- SQInteger _nnativecalls;
- SQInteger _nmetamethodscall;
- //suspend infos
- SQBool _suspended;
- SQBool _suspended_root;
- SQInteger _suspended_target;
- SQInteger _suspended_traps;
-};
-
-struct AutoDec{
- AutoDec(SQInteger *n) { _n = n; }
- ~AutoDec() { (*_n)--; }
- SQInteger *_n;
-};
-
-inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
-
-#define _ss(_vm_) (_vm_)->_sharedstate
-
-#ifndef NO_GARBAGE_COLLECTOR
-#define _opt_ss(_vm_) (_vm_)->_sharedstate
-#else
-#define _opt_ss(_vm_) NULL
-#endif
-
-#define PUSH_CALLINFO(v,nci){ \
- SQInteger css = v->_callsstacksize; \
- if(css == v->_alloccallsstacksize) { \
- v->GrowCallStack(); \
- } \
- v->ci = &v->_callsstack[css]; \
- *(v->ci) = nci; \
- v->_callsstacksize++; \
-}
-
-#define POP_CALLINFO(v){ \
- SQInteger css = --v->_callsstacksize; \
- v->ci->_closure.Null(); \
- v->ci = css?&v->_callsstack[css-1]:NULL; \
-}
-#endif //_SQVM_H_
+/* see copyright notice in squirrel.h */ +#ifndef _SQVM_H_ +#define _SQVM_H_ + +#include "sqopcodes.h" +#include "sqobject.h" +#define MAX_NATIVE_CALLS 100 +#define MIN_STACK_OVERHEAD 15 + +#define SQ_SUSPEND_FLAG -666 +#define DONT_FALL_BACK 666 +//base lib +void sq_base_register(HSQUIRRELVM v); + +struct SQExceptionTrap{ + SQExceptionTrap() {} + SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;} + SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; } + SQInteger _stackbase; + SQInteger _stacksize; + SQInstruction *_ip; + SQInteger _extarget; +}; + +#define _INLINE + +#define STK(a) _stack._vals[_stackbase+(a)] +#define TARGET _stack._vals[_stackbase+arg0] + +typedef sqvector<SQExceptionTrap> ExceptionsTraps; + +struct SQVM : public CHAINABLE_OBJ +{ + struct CallInfo{ + //CallInfo() { _generator = NULL;} + SQInstruction *_ip; + SQObjectPtr *_literals; + SQObjectPtr _closure; + SQGenerator *_generator; + SQInt32 _etraps; + SQInt32 _prevstkbase; + SQInt32 _prevtop; + SQInt32 _target; + SQInt32 _ncalls; + SQBool _root; + }; + +typedef sqvector<CallInfo> CallInfoVec; +public: + void DebugHookProxy(SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname); + static void _DebugHookProxy(HSQUIRRELVM v, SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname); + enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM,ET_RESUME_THROW_VM }; + SQVM(SQSharedState *ss); + ~SQVM(); + bool Init(SQVM *friendvm, SQInteger stacksize); + bool Execute(SQObjectPtr &func, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL); + //starts a native call return when the NATIVE closure returns + bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval,bool &suspend); + //starts a SQUIRREL call in the same "Execution loop" + bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall); + bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor); + //call a generic closure pure SQUIRREL or NATIVE + bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror); + SQRESULT Suspend(); + + void CallDebugHook(SQInteger type,SQInteger forcedline=0); + void CallErrorHandler(SQObjectPtr &e); + bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, SQInteger selfidx); + SQInteger FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest); + bool InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest); + bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, SQInteger selfidx); + SQInteger FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val); + bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic); + bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res); + bool Clone(const SQObjectPtr &self, SQObjectPtr &target); + bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res); + bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest); + static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res); + bool ToString(const SQObjectPtr &o,SQObjectPtr &res); + SQString *PrintObjVal(const SQObjectPtr &o); + + + void Raise_Error(const SQChar *s, ...); + void Raise_Error(const SQObjectPtr &desc); + void Raise_IdxError(const SQObjectPtr &o); + void Raise_CompareError(const SQObject &o1, const SQObject &o2); + void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type); + + void FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex); + void RelocateOuters(); + void CloseOuters(SQObjectPtr *stackindex); + + bool TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest); + bool CallMetaMethod(SQObjectPtr &closure, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres); + bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest); + bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval); + //new stuff + _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2); + _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2); + _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1); + _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res); + bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func); + bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs); + //return true if the loop is finished + bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump); + //_INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); + _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); + _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger arg0); +#ifdef _DEBUG_DUMP + void dumpstack(SQInteger stackbase=-1, bool dumpall = false); +#endif + +#ifndef NO_GARBAGE_COLLECTOR + void Mark(SQCollectable **chain); + SQObjectType GetType() {return OT_THREAD;} +#endif + void Finalize(); + void GrowCallStack() { + SQInteger newsize = _alloccallsstacksize*2; + _callstackdata.resize(newsize); + _callsstack = &_callstackdata[0]; + _alloccallsstacksize = newsize; + } + bool EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall); + void LeaveFrame(); + void Release(){ sq_delete(this,SQVM); } +//////////////////////////////////////////////////////////////////////////// + //stack functions for the api + void Remove(SQInteger n); + + static bool IsFalse(SQObjectPtr &o); + + void Pop(); + void Pop(SQInteger n); + void Push(const SQObjectPtr &o); + void PushNull(); + SQObjectPtr &Top(); + SQObjectPtr &PopGet(); + SQObjectPtr &GetUp(SQInteger n); + SQObjectPtr &GetAt(SQInteger n); + + SQObjectPtrVec _stack; + + SQInteger _top; + SQInteger _stackbase; + SQOuter *_openouters; + SQObjectPtr _roottable; + SQObjectPtr _lasterror; + SQObjectPtr _errorhandler; + + bool _debughook; + SQDEBUGHOOK _debughook_native; + SQObjectPtr _debughook_closure; + + SQObjectPtr temp_reg; + + + CallInfo* _callsstack; + SQInteger _callsstacksize; + SQInteger _alloccallsstacksize; + sqvector<CallInfo> _callstackdata; + + ExceptionsTraps _etraps; + CallInfo *ci; + void *_foreignptr; + //VMs sharing the same state + SQSharedState *_sharedstate; + SQInteger _nnativecalls; + SQInteger _nmetamethodscall; + //suspend infos + SQBool _suspended; + SQBool _suspended_root; + SQInteger _suspended_target; + SQInteger _suspended_traps; +}; + +struct AutoDec{ + AutoDec(SQInteger *n) { _n = n; } + ~AutoDec() { (*_n)--; } + SQInteger *_n; +}; + +inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));} + +#define _ss(_vm_) (_vm_)->_sharedstate + +#ifndef NO_GARBAGE_COLLECTOR +#define _opt_ss(_vm_) (_vm_)->_sharedstate +#else +#define _opt_ss(_vm_) NULL +#endif + +#define PUSH_CALLINFO(v,nci){ \ + SQInteger css = v->_callsstacksize; \ + if(css == v->_alloccallsstacksize) { \ + v->GrowCallStack(); \ + } \ + v->ci = &v->_callsstack[css]; \ + *(v->ci) = nci; \ + v->_callsstacksize++; \ +} + +#define POP_CALLINFO(v){ \ + SQInteger css = --v->_callsstacksize; \ + v->ci->_closure.Null(); \ + v->ci = css?&v->_callsstack[css-1]:NULL; \ +} +#endif //_SQVM_H_ diff --git a/tolua++-1.0.93/src/bin/toluabind.c b/tolua++-1.0.93/src/bin/toluabind.c index 70271fb3f..bf71cf158 100644 --- a/tolua++-1.0.93/src/bin/toluabind.c +++ b/tolua++-1.0.93/src/bin/toluabind.c @@ -7915,160 +7915,160 @@ TOLUA_API int tolua_tolua_open (lua_State* tolua_S) int top = lua_gettop(tolua_S); // _Xoft(o): hex dump of the lua/doit.lua file, generated by HxD static unsigned char B[] = { - 0x2D, 0x2D, 0x20, 0x47, 0x65, 0x6E, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20,
- 0x62, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x63, 0x6F, 0x64, 0x65,
- 0x0A, 0x2D, 0x2D, 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6E, 0x20,
- 0x62, 0x79, 0x20, 0x57, 0x61, 0x6C, 0x64, 0x65, 0x6D, 0x61, 0x72, 0x20,
- 0x43, 0x65, 0x6C, 0x65, 0x73, 0x0A, 0x2D, 0x2D, 0x20, 0x54, 0x65, 0x43,
- 0x47, 0x72, 0x61, 0x66, 0x2F, 0x50, 0x55, 0x43, 0x2D, 0x52, 0x69, 0x6F,
- 0x0A, 0x2D, 0x2D, 0x20, 0x4A, 0x75, 0x6C, 0x20, 0x31, 0x39, 0x39, 0x38,
- 0x0A, 0x2D, 0x2D, 0x20, 0x4C, 0x61, 0x73, 0x74, 0x20, 0x75, 0x70, 0x64,
- 0x61, 0x74, 0x65, 0x3A, 0x20, 0x41, 0x70, 0x72, 0x20, 0x32, 0x30, 0x30,
- 0x33, 0x0A, 0x2D, 0x2D, 0x20, 0x24, 0x49, 0x64, 0x3A, 0x20, 0x24, 0x0A,
- 0x0A, 0x0A, 0x2D, 0x2D, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6F,
- 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x73,
- 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x3B, 0x20, 0x79, 0x6F, 0x75,
- 0x20, 0x63, 0x61, 0x6E, 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72,
- 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6E, 0x64,
- 0x2F, 0x6F, 0x72, 0x20, 0x6D, 0x6F, 0x64, 0x69, 0x66, 0x79, 0x20, 0x69,
- 0x74, 0x2E, 0x0A, 0x2D, 0x2D, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6F,
- 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69,
- 0x64, 0x65, 0x64, 0x20, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6E, 0x64, 0x65,
- 0x72, 0x20, 0x69, 0x73, 0x20, 0x6F, 0x6E, 0x20, 0x61, 0x6E, 0x20, 0x22,
- 0x61, 0x73, 0x20, 0x69, 0x73, 0x22, 0x20, 0x62, 0x61, 0x73, 0x69, 0x73,
- 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x0A, 0x2D, 0x2D, 0x20, 0x74, 0x68, 0x65,
- 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x20, 0x68, 0x61, 0x73, 0x20,
- 0x6E, 0x6F, 0x20, 0x6F, 0x62, 0x6C, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F,
- 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69, 0x64, 0x65,
- 0x20, 0x6D, 0x61, 0x69, 0x6E, 0x74, 0x65, 0x6E, 0x61, 0x6E, 0x63, 0x65,
- 0x2C, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6F, 0x72, 0x74, 0x2C, 0x20, 0x75,
- 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x2C, 0x0A, 0x2D, 0x2D, 0x20, 0x65,
- 0x6E, 0x68, 0x61, 0x6E, 0x63, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x2C,
- 0x20, 0x6F, 0x72, 0x20, 0x6D, 0x6F, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61,
- 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x2E, 0x0A, 0x0A, 0x66, 0x75, 0x6E, 0x63,
- 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5F, 0x65,
- 0x78, 0x74, 0x72, 0x61, 0x28, 0x29, 0x0A, 0x0A, 0x09, 0x66, 0x6F, 0x72,
- 0x20, 0x6B, 0x2C, 0x76, 0x20, 0x69, 0x6E, 0x20, 0x69, 0x70, 0x61, 0x69,
- 0x72, 0x73, 0x28, 0x5F, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5F, 0x70, 0x61,
- 0x72, 0x61, 0x6D, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x6F, 0x72, 0x20,
- 0x7B, 0x7D, 0x29, 0x20, 0x64, 0x6F, 0x0A, 0x09, 0x09, 0x0A, 0x09, 0x09,
- 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x62, 0x2C, 0x65, 0x2C, 0x6E, 0x61,
- 0x6D, 0x65, 0x2C, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x73,
- 0x74, 0x72, 0x69, 0x6E, 0x67, 0x2E, 0x66, 0x69, 0x6E, 0x64, 0x28, 0x76,
- 0x2C, 0x20, 0x22, 0x5E, 0x28, 0x5B, 0x5E, 0x3D, 0x5D, 0x2A, 0x29, 0x3D,
- 0x28, 0x2E, 0x2A, 0x29, 0x24, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x69, 0x66,
- 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x09, 0x5F,
- 0x65, 0x78, 0x74, 0x72, 0x61, 0x5F, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x65,
- 0x74, 0x65, 0x72, 0x73, 0x5B, 0x6E, 0x61, 0x6D, 0x65, 0x5D, 0x20, 0x3D,
- 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x0A, 0x09, 0x09, 0x65, 0x6C, 0x73,
- 0x65, 0x0A, 0x09, 0x09, 0x09, 0x5F, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5F,
- 0x70, 0x61, 0x72, 0x61, 0x6D, 0x65, 0x74, 0x65, 0x72, 0x73, 0x5B, 0x76,
- 0x5D, 0x20, 0x3D, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0A, 0x09, 0x09, 0x65,
- 0x6E, 0x64, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x65, 0x6E, 0x64, 0x0A,
- 0x0A, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x64, 0x6F,
- 0x69, 0x74, 0x20, 0x28, 0x29, 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x64, 0x65,
- 0x66, 0x69, 0x6E, 0x65, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x61, 0x67, 0x65,
- 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x69, 0x66, 0x20, 0x6E, 0x6F,
- 0x74, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69, 0x64, 0x65, 0x64, 0x0A, 0x09,
- 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73,
- 0x2E, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x69, 0x66,
- 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x66, 0x20, 0x74, 0x68, 0x65,
- 0x6E, 0x0A, 0x09, 0x09, 0x09, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6E,
- 0x20, 0x3D, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x66, 0x6C, 0x61, 0x67,
- 0x73, 0x2E, 0x66, 0x2C, 0x22, 0x25, 0x2E, 0x2E, 0x2A, 0x24, 0x22, 0x2C,
- 0x22, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x5F, 0x2C, 0x5F, 0x2C, 0x66,
- 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6E, 0x20, 0x3D, 0x20, 0x73, 0x74, 0x72,
- 0x69, 0x6E, 0x67, 0x2E, 0x66, 0x69, 0x6E, 0x64, 0x28, 0x66, 0x6C, 0x61,
- 0x67, 0x73, 0x2E, 0x6E, 0x2C, 0x20, 0x22, 0x28, 0x5B, 0x5E, 0x2F, 0x5C,
- 0x5C, 0x5D, 0x2A, 0x29, 0x24, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6C,
- 0x73, 0x65, 0x0A, 0x09, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28,
- 0x22, 0x23, 0x6E, 0x6F, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x61, 0x67, 0x65,
- 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x6E, 0x6F, 0x72, 0x20, 0x69, 0x6E,
- 0x70, 0x75, 0x74, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x70, 0x72, 0x6F,
- 0x76, 0x69, 0x64, 0x65, 0x64, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6E,
- 0x64, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, 0x20,
- 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x20,
- 0x77, 0x69, 0x74, 0x68, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x20, 0x70,
- 0x61, 0x72, 0x61, 0x6D, 0x74, 0x65, 0x72, 0x73, 0x0A, 0x09, 0x70, 0x61,
- 0x72, 0x73, 0x65, 0x5F, 0x65, 0x78, 0x74, 0x72, 0x61, 0x28, 0x29, 0x0A,
- 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x64, 0x6F, 0x20, 0x74, 0x68, 0x69, 0x73,
- 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69,
- 0x6E, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x61,
- 0x67, 0x65, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x0A, 0x09, 0x69, 0x66, 0x20,
- 0x66, 0x6C, 0x61, 0x67, 0x73, 0x5B, 0x27, 0x4C, 0x27, 0x5D, 0x20, 0x74,
- 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x64, 0x6F, 0x66, 0x69, 0x6C, 0x65,
- 0x28, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x5B, 0x27, 0x4C, 0x27, 0x5D, 0x29,
- 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x61,
- 0x64, 0x64, 0x20, 0x63, 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67,
- 0x0A, 0x09, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x66, 0x6C, 0x61,
- 0x67, 0x73, 0x5B, 0x27, 0x53, 0x27, 0x5D, 0x20, 0x74, 0x68, 0x65, 0x6E,
- 0x0A, 0x09, 0x09, 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5B, 0x27, 0x73,
- 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x5D, 0x20, 0x3D, 0x20, 0x27, 0x63,
- 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x0A, 0x09, 0x09,
- 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5B, 0x27, 0x73, 0x74, 0x64, 0x3A,
- 0x3A, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x5D, 0x20, 0x3D, 0x20,
- 0x27, 0x63, 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x0A,
- 0x09, 0x09, 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5B, 0x27, 0x41, 0x53,
- 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x5D, 0x20, 0x3D, 0x20, 0x27, 0x63,
- 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x0A, 0x09, 0x09,
- 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5F, 0x63, 0x74, 0x79, 0x70, 0x65,
- 0x2E, 0x63, 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x3D,
- 0x20, 0x27, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72,
- 0x2A, 0x27, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D,
- 0x20, 0x70, 0x72, 0x6F, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x70, 0x61,
- 0x63, 0x6B, 0x61, 0x67, 0x65, 0x0A, 0x09, 0x6C, 0x6F, 0x63, 0x61, 0x6C,
- 0x20, 0x70, 0x20, 0x20, 0x3D, 0x20, 0x50, 0x61, 0x63, 0x6B, 0x61, 0x67,
- 0x65, 0x28, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6E, 0x2C, 0x66, 0x6C,
- 0x61, 0x67, 0x73, 0x2E, 0x66, 0x29, 0x0A, 0x0A, 0x09, 0x69, 0x66, 0x20,
- 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6E,
- 0x0A, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x20, 0x6F, 0x6E, 0x6C, 0x79,
- 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A,
- 0x0A, 0x09, 0x69, 0x66, 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6F,
- 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x6C, 0x6F, 0x63, 0x61,
- 0x6C, 0x20, 0x73, 0x74, 0x2C, 0x6D, 0x73, 0x67, 0x20, 0x3D, 0x20, 0x77,
- 0x72, 0x69, 0x74, 0x65, 0x74, 0x6F, 0x28, 0x66, 0x6C, 0x61, 0x67, 0x73,
- 0x2E, 0x6F, 0x29, 0x0A, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74,
- 0x20, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x09,
- 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x23, 0x27, 0x2E, 0x2E, 0x6D,
- 0x73, 0x67, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x09, 0x65,
- 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x70, 0x3A, 0x64, 0x65, 0x63, 0x6C, 0x74,
- 0x79, 0x70, 0x65, 0x28, 0x29, 0x0A, 0x09, 0x69, 0x66, 0x20, 0x66, 0x6C,
- 0x61, 0x67, 0x73, 0x2E, 0x50, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09,
- 0x09, 0x70, 0x3A, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x28, 0x29, 0x0A, 0x09,
- 0x65, 0x6C, 0x73, 0x65, 0x0A, 0x09, 0x09, 0x70, 0x75, 0x73, 0x68, 0x28,
- 0x70, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x72, 0x65, 0x5F, 0x6F, 0x75, 0x74,
- 0x70, 0x75, 0x74, 0x5F, 0x68, 0x6F, 0x6F, 0x6B, 0x28, 0x70, 0x29, 0x0A,
- 0x09, 0x09, 0x70, 0x6F, 0x70, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x3A,
- 0x70, 0x72, 0x65, 0x61, 0x6D, 0x62, 0x6C, 0x65, 0x28, 0x29, 0x0A, 0x09,
- 0x09, 0x70, 0x3A, 0x73, 0x75, 0x70, 0x63, 0x6F, 0x64, 0x65, 0x28, 0x29,
- 0x0A, 0x09, 0x09, 0x70, 0x75, 0x73, 0x68, 0x28, 0x70, 0x29, 0x0A, 0x09,
- 0x09, 0x70, 0x72, 0x65, 0x5F, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65,
- 0x72, 0x5F, 0x68, 0x6F, 0x6F, 0x6B, 0x28, 0x70, 0x29, 0x0A, 0x09, 0x09,
- 0x70, 0x6F, 0x70, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x3A, 0x72, 0x65,
- 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x70,
- 0x75, 0x73, 0x68, 0x28, 0x70, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x6F, 0x73,
- 0x74, 0x5F, 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5F, 0x68, 0x6F, 0x6F,
- 0x6B, 0x28, 0x70, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x6F, 0x70, 0x28, 0x29,
- 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x69, 0x66, 0x20, 0x66,
- 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A,
- 0x09, 0x09, 0x77, 0x72, 0x69, 0x74, 0x65, 0x74, 0x6F, 0x28, 0x29, 0x0A,
- 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x77, 0x72,
- 0x69, 0x74, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x66,
- 0x69, 0x6C, 0x65, 0x0A, 0x09, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20,
- 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x50, 0x20, 0x74, 0x68, 0x65, 0x6E,
- 0x0A, 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E,
- 0x48, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x09, 0x6C, 0x6F,
- 0x63, 0x61, 0x6C, 0x20, 0x73, 0x74, 0x2C, 0x6D, 0x73, 0x67, 0x20, 0x3D,
- 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x74, 0x6F, 0x28, 0x66, 0x6C, 0x61,
- 0x67, 0x73, 0x2E, 0x48, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20,
- 0x6E, 0x6F, 0x74, 0x20, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A,
- 0x09, 0x09, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x23,
- 0x27, 0x2E, 0x2E, 0x6D, 0x73, 0x67, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x65,
- 0x6E, 0x64, 0x0A, 0x09, 0x09, 0x09, 0x70, 0x3A, 0x68, 0x65, 0x61, 0x64,
- 0x65, 0x72, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x77, 0x72, 0x69, 0x74,
- 0x65, 0x74, 0x6F, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6E, 0x64, 0x0A,
- 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x65, 0x6E, 0x64, 0x0A, 0x0A
+ 0x2D, 0x2D, 0x20, 0x47, 0x65, 0x6E, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, + 0x62, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x63, 0x6F, 0x64, 0x65, + 0x0A, 0x2D, 0x2D, 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6E, 0x20, + 0x62, 0x79, 0x20, 0x57, 0x61, 0x6C, 0x64, 0x65, 0x6D, 0x61, 0x72, 0x20, + 0x43, 0x65, 0x6C, 0x65, 0x73, 0x0A, 0x2D, 0x2D, 0x20, 0x54, 0x65, 0x43, + 0x47, 0x72, 0x61, 0x66, 0x2F, 0x50, 0x55, 0x43, 0x2D, 0x52, 0x69, 0x6F, + 0x0A, 0x2D, 0x2D, 0x20, 0x4A, 0x75, 0x6C, 0x20, 0x31, 0x39, 0x39, 0x38, + 0x0A, 0x2D, 0x2D, 0x20, 0x4C, 0x61, 0x73, 0x74, 0x20, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x3A, 0x20, 0x41, 0x70, 0x72, 0x20, 0x32, 0x30, 0x30, + 0x33, 0x0A, 0x2D, 0x2D, 0x20, 0x24, 0x49, 0x64, 0x3A, 0x20, 0x24, 0x0A, + 0x0A, 0x0A, 0x2D, 0x2D, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6F, + 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x73, + 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x3B, 0x20, 0x79, 0x6F, 0x75, + 0x20, 0x63, 0x61, 0x6E, 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6E, 0x64, + 0x2F, 0x6F, 0x72, 0x20, 0x6D, 0x6F, 0x64, 0x69, 0x66, 0x79, 0x20, 0x69, + 0x74, 0x2E, 0x0A, 0x2D, 0x2D, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6F, + 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69, + 0x64, 0x65, 0x64, 0x20, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6E, 0x64, 0x65, + 0x72, 0x20, 0x69, 0x73, 0x20, 0x6F, 0x6E, 0x20, 0x61, 0x6E, 0x20, 0x22, + 0x61, 0x73, 0x20, 0x69, 0x73, 0x22, 0x20, 0x62, 0x61, 0x73, 0x69, 0x73, + 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x0A, 0x2D, 0x2D, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x20, 0x68, 0x61, 0x73, 0x20, + 0x6E, 0x6F, 0x20, 0x6F, 0x62, 0x6C, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69, 0x64, 0x65, + 0x20, 0x6D, 0x61, 0x69, 0x6E, 0x74, 0x65, 0x6E, 0x61, 0x6E, 0x63, 0x65, + 0x2C, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6F, 0x72, 0x74, 0x2C, 0x20, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x2C, 0x0A, 0x2D, 0x2D, 0x20, 0x65, + 0x6E, 0x68, 0x61, 0x6E, 0x63, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x2C, + 0x20, 0x6F, 0x72, 0x20, 0x6D, 0x6F, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x2E, 0x0A, 0x0A, 0x66, 0x75, 0x6E, 0x63, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5F, 0x65, + 0x78, 0x74, 0x72, 0x61, 0x28, 0x29, 0x0A, 0x0A, 0x09, 0x66, 0x6F, 0x72, + 0x20, 0x6B, 0x2C, 0x76, 0x20, 0x69, 0x6E, 0x20, 0x69, 0x70, 0x61, 0x69, + 0x72, 0x73, 0x28, 0x5F, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5F, 0x70, 0x61, + 0x72, 0x61, 0x6D, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x6F, 0x72, 0x20, + 0x7B, 0x7D, 0x29, 0x20, 0x64, 0x6F, 0x0A, 0x09, 0x09, 0x0A, 0x09, 0x09, + 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x62, 0x2C, 0x65, 0x2C, 0x6E, 0x61, + 0x6D, 0x65, 0x2C, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x20, 0x3D, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6E, 0x67, 0x2E, 0x66, 0x69, 0x6E, 0x64, 0x28, 0x76, + 0x2C, 0x20, 0x22, 0x5E, 0x28, 0x5B, 0x5E, 0x3D, 0x5D, 0x2A, 0x29, 0x3D, + 0x28, 0x2E, 0x2A, 0x29, 0x24, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x09, 0x5F, + 0x65, 0x78, 0x74, 0x72, 0x61, 0x5F, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x65, + 0x74, 0x65, 0x72, 0x73, 0x5B, 0x6E, 0x61, 0x6D, 0x65, 0x5D, 0x20, 0x3D, + 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x0A, 0x09, 0x09, 0x65, 0x6C, 0x73, + 0x65, 0x0A, 0x09, 0x09, 0x09, 0x5F, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5F, + 0x70, 0x61, 0x72, 0x61, 0x6D, 0x65, 0x74, 0x65, 0x72, 0x73, 0x5B, 0x76, + 0x5D, 0x20, 0x3D, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0A, 0x09, 0x09, 0x65, + 0x6E, 0x64, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x65, 0x6E, 0x64, 0x0A, + 0x0A, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x64, 0x6F, + 0x69, 0x74, 0x20, 0x28, 0x29, 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x64, 0x65, + 0x66, 0x69, 0x6E, 0x65, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x61, 0x67, 0x65, + 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x69, 0x66, 0x20, 0x6E, 0x6F, + 0x74, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69, 0x64, 0x65, 0x64, 0x0A, 0x09, + 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, + 0x2E, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x6E, 0x0A, 0x09, 0x09, 0x09, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6E, + 0x20, 0x3D, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x66, 0x6C, 0x61, 0x67, + 0x73, 0x2E, 0x66, 0x2C, 0x22, 0x25, 0x2E, 0x2E, 0x2A, 0x24, 0x22, 0x2C, + 0x22, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x5F, 0x2C, 0x5F, 0x2C, 0x66, + 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6E, 0x20, 0x3D, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6E, 0x67, 0x2E, 0x66, 0x69, 0x6E, 0x64, 0x28, 0x66, 0x6C, 0x61, + 0x67, 0x73, 0x2E, 0x6E, 0x2C, 0x20, 0x22, 0x28, 0x5B, 0x5E, 0x2F, 0x5C, + 0x5C, 0x5D, 0x2A, 0x29, 0x24, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6C, + 0x73, 0x65, 0x0A, 0x09, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, + 0x22, 0x23, 0x6E, 0x6F, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x61, 0x67, 0x65, + 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x6E, 0x6F, 0x72, 0x20, 0x69, 0x6E, + 0x70, 0x75, 0x74, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x70, 0x72, 0x6F, + 0x76, 0x69, 0x64, 0x65, 0x64, 0x22, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6E, + 0x64, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, 0x20, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x20, 0x70, + 0x61, 0x72, 0x61, 0x6D, 0x74, 0x65, 0x72, 0x73, 0x0A, 0x09, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x5F, 0x65, 0x78, 0x74, 0x72, 0x61, 0x28, 0x29, 0x0A, + 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x64, 0x6F, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, + 0x6E, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x61, + 0x67, 0x65, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x0A, 0x09, 0x69, 0x66, 0x20, + 0x66, 0x6C, 0x61, 0x67, 0x73, 0x5B, 0x27, 0x4C, 0x27, 0x5D, 0x20, 0x74, + 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x64, 0x6F, 0x66, 0x69, 0x6C, 0x65, + 0x28, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x5B, 0x27, 0x4C, 0x27, 0x5D, 0x29, + 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x61, + 0x64, 0x64, 0x20, 0x63, 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, + 0x0A, 0x09, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x66, 0x6C, 0x61, + 0x67, 0x73, 0x5B, 0x27, 0x53, 0x27, 0x5D, 0x20, 0x74, 0x68, 0x65, 0x6E, + 0x0A, 0x09, 0x09, 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5B, 0x27, 0x73, + 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x5D, 0x20, 0x3D, 0x20, 0x27, 0x63, + 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x0A, 0x09, 0x09, + 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5B, 0x27, 0x73, 0x74, 0x64, 0x3A, + 0x3A, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x5D, 0x20, 0x3D, 0x20, + 0x27, 0x63, 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x0A, + 0x09, 0x09, 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5B, 0x27, 0x41, 0x53, + 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x5D, 0x20, 0x3D, 0x20, 0x27, 0x63, + 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x27, 0x0A, 0x09, 0x09, + 0x5F, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5F, 0x63, 0x74, 0x79, 0x70, 0x65, + 0x2E, 0x63, 0x70, 0x70, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x3D, + 0x20, 0x27, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, + 0x2A, 0x27, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, + 0x20, 0x70, 0x72, 0x6F, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x70, 0x61, + 0x63, 0x6B, 0x61, 0x67, 0x65, 0x0A, 0x09, 0x6C, 0x6F, 0x63, 0x61, 0x6C, + 0x20, 0x70, 0x20, 0x20, 0x3D, 0x20, 0x50, 0x61, 0x63, 0x6B, 0x61, 0x67, + 0x65, 0x28, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6E, 0x2C, 0x66, 0x6C, + 0x61, 0x67, 0x73, 0x2E, 0x66, 0x29, 0x0A, 0x0A, 0x09, 0x69, 0x66, 0x20, + 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6E, + 0x0A, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2D, 0x2D, 0x20, 0x6F, 0x6E, 0x6C, 0x79, + 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, + 0x0A, 0x09, 0x69, 0x66, 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6F, + 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x6C, 0x6F, 0x63, 0x61, + 0x6C, 0x20, 0x73, 0x74, 0x2C, 0x6D, 0x73, 0x67, 0x20, 0x3D, 0x20, 0x77, + 0x72, 0x69, 0x74, 0x65, 0x74, 0x6F, 0x28, 0x66, 0x6C, 0x61, 0x67, 0x73, + 0x2E, 0x6F, 0x29, 0x0A, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, + 0x20, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x09, + 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x23, 0x27, 0x2E, 0x2E, 0x6D, + 0x73, 0x67, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x09, 0x65, + 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x70, 0x3A, 0x64, 0x65, 0x63, 0x6C, 0x74, + 0x79, 0x70, 0x65, 0x28, 0x29, 0x0A, 0x09, 0x69, 0x66, 0x20, 0x66, 0x6C, + 0x61, 0x67, 0x73, 0x2E, 0x50, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, + 0x09, 0x70, 0x3A, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x28, 0x29, 0x0A, 0x09, + 0x65, 0x6C, 0x73, 0x65, 0x0A, 0x09, 0x09, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x70, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x72, 0x65, 0x5F, 0x6F, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x5F, 0x68, 0x6F, 0x6F, 0x6B, 0x28, 0x70, 0x29, 0x0A, + 0x09, 0x09, 0x70, 0x6F, 0x70, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x3A, + 0x70, 0x72, 0x65, 0x61, 0x6D, 0x62, 0x6C, 0x65, 0x28, 0x29, 0x0A, 0x09, + 0x09, 0x70, 0x3A, 0x73, 0x75, 0x70, 0x63, 0x6F, 0x64, 0x65, 0x28, 0x29, + 0x0A, 0x09, 0x09, 0x70, 0x75, 0x73, 0x68, 0x28, 0x70, 0x29, 0x0A, 0x09, + 0x09, 0x70, 0x72, 0x65, 0x5F, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x5F, 0x68, 0x6F, 0x6F, 0x6B, 0x28, 0x70, 0x29, 0x0A, 0x09, 0x09, + 0x70, 0x6F, 0x70, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x3A, 0x72, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x70, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x6F, 0x73, + 0x74, 0x5F, 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5F, 0x68, 0x6F, 0x6F, + 0x6B, 0x28, 0x70, 0x29, 0x0A, 0x09, 0x09, 0x70, 0x6F, 0x70, 0x28, 0x29, + 0x0A, 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x69, 0x66, 0x20, 0x66, + 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, + 0x09, 0x09, 0x77, 0x72, 0x69, 0x74, 0x65, 0x74, 0x6F, 0x28, 0x29, 0x0A, + 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x0A, 0x09, 0x2D, 0x2D, 0x20, 0x77, 0x72, + 0x69, 0x74, 0x65, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x66, + 0x69, 0x6C, 0x65, 0x0A, 0x09, 0x69, 0x66, 0x20, 0x6E, 0x6F, 0x74, 0x20, + 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, 0x50, 0x20, 0x74, 0x68, 0x65, 0x6E, + 0x0A, 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x2E, + 0x48, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, 0x09, 0x09, 0x09, 0x6C, 0x6F, + 0x63, 0x61, 0x6C, 0x20, 0x73, 0x74, 0x2C, 0x6D, 0x73, 0x67, 0x20, 0x3D, + 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x74, 0x6F, 0x28, 0x66, 0x6C, 0x61, + 0x67, 0x73, 0x2E, 0x48, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, + 0x6E, 0x6F, 0x74, 0x20, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6E, 0x0A, + 0x09, 0x09, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x28, 0x27, 0x23, + 0x27, 0x2E, 0x2E, 0x6D, 0x73, 0x67, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x65, + 0x6E, 0x64, 0x0A, 0x09, 0x09, 0x09, 0x70, 0x3A, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x09, 0x77, 0x72, 0x69, 0x74, + 0x65, 0x74, 0x6F, 0x28, 0x29, 0x0A, 0x09, 0x09, 0x65, 0x6E, 0x64, 0x0A, + 0x09, 0x65, 0x6E, 0x64, 0x0A, 0x65, 0x6E, 0x64, 0x0A, 0x0A }; tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: src/bin/lua/doit.lua"); lua_settop(tolua_S, top); |