#include "guiscalingfilter.h"
#include "script/scripting_client.h"
#include "game.h"
+#include "chatmessage.h"
extern gui::IGUIEnvironment* guienv;
m_script->setEnv(&m_env);
}
-void Client::initMods()
+void Client::loadMods()
{
- m_script->loadMod(getBuiltinLuaPath() + DIR_DELIM "init.lua", BUILTIN_MOD_NAME);
+ // Load builtin
+ scanModIntoMemory(BUILTIN_MOD_NAME, getBuiltinLuaPath());
// If modding is not enabled, don't load mods, just builtin
if (!m_modding_enabled) {
return;
}
-
ClientModConfiguration modconf(getClientModsLuaPath());
- std::vector<ModSpec> mods = modconf.getMods();
+ m_mods = modconf.getMods();
std::vector<ModSpec> unsatisfied_mods = modconf.getUnsatisfiedMods();
// complain about mods with unsatisfied dependencies
if (!modconf.isConsistent()) {
// Print mods
infostream << "Client Loading mods: ";
- for (std::vector<ModSpec>::const_iterator i = mods.begin();
- i != mods.end(); ++i) {
- infostream << (*i).name << " ";
- }
-
+ for (const ModSpec &mod : m_mods)
+ infostream << mod.name << " ";
infostream << std::endl;
+
// Load and run "mod" scripts
- for (std::vector<ModSpec>::const_iterator it = mods.begin();
- it != mods.end(); ++it) {
- const ModSpec &mod = *it;
+ for (const ModSpec &mod : m_mods) {
if (!string_allowed(mod.name, MODNAME_ALLOWED_CHARS)) {
throw ModError("Error loading mod \"" + mod.name +
"\": Mod name does not follow naming conventions: "
"Only characters [a-z0-9_] are allowed.");
}
- std::string script_path = mod.path + DIR_DELIM + "init.lua";
- infostream << " [" << padStringRight(mod.name, 12) << "] [\""
- << script_path << "\"]" << std::endl;
- m_script->loadMod(script_path, mod.name);
+ scanModIntoMemory(mod.name, mod.path);
+ }
+}
+
+void Client::scanModSubfolder(const std::string &mod_name, const std::string &mod_path,
+ std::string mod_subpath)
+{
+ std::string full_path = mod_path + DIR_DELIM + mod_subpath;
+ std::vector<fs::DirListNode> mod = fs::GetDirListing(full_path);
+ for (unsigned int j=0; j < mod.size(); j++){
+ std::string filename = mod[j].name;
+ if (mod[j].dir) {
+ scanModSubfolder(mod_name, mod_path, mod_subpath
+ + filename + DIR_DELIM);
+ continue;
+ }
+ std::replace( mod_subpath.begin(), mod_subpath.end(), DIR_DELIM_CHAR, '/');
+ m_mod_files[mod_name + ":" + mod_subpath + filename] = full_path + filename;
}
}
+void Client::initMods()
+{
+ m_script->loadModFromMemory(BUILTIN_MOD_NAME);
+
+ // If modding is not enabled, don't load mods, just builtin
+ if (!m_modding_enabled) {
+ return;
+ }
+
+ // Load and run "mod" scripts
+ for (const ModSpec &mod : m_mods)
+ m_script->loadModFromMemory(mod.name);
+}
+
const std::string &Client::getBuiltinLuaPath()
{
static const std::string builtin_dir = porting::path_share + DIR_DELIM + "builtin";
// Control local player (0ms)
LocalPlayer *player = m_env.getLocalPlayer();
assert(player);
- player->applyControl(dtime);
+ player->applyControl(dtime, &m_env);
// Step environment
m_env.step(dtime);
}
}
+/**
+ * Helper function for Client Side Modding
+ * Flavour is applied there, this should not be used for core engine
+ * @param p
+ * @param is_valid_position
+ * @return
+ */
MapNode Client::getNode(v3s16 p, bool *is_valid_position)
{
+ if (checkCSMFlavourLimit(CSMFlavourLimit::CSM_FL_LOOKUP_NODES)) {
+ v3s16 ppos = floatToInt(m_env.getLocalPlayer()->getPosition(), BS);
+ if ((u32) ppos.getDistanceFrom(p) > m_csm_noderange_limit) {
+ *is_valid_position = false;
+ return MapNode();
+ }
+ }
return m_env.getMap().getNodeNoEx(p, is_valid_position);
}
return player->hp;
}
-bool Client::getChatMessage(std::wstring &message)
+bool Client::getChatMessage(std::wstring &res)
{
- if(m_chat_queue.size() == 0)
+ if (m_chat_queue.empty())
return false;
- message = m_chat_queue.front();
+
+ ChatMessage *chatMessage = m_chat_queue.front();
m_chat_queue.pop();
+
+ res = L"";
+
+ switch (chatMessage->type) {
+ case CHATMESSAGE_TYPE_RAW:
+ case CHATMESSAGE_TYPE_ANNOUNCE:
+ case CHATMESSAGE_TYPE_SYSTEM:
+ res = chatMessage->message;
+ break;
+ case CHATMESSAGE_TYPE_NORMAL: {
+ if (!chatMessage->sender.empty())
+ res = L"<" + chatMessage->sender + L"> " + chatMessage->message;
+ else
+ res = chatMessage->message;
+ break;
+ }
+ default:
+ break;
+ }
+
+ delete chatMessage;
return true;
}
sendChatMessage(message);
// Show locally
- if (message[0] != L'/')
- {
+ if (message[0] != L'/') {
// compatibility code
if (m_proto_ver < 29) {
LocalPlayer *player = m_env.getLocalPlayer();
assert(player);
std::wstring name = narrow_to_wide(player->getName());
- pushToChatQueue((std::wstring)L"<" + name + L"> " + message);
+ pushToChatQueue(new ChatMessage(CHATMESSAGE_TYPE_NORMAL, message, name));
}
}
}
} else {
sstr << "Failed to save screenshot '" << filename << "'";
}
- pushToChatQueue(narrow_to_wide(sstr.str()));
+ pushToChatQueue(new ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
+ narrow_to_wide(sstr.str())));
infostream << sstr.str() << std::endl;
image->drop();
}
return mesh;
}
+const std::string* Client::getModFile(const std::string &filename)
+{
+ StringMap::const_iterator it = m_mod_files.find(filename);
+ if (it == m_mod_files.end()) {
+ errorstream << "Client::getModFile(): File not found: \"" << filename
+ << "\"" << std::endl;
+ return NULL;
+ }
+ return &it->second;
+}
+
bool Client::registerModStorage(ModMetadata *storage)
{
if (m_mod_storages.find(storage->getModName()) != m_mod_storages.end()) {