diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/game-server/character.cpp | 10 | ||||
-rw-r--r-- | src/game-server/commandhandler.cpp | 4 | ||||
-rw-r--r-- | src/game-server/item.cpp | 28 | ||||
-rw-r--r-- | src/game-server/item.h | 8 | ||||
-rw-r--r-- | src/game-server/itemmanager.cpp | 19 | ||||
-rw-r--r-- | src/game-server/main-game.cpp | 13 | ||||
-rw-r--r-- | src/game-server/mapcomposite.cpp | 57 | ||||
-rw-r--r-- | src/game-server/mapcomposite.h | 9 | ||||
-rw-r--r-- | src/game-server/monster.cpp | 42 | ||||
-rw-r--r-- | src/game-server/monster.h | 6 | ||||
-rw-r--r-- | src/game-server/state.cpp | 17 | ||||
-rw-r--r-- | src/game-server/statuseffect.cpp | 18 | ||||
-rw-r--r-- | src/game-server/statuseffect.h | 9 | ||||
-rw-r--r-- | src/game-server/statusmanager.cpp | 9 | ||||
-rw-r--r-- | src/scripting/script.cpp | 90 | ||||
-rw-r--r-- | src/scripting/script.h | 17 | ||||
-rw-r--r-- | src/scripting/scriptmanager.cpp | 98 | ||||
-rw-r--r-- | src/scripting/scriptmanager.h | 70 |
19 files changed, 259 insertions, 267 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1b5ad942..ecefab4f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -256,6 +256,8 @@ SET(SRCS_MANASERVGAME game-server/trigger.cpp scripting/script.h scripting/script.cpp + scripting/scriptmanager.h + scripting/scriptmanager.cpp utils/base64.h utils/base64.cpp utils/mathutils.h diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index 66fbd160..819da1c1 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -39,7 +39,7 @@ #include "game-server/skillmanager.h" #include "game-server/state.h" #include "game-server/trade.h" -#include "scripting/script.h" +#include "scripting/scriptmanager.h" #include "net/messagein.h" #include "net/messageout.h" #include "serialize/characterdata.h" @@ -197,7 +197,7 @@ void Character::perform() void Character::died() { Being::died(); - Script::executeGlobalEventFunction("on_chr_death", this); + ScriptManager::executeGlobalEventFunction("on_chr_death", this); } void Character::respawn() @@ -215,7 +215,7 @@ void Character::respawn() mTarget = NULL; // Execute respawn script - if (Script::executeGlobalEventFunction("on_chr_death_accept", this)) + if (ScriptManager::executeGlobalEventFunction("on_chr_death_accept", this)) return; // Script-controlled respawning didn't work - fall back to hardcoded logic. @@ -250,7 +250,7 @@ void Character::useSpecial(int id) //tell script engine to cast the spell special->currentMana = 0; - Script::performSpecialAction(id, this); + ScriptManager::performSpecialAction(id, this); mSpecialUpdateNeeded = true; return; } @@ -693,7 +693,7 @@ void Character::giveSpecial(int id) if (mSpecials.find(id) == mSpecials.end()) { Special *s = new Special(); - Script::addDataToSpecial(id, s); + ScriptManager::addDataToSpecial(id, s); mSpecials[id] = s; mSpecialUpdateNeeded = true; } diff --git a/src/game-server/commandhandler.cpp b/src/game-server/commandhandler.cpp index 6904e0fc..b59177ca 100644 --- a/src/game-server/commandhandler.cpp +++ b/src/game-server/commandhandler.cpp @@ -33,7 +33,7 @@ #include "game-server/monstermanager.h" #include "game-server/state.h" -#include "scripting/script.h" +#include "scripting/scriptmanager.h" #include "common/configuration.h" #include "common/permissionmanager.h" @@ -1408,7 +1408,7 @@ static void handleCraft(Character *player, std::string &args) // pass to script engine. The engine is responsible for all // further processing of the crafting operation, including // outputting an error message when the recipe is invalid. - Script::performCraft(player, recipe); + ScriptManager::performCraft(player, recipe); } } diff --git a/src/game-server/item.cpp b/src/game-server/item.cpp index 980db785..979a1bc3 100644 --- a/src/game-server/item.cpp +++ b/src/game-server/item.cpp @@ -30,6 +30,7 @@ #include "game-server/being.h" #include "game-server/state.h" #include "scripting/script.h" +#include "scripting/scriptmanager.h" bool ItemEffectAttrMod::apply(Being *itemUser) { @@ -59,18 +60,18 @@ void ItemEffectAutoAttack::dispell(Being *itemUser) ItemEffectScript::~ItemEffectScript() { - delete mScript; } bool ItemEffectScript::apply(Being *itemUser) { - if (mScript && !mActivateFunctionName.empty()) + if (!mActivateFunctionName.empty()) { - mScript->setMap(itemUser->getMap()); - mScript->prepare(mActivateFunctionName); - mScript->push(itemUser); - mScript->push(mItemId); - mScript->execute(); // TODO return depending on script execution success. + Script *script = ScriptManager::currentState(); + script->setMap(itemUser->getMap()); + script->prepare(mActivateFunctionName); + script->push(itemUser); + script->push(mItemId); + script->execute(); // TODO return depending on script execution success. return true; } return false; @@ -78,13 +79,14 @@ bool ItemEffectScript::apply(Being *itemUser) void ItemEffectScript::dispell(Being *itemUser) { - if (mScript && !mDispellFunctionName.empty()) + if (!mDispellFunctionName.empty()) { - mScript->setMap(itemUser->getMap()); - mScript->prepare(mDispellFunctionName); - mScript->push(itemUser); - mScript->push(mItemId); - mScript->execute(); + Script *script = ScriptManager::currentState(); + script->setMap(itemUser->getMap()); + script->prepare(mDispellFunctionName); + script->push(itemUser); + script->push(mItemId); + script->execute(); } } diff --git a/src/game-server/item.h b/src/game-server/item.h index f7c380f1..8cd3ce64 100644 --- a/src/game-server/item.h +++ b/src/game-server/item.h @@ -26,7 +26,6 @@ #include "game-server/actor.h" class Being; -class Script; // Indicates the equip slot "cost" to equip an item. struct ItemEquipRequirement { @@ -144,11 +143,10 @@ class ItemEffectConsumes : public ItemEffectInfo class ItemEffectScript : public ItemEffectInfo { public: - ItemEffectScript(int itemId, Script *script, + ItemEffectScript(int itemId, const std::string& activateFunctionName, const std::string& dispellFunctionName): - mItemId(0), - mScript(script), + mItemId(itemId), mActivateFunctionName(activateFunctionName), mDispellFunctionName(dispellFunctionName) {} @@ -157,9 +155,9 @@ class ItemEffectScript : public ItemEffectInfo bool apply(Being *itemUser); void dispell(Being *itemUser); + private: int mItemId; - Script *mScript; std::string mActivateFunctionName; std::string mDispellFunctionName; }; diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp index ffbdce89..b334760a 100644 --- a/src/game-server/itemmanager.cpp +++ b/src/game-server/itemmanager.cpp @@ -26,6 +26,7 @@ #include "game-server/item.h" #include "game-server/skillmanager.h" #include "scripting/script.h" +#include "scripting/scriptmanager.h" #include "utils/logger.h" #include <map> @@ -401,7 +402,7 @@ void ItemManager::readEffectNode(xmlNodePtr effectNode, ItemClass *item) } else if (xmlStrEqual(subNode->name, BAD_CAST "consumes")) { - item->addEffect(new ItemEffectConsumes(), triggerTypes.first); + item->addEffect(new ItemEffectConsumes, triggerTypes.first); } else if (xmlStrEqual(subNode->name, BAD_CAST "script")) { @@ -432,29 +433,19 @@ void ItemManager::readEffectNode(xmlNodePtr effectNode, ItemClass *item) } LOG_INFO("Loading item script: " << filename.str()); - - std::string engineName = - Script::determineEngineByFilename(filename.str()); - Script *script = Script::create(engineName); + Script *script = ScriptManager::currentState(); if (!script->loadFile(filename.str())) { - // Delete the script as it's invalid. - delete script; - LOG_WARN("Could not load script file \"" << filename.str() - << "\" for item #" << item->mDatabaseID); + << "\" for item #" << item->mDatabaseID); continue; } - for_each_xml_child_node(scriptSubNode, subNode) - { - // TODO: Load variables from variable subnodes - } std::string dispellFunctionName = XML::getProperty(subNode, "dispell-function", std::string()); - item->addEffect(new ItemEffectScript(item->mDatabaseID, script, + item->addEffect(new ItemEffectScript(item->mDatabaseID, activateFunctionName, dispellFunctionName), triggerTypes.first, diff --git a/src/game-server/main-game.cpp b/src/game-server/main-game.cpp index daf15611..c3b3c36a 100644 --- a/src/game-server/main-game.cpp +++ b/src/game-server/main-game.cpp @@ -52,7 +52,7 @@ #include "net/bandwidth.h" #include "net/connectionhandler.h" #include "net/messageout.h" -#include "scripting/luascript.h" +#include "scripting/scriptmanager.h" #include "utils/logger.h" #include "utils/processorutils.h" #include "utils/stringfilter.h" @@ -71,7 +71,7 @@ using utils::Logger; #define DEFAULT_MONSTERSDB_FILE "monsters.xml" #define DEFAULT_STATUSDB_FILE "status-effects.xml" #define DEFAULT_PERMISSION_FILE "permissions.xml" -#define DEFAULT_GLOBAL_EVENT_SCRIPT_FILE "scripts/main.lua" +#define DEFAULT_MAIN_SCRIPT_FILE "scripts/main.lua" static int const WORLD_TICK_SKIP = 2; /** tolerance for lagging behind in world calculation) **/ @@ -127,6 +127,7 @@ static void initializeServer() stringFilter = new utils::StringFilter; ResourceManager::initialize(); + ScriptManager::initialize(); // Depends on ResourceManager if (MapManager::initialize(DEFAULT_MAPSDB_FILE) < 1) { LOG_FATAL("The Game Server can't find any valid/available maps."); @@ -139,10 +140,9 @@ static void initializeServer() StatusManager::initialize(DEFAULT_STATUSDB_FILE); PermissionManager::initialize(DEFAULT_PERMISSION_FILE); - const std::string mainScriptFile = - Configuration::getValue("script_mainFile", - DEFAULT_GLOBAL_EVENT_SCRIPT_FILE); - Script::loadGlobalEventScript(mainScriptFile); + std::string mainScript = Configuration::getValue("script_mainFile", + DEFAULT_MAIN_SCRIPT_FILE); + ScriptManager::loadMainScript(mainScript); // --- Initialize the global handlers // FIXME: Make the global handlers global vars or part of a bigger @@ -194,6 +194,7 @@ static void deinitializeServer() delete itemManager; itemManager = 0; MapManager::deinitialize(); StatusManager::deinitialize(); + ScriptManager::deinitialize(); PHYSFS_deinit(); } diff --git a/src/game-server/mapcomposite.cpp b/src/game-server/mapcomposite.cpp index 99590566..c9090008 100644 --- a/src/game-server/mapcomposite.cpp +++ b/src/game-server/mapcomposite.cpp @@ -34,6 +34,7 @@ #include "game-server/spawnarea.h" #include "game-server/trigger.h" #include "scripting/script.h" +#include "scripting/scriptmanager.h" #include "utils/logger.h" #include "utils/point.h" @@ -458,7 +459,6 @@ MapZone& MapContent::getZone(const Point &pos) const MapComposite::MapComposite(int id, const std::string &name): mMap(NULL), mContent(NULL), - mScript(NULL), mName(name), mID(id) { @@ -468,7 +468,6 @@ MapComposite::~MapComposite() { delete mMap; delete mContent; - delete mScript; } bool MapComposite::activate() @@ -494,12 +493,10 @@ bool MapComposite::activate() else mPvPRules = PVP_NONE; - if (Script *s = getScript()) - { - s->setMap(this); - s->prepare("initialize"); - s->execute(); - } + Script *s = ScriptManager::currentState(); + s->setMap(this); + s->prepare("initialize"); + s->execute(); return true; } @@ -730,25 +727,12 @@ void MapComposite::initializeContent() int npcId = utils::stringToInt(object->getProperty("NPC_ID")); std::string scriptText = object->getProperty("SCRIPT"); - if (!mScript) - { - // Determine script engine by xml property - std::string scriptEngineName = object->getProperty("ENGINE"); - if (scriptEngineName.empty()) - { - // Set engine to default value and print warning - scriptEngineName = Configuration::getValue("script_defaultEngine", "lua"); - LOG_WARN("No script engine specified for map script \"" - + mName + "\", falling back to default"); - } - mScript = Script::create(scriptEngineName); - } - if (npcId && !scriptText.empty()) { - mScript->loadNPC(object->getName(), npcId, - object->getX(), object->getY(), - scriptText.c_str()); + Script *script = ScriptManager::currentState(); + script->loadNPC(object->getName(), npcId, + object->getX(), object->getY(), + scriptText.c_str()); } else { @@ -760,33 +744,16 @@ void MapComposite::initializeContent() std::string scriptFilename = object->getProperty("FILENAME"); std::string scriptText = object->getProperty("TEXT"); - if (!mScript) - { - // Determine script engine by xml property - std::string scriptEngineName = object->getProperty("ENGINE"); - if (!scriptFilename.empty() && scriptEngineName.empty()) - { - // Engine property is empty - determine by filename - scriptEngineName = Script::determineEngineByFilename(scriptFilename); - } - else if (scriptEngineName.empty()) - { - // Set engine to default value and print warning - scriptEngineName = Configuration::getValue("script_defaultEngine", "lua"); - LOG_WARN("No script engine specified for map script \"" - + mName + "\", falling back to default"); - } - mScript = Script::create(scriptEngineName); - } + Script *script = ScriptManager::currentState(); if (!scriptFilename.empty()) { - mScript->loadFile(scriptFilename); + script->loadFile(scriptFilename); } else if (!scriptText.empty()) { std::string name = "'" + object->getName() + "'' in " + mName; - mScript->load(scriptText.c_str(), name.c_str()); + script->load(scriptText.c_str(), name.c_str()); } else { diff --git a/src/game-server/mapcomposite.h b/src/game-server/mapcomposite.h index 988b0ed8..49296911 100644 --- a/src/game-server/mapcomposite.h +++ b/src/game-server/mapcomposite.h @@ -33,7 +33,6 @@ class Map; class MapComposite; class Point; class Rectangle; -class Script; class Thing; struct MapContent; @@ -249,13 +248,6 @@ class MapComposite { return mMap; } /** - * Gets the associated script. Returns 0 when no scripts or inline - * NPCs are used on this map! - */ - Script *getScript() const - { return mScript; } - - /** * Returns whether the map is active on this server or not. */ bool isActive() const @@ -351,7 +343,6 @@ class MapComposite Map *mMap; /**< Actual map. */ MapContent *mContent; /**< Entities on the map. */ - Script *mScript; /**< Script associated to this map. */ std::string mName; /**< Name of the map. */ unsigned short mID; /**< ID of the map. */ /** Cached persistent variables */ diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp index 6e40fb24..21eeea7c 100644 --- a/src/game-server/monster.cpp +++ b/src/game-server/monster.cpp @@ -29,6 +29,7 @@ #include "game-server/mapcomposite.h" #include "game-server/state.h" #include "scripting/script.h" +#include "scripting/scriptmanager.h" #include "utils/logger.h" #include "utils/speedconv.h" @@ -49,7 +50,6 @@ static MonsterTargetEventDispatch monsterTargetEventDispatch; Monster::Monster(MonsterClass *specy): Being(OBJECT_MONSTER), mSpecy(specy), - mScript(NULL), mTargetListener(&monsterTargetEventDispatch), mOwner(NULL), mCurrentAttack(NULL) @@ -108,10 +108,6 @@ Monster::Monster(MonsterClass *specy): Monster::~Monster() { - // Remove the monster's script if it has one - if (mScript) - delete mScript; - // Remove death listeners. for (std::map<Being *, int>::iterator i = mAnger.begin(), i_end = mAnger.end(); i != i_end; ++i) @@ -145,15 +141,15 @@ void Monster::perform() int hit = performAttack(mTarget, dmg); if (! mCurrentAttack->scriptFunction.empty() - && mScript && hit > -1) { - mScript->setMap(getMap()); - mScript->prepare(mCurrentAttack->scriptFunction); - mScript->push(this); - mScript->push(mTarget); - mScript->push(hit); - mScript->execute(); + Script *script = ScriptManager::currentState(); + script->setMap(getMap()); + script->prepare(mCurrentAttack->scriptFunction); + script->push(this); + script->push(mTarget); + script->push(hit); + script->execute(); } } } @@ -183,13 +179,12 @@ void Monster::update() } return; } - else if(mScript) - { - mScript->setMap(getMap()); - mScript->prepare("update"); - mScript->push(this); - mScript->execute(); - } + + Script *script = ScriptManager::currentState(); + script->setMap(getMap()); + script->prepare("update_monster"); + script->push(this); + script->execute(); // Cancel the rest when we are currently performing an attack if (isTimerRunning(T_M_ATTACK_TIME)) @@ -324,10 +319,6 @@ void Monster::update() void Monster::loadScript(const std::string &scriptName) { - // A script may have already been loaded for this monster - delete mScript; - mScript = 0; - if (scriptName.length() == 0) return; @@ -336,10 +327,7 @@ void Monster::loadScript(const std::string &scriptName) if (ResourceManager::exists(filename.str())) { LOG_INFO("Loading monster script: " << filename.str()); - std::string engineName = - Script::determineEngineByFilename(filename.str()); - mScript = Script::create(engineName); - mScript->loadFile(filename.str()); + ScriptManager::currentState()->loadFile(filename.str()); } else { diff --git a/src/game-server/monster.h b/src/game-server/monster.h index fe68a8a8..37bbe355 100644 --- a/src/game-server/monster.h +++ b/src/game-server/monster.h @@ -328,12 +328,6 @@ class Monster : public Being MonsterClass *mSpecy; - /** - * Stores individual script for the monster, when NULL the script - * from mSpecy is used. - */ - Script *mScript; - /** Aggression towards other beings. */ std::map<Being *, int> mAnger; diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index 930c475b..471cc7c3 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -37,6 +37,7 @@ #include "game-server/trade.h" #include "net/messageout.h" #include "scripting/script.h" +#include "scripting/scriptmanager.h" #include "utils/logger.h" #include "utils/point.h" #include "utils/speedconv.h" @@ -75,7 +76,7 @@ static std::map< std::string, std::string > mScriptVariables; */ static void updateMap(MapComposite *map) { - // 1. update object status. + // Update object status const std::vector< Thing * > &things = map->getEverything(); for (std::vector< Thing * >::const_iterator it = things.begin(), it_end = things.end(); it != it_end; ++it) @@ -83,19 +84,13 @@ static void updateMap(MapComposite *map) (*it)->update(); } - // 2. run scripts. - if (Script *s = map->getScript()) - { - s->update(); - } - - // 3. perform actions. + // Perform actions for (BeingIterator it(map->getWholeMapIterator()); it; ++it) { (*it)->perform(); } - // 4. move objects around and update zones. + // Move objects around and update zones. for (BeingIterator it(map->getWholeMapIterator()); it; ++it) { (*it)->move(); @@ -450,6 +445,8 @@ void GameState::update(int worldTime) dbgLockObjects = true; # endif + ScriptManager::currentState()->update(); + // Update game state (update AI, etc.) const MapManager::Maps &maps = MapManager::getMaps(); for (MapManager::Maps::const_iterator m = maps.begin(), @@ -457,9 +454,7 @@ void GameState::update(int worldTime) { MapComposite *map = m->second; if (!map->isActive()) - { continue; - } updateMap(map); diff --git a/src/game-server/statuseffect.cpp b/src/game-server/statuseffect.cpp index 9f917110..32e0d621 100644 --- a/src/game-server/statuseffect.cpp +++ b/src/game-server/statuseffect.cpp @@ -21,27 +21,27 @@ #include "game-server/statuseffect.h" #include "scripting/script.h" +#include "scripting/scriptmanager.h" #include "game-server/being.h" StatusEffect::StatusEffect(int id): - mId(id), - mScript(0) + mId(id) { } StatusEffect::~StatusEffect() { - delete mScript; } void StatusEffect::tick(Being *target, int count) { - if (mScript) + if (!mTickFunction.empty()) { - mScript->setMap(target->getMap()); - mScript->prepare("tick"); - mScript->push(target); - mScript->push(count); - mScript->execute(); + Script *script = ScriptManager::currentState(); + script->setMap(target->getMap()); + script->prepare(mTickFunction); + script->push(target); + script->push(count); + script->execute(); } } diff --git a/src/game-server/statuseffect.h b/src/game-server/statuseffect.h index 3aa4d843..2b7a36f8 100644 --- a/src/game-server/statuseffect.h +++ b/src/game-server/statuseffect.h @@ -21,7 +21,8 @@ #ifndef STATUSEFFECT_H #define STATUSEFFECT_H -class Script; +#include <string> + class Being; class StatusEffect @@ -35,12 +36,12 @@ class StatusEffect int getId() const { return mId; } - void setScript(Script *script) - { mScript = script; } + void setTickFunction(const std::string &tickFunction) + { mTickFunction = tickFunction; } private: int mId; - Script *mScript; + std::string mTickFunction; }; #endif diff --git a/src/game-server/statusmanager.cpp b/src/game-server/statusmanager.cpp index 66c2642a..15203d65 100644 --- a/src/game-server/statusmanager.cpp +++ b/src/game-server/statusmanager.cpp @@ -23,6 +23,7 @@ #include "common/resourcemanager.h" #include "game-server/statuseffect.h" #include "scripting/script.h" +#include "scripting/scriptmanager.h" #include "utils/logger.h" #include "utils/xml.h" @@ -68,6 +69,8 @@ void StatusManager::reload() } std::string scriptFile = XML::getProperty(node, "script", std::string()); + std::string tickFunction = XML::getProperty(node, "tick-function", + std::string()); //TODO: Get these modifiers /* modifiers.setAttributeValue(BASE_ATTR_PHY_ATK_MIN, XML::getProperty(node, "attack-min", 0)); @@ -82,6 +85,7 @@ void StatusManager::reload() modifiers.setAttributeValue(CHAR_ATTR_WILLPOWER, XML::getProperty(node, "willpower", 0)); */ StatusEffect *statusEffect = new StatusEffect(id); + statusEffect->setTickFunction(tickFunction); if (!scriptFile.empty()) { std::stringstream filename; @@ -89,11 +93,8 @@ void StatusManager::reload() if (ResourceManager::exists(filename.str())) // file exists! { LOG_INFO("Loading status script: " << filename.str()); - std::string engineName = - Script::determineEngineByFilename(filename.str()); - Script *s = Script::create(engineName); + Script *s = ScriptManager::currentState(); s->loadFile(filename.str()); - statusEffect->setScript(s); } else { LOG_WARN("Could not find script file \"" << filename.str() << "\" for status #"<<id); 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 |