From 1702f4fe35a59d6fbeb6864902da168e2138a592 Mon Sep 17 00:00:00 2001 From: Chuck Miller Date: Wed, 16 Sep 2009 21:11:34 -0400 Subject: Allow for basic scripted monsters --- src/game-server/monster.cpp | 33 +++++++++++++++++++++++++++++++++ src/game-server/monster.hpp | 12 ++++++++++++ src/scripting/lua.cpp | 26 ++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) (limited to 'src') diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp index 2de90787..f7d2bac6 100644 --- a/src/game-server/monster.cpp +++ b/src/game-server/monster.cpp @@ -24,8 +24,10 @@ #include "game-server/character.hpp" #include "game-server/collisiondetection.hpp" #include "game-server/item.hpp" +#include "game-server/resourcemanager.hpp" #include "game-server/mapcomposite.hpp" #include "game-server/state.hpp" +#include "scripting/script.hpp" #include "utils/logger.h" #include @@ -60,6 +62,7 @@ static MonsterTargetEventDispatch monsterTargetEventDispatch; Monster::Monster(MonsterClass *specy): Being(OBJECT_MONSTER), mSpecy(specy), + mScript(NULL), mCountDown(0), mTargetListener(&monsterTargetEventDispatch), mOwner(NULL), @@ -94,6 +97,10 @@ 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::iterator i = mAnger.begin(), i_end = mAnger.end(); i != i_end; ++i) @@ -152,6 +159,13 @@ void Monster::update() } return; } + else if(mScript) + { + mScript->setMap(getMap()); + mScript->prepare("update"); + mScript->push(this); + mScript->execute(); + } if (mAction == ATTACK) { @@ -276,6 +290,25 @@ void Monster::update() } } +void Monster::loadScript(std::string &scriptName) +{ + if (mScript) + return; // A script has already been loaded for this monster + + std::stringstream filename; + filename << "scripts/monster/" << scriptName; + if (ResourceManager::exists(filename.str())) // file exists! + { + LOG_INFO("Loading monster script: " << filename.str()); + mScript = Script::create("lua"); + mScript->loadFile(filename.str()); + } else { + LOG_WARN("Could not find script file \"" << filename.str() << "\" for monster"); + } + + +} + int Monster::calculatePositionPriority(Point position, int targetPriority) { Point thisPos = getPosition(); diff --git a/src/game-server/monster.hpp b/src/game-server/monster.hpp index 21b6cf2c..8dc2102b 100644 --- a/src/game-server/monster.hpp +++ b/src/game-server/monster.hpp @@ -23,11 +23,13 @@ #include #include +#include #include "game-server/being.hpp" #include "game-server/eventlistener.hpp" class ItemClass; +class Script; /** * Structure containing an item class and its probability to be dropped @@ -234,6 +236,11 @@ class Monster : public Being */ void perform(); + /** + * Loads a script file for this monster + */ + void loadScript(std::string &scriptName); + /** * */ @@ -276,6 +283,11 @@ class Monster : public Being MonsterClass *mSpecy; + /** + * Stores script for the monster, null if no script exist + */ + Script *mScript; + /** Count down till next random movement (temporary). */ int mCountDown; diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index f82b581a..4b2513e6 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -777,6 +777,31 @@ static int monster_create(lua_State *s) return 1; } +/** + * tmw.monster_load_script(mob, scriptfilename) + * loads a LUA script given for mob + */ +static int monster_load_script(lua_State *s) +{ + Monster *m = static_cast< Monster* >(getBeing(s, 1)); + if (!m) + { + raiseScriptError(s, "monster_load_script called for a nonexistance monster."); + return 0; + } + + std::string scriptName(lua_tostring(s, 2)); + if (scriptName == "") + { + raiseScriptError(s, "monster_load_script called with incorrect parameters."); + return 0; + } + + m->loadScript(scriptName); + return 0; +} + + /** * Callback for getting a quest variable. Starts a recovery and returns * immediatly, if the variable is not known yet. @@ -1339,6 +1364,7 @@ LuaScript::LuaScript(): { "chr_get_hair_color", &chr_get_hair_color }, { "exp_for_level", &exp_for_level }, { "monster_create", &monster_create }, + { "monster_load_script", &monster_load_script }, { "being_apply_status", &being_apply_status }, { "being_remove_status", &being_remove_status }, { "being_has_status", &being_has_status }, -- cgit v1.2.3-70-g09d2