summaryrefslogtreecommitdiff
path: root/src/scripting
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-02-26 22:06:10 +0100
committerThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-03-02 18:12:07 +0100
commit34ac0d64e23f2b2d3981dbb0ea72157f334805dd (patch)
tree114b1f7a65956c097f7a59078292c9fa29c6451f /src/scripting
parente896d0b0125b48e12d43d99ace4498e56d968d50 (diff)
downloadmanaserv-34ac0d64e23f2b2d3981dbb0ea72157f334805dd.tar.gz
manaserv-34ac0d64e23f2b2d3981dbb0ea72157f334805dd.tar.bz2
manaserv-34ac0d64e23f2b2d3981dbb0ea72157f334805dd.tar.xz
manaserv-34ac0d64e23f2b2d3981dbb0ea72157f334805dd.zip
Merged all the different Lua states into one
No more Lua state for each status effect, monster, item effect or map. All scripts are loaded into the same state. This should be more efficient overall and make it easier to implement dynamic reloading of the scripts in the future. Now, this introduces the problem of name collisions between different Lua scripts. For now this is solved by using more specific function names, like 'tick_plague' and 'tick_jump' rather than just 'tick'. The plan is however to get rid of these globals, and register these callbacks from the script, so that they can be local functions without the danger of colliding with other scripts. Reviewed-by: Erik Schilling Reviewed-by: Yohann Ferreira
Diffstat (limited to 'src/scripting')
-rw-r--r--src/scripting/script.cpp90
-rw-r--r--src/scripting/script.h17
-rw-r--r--src/scripting/scriptmanager.cpp98
-rw-r--r--src/scripting/scriptmanager.h70
4 files changed, 168 insertions, 107 deletions
diff --git a/src/scripting/script.cpp b/src/scripting/script.cpp
index 722979fd..db44bd57 100644
--- a/src/scripting/script.cpp
+++ b/src/scripting/script.cpp
@@ -33,7 +33,6 @@
typedef std::map< std::string, Script::Factory > Engines;
static Engines *engines = NULL;
-Script *Script::globalEventScript = NULL;
Script::Script():
mMap(NULL),
@@ -107,92 +106,3 @@ void Script::loadNPC(const std::string &name, int id, int x, int y,
push(y);
execute();
}
-
-bool Script::loadGlobalEventScript(const std::string &file)
-{
- std::string engineName = determineEngineByFilename(file);
- if (Script *script = Script::create(engineName))
- {
- globalEventScript = script;
- return globalEventScript->loadFile(file);
- }
- return false;
-}
-
-bool Script::executeGlobalEventFunction(const std::string &function, Being* obj)
-{
- bool isScriptHandled = false;
- if (Script *script = globalEventScript)
- {
- script->setMap(obj->getMap());
- script->prepare(function);
- script->push(obj);
- script->execute();
- script->setMap(NULL);
- isScriptHandled = true; // TODO: don't set to true when execution failed
- }
- return isScriptHandled;
-}
-
-
-void Script::addDataToSpecial(int id, Special *special)
-{
- /* currently only gets the recharge cost.
- TODO: get any other info in a similar way, but
- first we have to agree on what other
- info we actually want to provide.
- */
- if (special)
- {
- if (Script *script = globalEventScript)
- {
- script->prepare("get_special_recharge_cost");
- script->push(id);
- int scriptReturn = script->execute();
- special->neededMana = scriptReturn;
- }
- }
-
-}
-
-bool Script::performSpecialAction(int specialId, Being *caster)
-{
- if (Script *script = globalEventScript)
- {
- script->prepare("use_special");
- script->push(caster);
- script->push(specialId);
- script->execute();
- }
- return true;
-}
-
-bool Script::performCraft(Being *crafter,
- const std::list<InventoryItem> &recipe)
-{
- if (Script *script = globalEventScript)
- {
- script->prepare("on_craft");
- script->push(crafter);
- script->push(recipe);
- script->execute();
- }
- return true;
-}
-
-std::string Script::determineEngineByFilename(const std::string &filename)
-{
- std::string ext = filename.substr(filename.find_last_of(".") + 1);
-
- if (ext == "lua")
- {
- return "lua";
- }
- else
- {
- // Set to default engine and print warning
- LOG_WARN("Unknown file extension for script \""
- + filename + "\", falling back to default script engine");
- return Configuration::getValue("script_defaultEngine", "lua");
- }
-}
diff --git a/src/scripting/script.h b/src/scripting/script.h
index a7737512..bd143114 100644
--- a/src/scripting/script.h
+++ b/src/scripting/script.h
@@ -135,21 +135,6 @@ class Script
virtual void processRemoveEvent(Thing *thing) = 0;
- /**
- * Loads the global event script file
- */
- static bool loadGlobalEventScript(const std::string &file);
-
- /**
- * Runs a function from the global event script file
- */
- static bool executeGlobalEventFunction(const std::string &function, Being *obj);
- static void addDataToSpecial(int specialId, Special *special);
- static bool performSpecialAction(int specialId, Being *caster);
- static bool performCraft(Being *crafter, const std::list<InventoryItem> &recipe);
-
- static std::string determineEngineByFilename(const std::string &filename);
-
protected:
std::string mScriptFile;
@@ -157,8 +142,6 @@ class Script
MapComposite *mMap;
EventListener mEventListener; /**< Tracking of being deaths. */
- static Script *globalEventScript;
-
friend struct ScriptEventDispatch;
};
diff --git a/src/scripting/scriptmanager.cpp b/src/scripting/scriptmanager.cpp
new file mode 100644
index 00000000..52515699
--- /dev/null
+++ b/src/scripting/scriptmanager.cpp
@@ -0,0 +1,98 @@
+/*
+ * The Mana Server
+ * Copyright (C) 2012 The Mana Developers
+ *
+ * This file is part of The Mana Server.
+ *
+ * The Mana Server is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana Server is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana Server. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "scriptmanager.h"
+
+#include "common/configuration.h"
+#include "scripting/script.h"
+
+static Script *_currentState;
+
+void ScriptManager::initialize()
+{
+ const std::string engine = Configuration::getValue("script_engine", "lua");
+ _currentState = Script::create(engine);
+}
+
+void ScriptManager::deinitialize()
+{
+ delete _currentState;
+ _currentState = 0;
+}
+
+bool ScriptManager::loadMainScript(const std::string &file)
+{
+ return _currentState->loadFile(file);
+}
+
+Script *ScriptManager::currentState()
+{
+ return _currentState;
+}
+
+// TODO: Have some generic event mechanism rather than calling global functions
+
+bool ScriptManager::executeGlobalEventFunction(const std::string &function, Being* obj)
+{
+ bool isScriptHandled = false;
+ _currentState->setMap(obj->getMap());
+ _currentState->prepare(function);
+ _currentState->push(obj);
+ _currentState->execute();
+ _currentState->setMap(NULL);
+ isScriptHandled = true; // TODO: don't set to true when execution failed
+ return isScriptHandled;
+}
+
+
+void ScriptManager::addDataToSpecial(int id, Special *special)
+{
+ /* currently only gets the recharge cost.
+ TODO: get any other info in a similar way, but
+ first we have to agree on what other
+ info we actually want to provide.
+ */
+ if (special)
+ {
+ _currentState->prepare("get_special_recharge_cost");
+ _currentState->push(id);
+ int scriptReturn = _currentState->execute();
+ special->neededMana = scriptReturn;
+ }
+}
+
+bool ScriptManager::performSpecialAction(int specialId, Being *caster)
+{
+ _currentState->prepare("use_special");
+ _currentState->push(caster);
+ _currentState->push(specialId);
+ _currentState->execute();
+ return true;
+}
+
+bool ScriptManager::performCraft(Being *crafter,
+ const std::list<InventoryItem> &recipe)
+{
+ _currentState->prepare("on_craft");
+ _currentState->push(crafter);
+ _currentState->push(recipe);
+ _currentState->execute();
+ return true;
+}
diff --git a/src/scripting/scriptmanager.h b/src/scripting/scriptmanager.h
new file mode 100644
index 00000000..7560c343
--- /dev/null
+++ b/src/scripting/scriptmanager.h
@@ -0,0 +1,70 @@
+/*
+ * The Mana Server
+ * Copyright (C) 2012 The Mana Developers
+ *
+ * This file is part of The Mana Server.
+ *
+ * The Mana Server is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana Server is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana Server. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SCRIPTMANAGER_H
+#define SCRIPTMANAGER_H
+
+#include "game-server/character.h"
+
+#include <string>
+
+class Script;
+class Special;
+
+/**
+ * Manages the script states. In fact at the moment it simply provides access
+ * to the single global script state, but in the future it is planned to allow
+ * reloading the scripts while the server is running, by keeping old script
+ * states around until they are no longer in use.
+ */
+namespace ScriptManager {
+
+/**
+ * Initializes the script manager by creating the script state.
+ */
+void initialize();
+
+/**
+ * Deinitializes the script manager by deleting the script state.
+ */
+void deinitialize();
+
+/**
+ * Loads the main script file.
+ */
+bool loadMainScript(const std::string &file);
+
+/**
+ * Returns the current global script state.
+ */
+Script *currentState();
+
+
+/**
+ * Runs a global function from the global event script file
+ */
+bool executeGlobalEventFunction(const std::string &function, Being *obj);
+void addDataToSpecial(int specialId, Special *special);
+bool performSpecialAction(int specialId, Being *caster);
+bool performCraft(Being *crafter, const std::list<InventoryItem> &recipe);
+
+} // namespace ScriptManager
+
+#endif // SCRIPTMANAGER_H