diff options
author | Erik Schilling <ablu.erikschilling@googlemail.com> | 2012-04-03 13:29:05 +0200 |
---|---|---|
committer | Erik Schilling <ablu.erikschilling@googlemail.com> | 2012-04-04 16:22:11 +0200 |
commit | f8e816d9185c09d1c17d921b775e483d132982e5 (patch) | |
tree | 3ab299ab6057db3bfd8feb24130a6fcb7e64a60d /src/scripting | |
parent | e4baa92aae537921dd17873328a95ab17afcfdfc (diff) | |
download | manaserv-f8e816d9185c09d1c17d921b775e483d132982e5.tar.gz manaserv-f8e816d9185c09d1c17d921b775e483d132982e5.tar.bz2 manaserv-f8e816d9185c09d1c17d921b775e483d132982e5.tar.xz manaserv-f8e816d9185c09d1c17d921b775e483d132982e5.zip |
Enhanced special support
- Made the current charge being saved.
- Added script binds:
- chr_set_special_recharge_speed
- chr_get_special_recharge_speed
- chr_set_special_mana
- chr_get_special_mana
- get_special_info
- Added special info lua class. Functions:
- name
- needed_mana
- rechargeable
- on_use
- on_recharged
- category
Further the engine no longer sets charge to 0 after using of specials
this allows more flexbilillity (like failing specials).
Changes on the xml database:
- recharge renamed to rechargeable (needed by client and server)
- needed - the needed mana to trigger a special (server only)
- rechargespeed - the defailt recharge speed in mana per tick (server only)
- target - the type of target (either being or point) (server and client)
I also made the lua engine pushing nil instead of a 0 light userdata when
the pointer was 0.
Database update needed.
Change is tested.
Mana-Mantis: #167, #156
Reviewed-by: bjorn.
Diffstat (limited to 'src/scripting')
-rw-r--r-- | src/scripting/lua.cpp | 140 | ||||
-rw-r--r-- | src/scripting/luascript.cpp | 5 | ||||
-rw-r--r-- | src/scripting/luautil.cpp | 23 | ||||
-rw-r--r-- | src/scripting/luautil.h | 4 | ||||
-rw-r--r-- | src/scripting/scriptmanager.cpp | 33 | ||||
-rw-r--r-- | src/scripting/scriptmanager.h | 3 |
6 files changed, 162 insertions, 46 deletions
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 2d98c713..47672659 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -1819,9 +1819,10 @@ static int chr_give_special(lua_State *s) { // cost_type is ignored until we have more than one cost type Character *c = checkCharacter(s, 1); - const int special = luaL_checkint(s, 2); + const int special = checkSpecial(s, 2); + const int currentMana = luaL_optint(s, 3, 0); - c->giveSpecial(special); + c->giveSpecial(special, currentMana); return 0; } @@ -1853,6 +1854,70 @@ static int chr_take_special(lua_State *s) } /** + * chr_set_special_recharge_speed(Character*, int special, int speed) + * Sets recharge speed for a special. + */ +static int chr_set_special_recharge_speed(lua_State *s) +{ + Character *c = checkCharacter(s, 1); + const int special = checkSpecial(s, 2); + const int speed = luaL_checkint(s, 3); + + if (c->setSpecialRechargeSpeed(special, speed)) + raiseScriptError(s, "chr_set_special_mana called with special " + "that is not owned by character."); + return 0; +} + +/** + * chr_get_special_recharge_speed(Character*, int special) + * Gets recharge speed of a special. + */ +static int chr_get_special_recharge_speed(lua_State *s) +{ + Character *c = checkCharacter(s, 1); + const int special = checkSpecial(s, 2); + + SpecialMap::iterator it = c->findSpecial(special); + + luaL_argcheck(s, it != c->getSpecialEnd(), 2, + "character does not have special"); + + lua_pushinteger(s, it->second.rechargeSpeed); + return 1; +} + +/** + * chr_set_special_mana(Character*, int special, int mana) + * Sets the current charge of the special. + */ +static int chr_set_special_mana(lua_State *s) +{ + Character *c = checkCharacter(s, 1); + const int special = checkSpecial(s, 2); + const int mana = luaL_checkint(s, 3); + if (!c->setSpecialMana(special, mana)) + raiseScriptError(s, "chr_set_special_mana called with special " + "that is not owned by character."); + return 0; +} + +/** + * chr_get_special_mana(Character*, int special): int + * Gets the current charge of a special. + */ +static int chr_get_special_mana(lua_State *s) +{ + Character *c = checkCharacter(s, 1); + const int special = checkSpecial(s, 2); + SpecialMap::iterator it = c->findSpecial(special); + luaL_argcheck(s, it != c->getSpecialEnd(), 2, + "character does not have special"); + lua_pushinteger(s, it->second.currentMana); + return 1; +} + +/** * chr_get_rights(Character*): int * Returns the rights level of a character. */ @@ -2207,6 +2272,61 @@ static int announce(lua_State *s) return 0; } +static int get_special_info(lua_State *s) +{ + const int special = checkSpecial(s, 1); + SpecialManager::SpecialInfo *info = specialManager->getSpecialInfo(special); + luaL_argcheck(s, info, 1, "invalid special"); + LuaSpecialInfo::push(s, info); + return 1; +} + +static int specialinfo_get_name(lua_State *s) +{ + SpecialManager::SpecialInfo *info = LuaSpecialInfo::check(s, 1); + lua_pushstring(s, info->name.c_str()); + return 1; +} + +static int specialinfo_get_needed_mana(lua_State *s) +{ + SpecialManager::SpecialInfo *info = LuaSpecialInfo::check(s, 1); + lua_pushinteger(s, info->neededMana); + return 1; +} + +static int specialinfo_is_rechargeable(lua_State *s) +{ + SpecialManager::SpecialInfo *info = LuaSpecialInfo::check(s, 1); + lua_pushboolean(s, info->rechargeable); + return 1; +} + +static int specialinfo_get_category(lua_State *s) +{ + SpecialManager::SpecialInfo *info = LuaSpecialInfo::check(s, 1); + lua_pushstring(s, info->setName.c_str()); + return 1; +} + +static int specialinfo_on_recharged(lua_State *s) +{ + SpecialManager::SpecialInfo *info = LuaSpecialInfo::check(s, 1); + Script *script = getScript(s); + luaL_checktype(s, 2, LUA_TFUNCTION); + script->assignCallback(info->rechargedCallback); + return 0; +} + +static int specialinfo_on_use(lua_State *s) +{ + SpecialManager::SpecialInfo *info = LuaSpecialInfo::check(s, 1); + Script *script = getScript(s); + luaL_checktype(s, 2, LUA_TFUNCTION); + script->assignCallback(info->useCallback); + return 0; +} + static int require_loader(lua_State *s) { // Add .lua extension (maybe only do this when it doesn't have it already) @@ -2292,6 +2412,10 @@ LuaScript::LuaScript(): { "chr_give_special", &chr_give_special }, { "chr_has_special", &chr_has_special }, { "chr_take_special", &chr_take_special }, + { "chr_set_special_recharge_speed", &chr_set_special_recharge_speed }, + { "chr_get_special_recharge_speed", &chr_get_special_recharge_speed }, + { "chr_set_special_mana", &chr_set_special_mana }, + { "chr_get_special_mana", &chr_get_special_mana }, { "chr_kick", &chr_kick }, { "exp_for_level", &exp_for_level }, { "monster_create", &monster_create }, @@ -2346,6 +2470,7 @@ LuaScript::LuaScript(): { "get_distance", &get_distance }, { "map_get_objects", &map_get_objects }, { "announce", &announce }, + { "get_special_info", &get_special_info }, { NULL, NULL } }; lua_pushvalue(mRootState, LUA_GLOBALSINDEX); @@ -2376,10 +2501,21 @@ LuaScript::LuaScript(): { NULL, NULL } }; + static luaL_Reg const members_SpecialInfo[] = { + { "name", &specialinfo_get_name }, + { "needed_mana", &specialinfo_get_needed_mana }, + { "rechargeable", &specialinfo_is_rechargeable }, + { "on_use", &specialinfo_on_use }, + { "on_recharged", &specialinfo_on_recharged }, + { "category", &specialinfo_get_category }, + { NULL, NULL} + }; + LuaItemClass::registerType(mRootState, "ItemClass", members_ItemClass); LuaMapObject::registerType(mRootState, "MapObject", members_MapObject); LuaMonsterClass::registerType(mRootState, "MonsterClass", members_MonsterClass); LuaStatusEffect::registerType(mRootState, "StatusEffect", members_StatusEffect); + LuaSpecialInfo::registerType(mRootState, "SpecialInfo", members_SpecialInfo); // Make script object available to callback functions. lua_pushlightuserdata(mRootState, const_cast<char *>(®istryKey)); diff --git a/src/scripting/luascript.cpp b/src/scripting/luascript.cpp index 36adb912..3a45b3fc 100644 --- a/src/scripting/luascript.cpp +++ b/src/scripting/luascript.cpp @@ -89,7 +89,10 @@ void LuaScript::push(const std::string &v) void LuaScript::push(Thing *v) { assert(nbArgs >= 0); - lua_pushlightuserdata(mCurrentState, v); + if (v) + lua_pushlightuserdata(mCurrentState, v); + else + lua_pushnil(mCurrentState); ++nbArgs; } diff --git a/src/scripting/luautil.cpp b/src/scripting/luautil.cpp index 67dd7395..feed7568 100644 --- a/src/scripting/luautil.cpp +++ b/src/scripting/luautil.cpp @@ -255,13 +255,22 @@ NPC *checkNPC(lua_State *s, int p) int checkSkill(lua_State *s, int p) { - if (lua_isstring(s, p)) - { - int id = skillManager->getId(luaL_checkstring(s, p)); - luaL_argcheck(s, id != 0, p, "invalid skill name"); - return id; - } - return luaL_checkint(s, 2); + if (lua_isnumber(s, p)) + return luaL_checkint(s, p); + + int id = skillManager->getId(luaL_checkstring(s, p)); + luaL_argcheck(s, id != 0, p, "invalid special name"); + return id; +} + +int checkSpecial(lua_State *s, int p) +{ + if (lua_isnumber(s, p)) + return luaL_checkint(s, p); + + int id = specialManager->getId(luaL_checkstring(s, p)); + luaL_argcheck(s, id != 0, p, "invalid special name"); + return id; } diff --git a/src/scripting/luautil.h b/src/scripting/luautil.h index a0eac120..86a748a4 100644 --- a/src/scripting/luautil.h +++ b/src/scripting/luautil.h @@ -34,6 +34,8 @@ extern "C" { #include <set> #include <vector> +#include "game-server/specialmanager.h" + class Being; class Character; class ItemClass; @@ -152,6 +154,7 @@ typedef LuaUserData<ItemClass> LuaItemClass; typedef LuaUserData<MapObject> LuaMapObject; typedef LuaUserData<MonsterClass> LuaMonsterClass; typedef LuaUserData<StatusEffect> LuaStatusEffect; +typedef LuaUserData<SpecialManager::SpecialInfo> LuaSpecialInfo; Script * getScript(lua_State *s); @@ -169,6 +172,7 @@ Monster * checkMonster(lua_State *s, int p); MonsterClass * checkMonsterClass(lua_State *s, int p); NPC * checkNPC(lua_State *s, int p); int checkSkill(lua_State *s, int p); +int checkSpecial(lua_State *s, int p); MapComposite * checkCurrentMap(lua_State *s, Script *script = 0); Script::Thread* checkCurrentThread(lua_State *s, Script *script = 0); diff --git a/src/scripting/scriptmanager.cpp b/src/scripting/scriptmanager.cpp index c133a5e2..76c4dae9 100644 --- a/src/scripting/scriptmanager.cpp +++ b/src/scripting/scriptmanager.cpp @@ -51,39 +51,6 @@ Script *ScriptManager::currentState() return _currentState; } -// TODO: Have some generic event mechanism rather than calling global functions - -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 && _getSpecialRechargeCostCallback.isValid()) - { - _currentState->prepare(_getSpecialRechargeCostCallback); - _currentState->push(id); - int scriptReturn = _currentState->execute(); - special->neededMana = scriptReturn; - } -} - -bool ScriptManager::performSpecialAction(int specialId, Being *caster) -{ - if (!_specialCallback.isValid()) - { - LOG_WARN("No callback for specials set! Specials disabled."); - return false; - } - - _currentState->prepare(_specialCallback); - _currentState->push(caster); - _currentState->push(specialId); - _currentState->execute(); - return true; -} - bool ScriptManager::performCraft(Being *crafter, const std::list<InventoryItem> &recipe) { diff --git a/src/scripting/scriptmanager.h b/src/scripting/scriptmanager.h index d0d03707..03b6e64b 100644 --- a/src/scripting/scriptmanager.h +++ b/src/scripting/scriptmanager.h @@ -26,7 +26,6 @@ #include <string> class Script; -class Special; /** * Manages the script states. In fact at the moment it simply provides access @@ -56,8 +55,6 @@ bool loadMainScript(const std::string &file); */ Script *currentState(); -void addDataToSpecial(int specialId, Special *special); -bool performSpecialAction(int specialId, Being *caster); bool performCraft(Being *crafter, const std::list<InventoryItem> &recipe); void setCraftCallback(Script *script); |