diff options
author | Clyne Sullivan <tullivan99@gmail.com> | 2017-10-12 08:32:21 -0400 |
---|---|---|
committer | Clyne Sullivan <tullivan99@gmail.com> | 2017-10-12 08:32:21 -0400 |
commit | b709a392436d4ed17e214cd9e302ddbd23d71c21 (patch) | |
tree | 9ad8dd18d26ab6aa907b182170c08f26bea10585 | |
parent | dbf47c4e8e7731519bec212419f70e08b139be0f (diff) |
more lua scripting
-rw-r--r-- | config/items.xml | 14 | ||||
-rw-r--r-- | include/attack.hpp | 5 | ||||
-rw-r--r-- | include/components/hit.hpp | 8 | ||||
-rw-r--r-- | include/systems/lua.hpp | 18 | ||||
-rw-r--r-- | src/attack.cpp | 40 | ||||
-rw-r--r-- | src/inventory.cpp | 7 | ||||
-rw-r--r-- | src/player.cpp | 2 | ||||
-rw-r--r-- | src/systems/lua.cpp | 52 | ||||
-rw-r--r-- | src/systems/movement.cpp | 8 | ||||
-rw-r--r-- | src/world.cpp | 1 | ||||
-rw-r--r-- | xml/!town.xml | 5 |
11 files changed, 127 insertions, 33 deletions
diff --git a/config/items.xml b/config/items.xml index 6225062..cac7eb1 100644 --- a/config/items.xml +++ b/config/items.xml @@ -18,10 +18,20 @@ <!-- WEAPONS --> <item name="Wood Sword" type="Sword" damage="3" maxStackSize="1" sound="assets/sounds/longSwing.wav" sprite="assets/items/SWORD_WOOD.png" cooldown="250"> - <attack range="6, 2" power="1" effect="assets/effects/starAttack.gif"/> + <attack range="6, 2" power="1" effect="assets/effects/starAttack.gif"> + update = function() + flash(255, 0, 0) + damage(8) + end + </attack> </item> <item name="Hunters Bow" type="Bow" damage="2" maxStackSize="1" sprite="assets/items/bow.png" cooldown="600"> - <attack power="4" effect="assets/effects/starAttack.gif"/> + <attack effect="assets/effects/starAttack.gif"> + update = function() + flash(255, 0, 255) + damage(4) + end + </attack> </item> <item name="Arrow" type="Arrow" damage="1" maxStackSize="99" sprite="assets/items/arrow_crude.png"/> diff --git a/include/attack.hpp b/include/attack.hpp index 941e3d7..deea418 100644 --- a/include/attack.hpp +++ b/include/attack.hpp @@ -6,16 +6,17 @@ #include <forward_list> #include <vector> +#include <systems/lua.hpp> #include <texture.hpp> #include <vector2.hpp> struct Attack { - int power; vec2 offset; vec2 range; vec2 vel; // TODO use vec2 accel; // TODO use + LuaScript script; TextureIterator effect; }; @@ -50,6 +51,8 @@ public: bool receive(const AttackEvent& ae); void update(entityx::EntityManager& en, entityx::EventManager& ev, entityx::TimeDelta dt) override; static void render(void); + + static void initLua(LuaScript& s); }; #endif // ATTACK_HPP_ diff --git a/include/components/hit.hpp b/include/components/hit.hpp index 334712b..45e6466 100644 --- a/include/components/hit.hpp +++ b/include/components/hit.hpp @@ -3,14 +3,14 @@ #include "base.hpp" +#include <attack.hpp> #include <texture.hpp> struct Hit : public Component { - Hit(int d, bool p = false) - : damage(d), pierce(p) {} + Hit(Attack* a) + : attack(a) {} - int damage; - bool pierce; + Attack* attack; TextureIterator effect; void fromXML(XMLElement* imp, XMLElement* def) final { diff --git a/include/systems/lua.hpp b/include/systems/lua.hpp index 8c4698a..2df038a 100644 --- a/include/systems/lua.hpp +++ b/include/systems/lua.hpp @@ -13,7 +13,8 @@ private: lua_State* state; std::string script; - void setGlobal(const LuaVariable&); + void setGlobal(const LuaVariable&) const; + void getReturns(std::vector<double>& rets) const; static void replace(std::string& s, const std::string& rid, const std::string& put) { for (unsigned int i = 0; i < s.size(); i++) { @@ -35,8 +36,19 @@ public: lua_pcall(state, 0, 0, 0); } - void operator()(std::vector<LuaVariable> vars); - void operator()(void); + inline lua_State* getState(void) + { return state; } + + inline void addFunction(const std::string& name, lua_CFunction func) { + lua_pushcclosure(state, func, 0); + lua_setglobal(state, name.c_str()); + } + + void operator()(const std::string& func, std::vector<LuaVariable> vars) const; + void operator()(const std::string& func, std::vector<double>& rets, std::vector<LuaVariable> vars) const; + void operator()(std::vector<LuaVariable> vars) const; + void operator()(std::vector<double>& rets, std::vector<LuaVariable> vars) const; + void operator()(const std::string& func = "update") const; }; class LuaSystem { diff --git a/src/attack.cpp b/src/attack.cpp index 720e2f2..c4ad95b 100644 --- a/src/attack.cpp +++ b/src/attack.cpp @@ -34,6 +34,34 @@ bool AttackSystem::receive(const AttackEvent& ae) return true; } +namespace lua { + static entityx::Entity* entity; + + inline void setEntity(entityx::Entity* e) { + entity = e; + } + + int flash(lua_State* state) { + float r = lua_tonumber(state, 1); + float g = lua_tonumber(state, 2); + float b = lua_tonumber(state, 3); + entity->replace<Flash>(Color(r, g, b)); + return 0; + } + + int damage(lua_State* state) { + float d = lua_tonumber(state, 1); + entity->component<Health>()->health -= d; + return 0; + } +} + +void AttackSystem::initLua(LuaScript& s) +{ + s.addFunction("flash", lua::flash); + s.addFunction("damage", lua::damage); +} + void AttackSystem::update(entityx::EntityManager& en, entityx::EventManager& ev, entityx::TimeDelta dt) { (void)en; @@ -44,14 +72,15 @@ void AttackSystem::update(entityx::EntityManager& en, entityx::EventManager& ev, en.each<Hit, Position>([&](entityx::Entity p, Hit& hit, Position& ppos) { bool die = false; en.each<Health, Position, Solid>([&](entityx::Entity e, Health& health, Position& pos, Solid& dim) { + (void)health; if (!e.has_component<Player>() && inrange(ppos.x, pos.x, pos.x + dim.width) && inrange(ppos.y, pos.y - 2, pos.y + dim.height)) { - health.health -= hit.damage; - e.replace<Flash>(Color(255, 0, 0)); + lua::setEntity(&e); + hit.attack->script(); if (hit.effect.size() > 0) effects.emplace_back(vec2(ppos.x, ppos.y), hit.effect); //ParticleSystem::addMultiple(15, ParticleType::SmallBlast, // [&](){ return vec2(pos.x + dim.width / 2, pos.y + dim.height / 2); }, 300, 7); - die = !hit.pierce; + die = true; } else if (WorldSystem::isAboveGround(vec2(ppos.x, ppos.y - 5))) die = true; }); @@ -68,13 +97,14 @@ void AttackSystem::update(entityx::EntityManager& en, entityx::EventManager& ev, en.each<Position, Solid, Health>( [&](entityx::Entity e, Position& pos, Solid& dim, Health& h) { + (void)h; if (!(e.has_component<Player>() ^ a.fromplayer)) // no self-harm please return; if (inrange(point.x, pos.x, pos.x + dim.width, HLINES(size.x)) && inrange(point.y, pos.y, pos.y + dim.height, HLINES(size.y))) { - h.health -= a.attack.power; - e.replace<Flash>(Color(255, 0, 0)); + lua::setEntity(&e); + a.attack.script(); if (a.attack.effect.size() > 0) effects.emplace_back(point, a.attack.effect); //ParticleSystem::addMultiple(15, ParticleType::DownSlash, diff --git a/src/inventory.cpp b/src/inventory.cpp index 41fe661..0ed5dc7 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -75,14 +75,15 @@ void InventorySystem::loadItems(void) { auto atk = itm->FirstChildElement("attack"); if (atk != nullptr) { Attack attack; - attack.power = 0; - atk->QueryIntAttribute("power", &attack.power); attack.offset = atk->StrAttribute("offset"); attack.range = atk->StrAttribute("range"); attack.vel = atk->StrAttribute("velocity"); attack.accel = atk->StrAttribute("accel"); if (atk->Attribute("effect") != nullptr) - attack.effect.appendGIF(atk->StrAttribute("effect")); + attack.effect.appendGIF(atk->StrAttribute("effect")); + auto script = atk->GetText(); + attack.script = LuaScript(script != nullptr ? script : ""); + AttackSystem::initLua(attack.script); attackList.emplace(item.name, attack); } diff --git a/src/player.cpp b/src/player.cpp index 9611d0e..5d4d89b 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -244,7 +244,7 @@ bool PlayerSystem::receive(const UseItemEvent& uie) sprite->addSpriteSegment(SpriteData(tex->sprite), 0); auto dim = HLINES(sprite->getSpriteSize()); e.assign<Solid>(dim.x, dim.y); - e.assign<Hit>(uie.attack->power, false); + e.assign<Hit>(uie.attack); if (uie.attack->effect.size() > 0) e.component<Hit>()->effect = uie.attack->effect; } diff --git a/src/systems/lua.cpp b/src/systems/lua.cpp index fa1e93e..e412334 100644 --- a/src/systems/lua.cpp +++ b/src/systems/lua.cpp @@ -1,25 +1,69 @@ #include <systems/lua.hpp> -void LuaScript::setGlobal(const LuaVariable& nv) +void LuaScript::setGlobal(const LuaVariable& nv) const { lua_pushnumber(state, std::get<float&>(nv)); lua_setglobal(state, std::get<std::string>(nv).c_str()); } -void LuaScript::operator()(std::vector<LuaVariable> vars) +void LuaScript::getReturns(std::vector<double>& rets) const +{ + int count = lua_gettop(state); + for (int i = 1; i <= count; i++) + rets.emplace_back(lua_tonumber(state, i)); + lua_pop(state, count); +} + +void LuaScript::operator()(const std::string& func, std::vector<LuaVariable> vars) const +{ + for (auto& v : vars) + setGlobal(v); + (*this)(func); + for (auto& v : vars) { + lua_getglobal(state, std::get<std::string>(v).c_str()); + std::get<float&>(v) = lua_tonumber(state, -1); + } +} + +void LuaScript::operator()(const std::string& func, std::vector<double>& rets, + std::vector<LuaVariable> vars) const +{ + for (auto& v : vars) + setGlobal(v); + (*this)(func); + getReturns(rets); + for (auto& v : vars) { + lua_getglobal(state, std::get<std::string>(v).c_str()); + std::get<float&>(v) = lua_tonumber(state, -1); + } +} + +void LuaScript::operator()(std::vector<LuaVariable> vars) const +{ + for (auto& v : vars) + setGlobal(v); + (*this)(); + for (auto& v : vars) { + lua_getglobal(state, std::get<std::string>(v).c_str()); + std::get<float&>(v) = lua_tonumber(state, -1); + } +} + +void LuaScript::operator()(std::vector<double>& rets, std::vector<LuaVariable> vars) const { for (auto& v : vars) setGlobal(v); (*this)(); + getReturns(rets); for (auto& v : vars) { lua_getglobal(state, std::get<std::string>(v).c_str()); std::get<float&>(v) = lua_tonumber(state, -1); } } -void LuaScript::operator()(void) +void LuaScript::operator()(const std::string& s) const { - lua_getglobal(state, "update"); + lua_getglobal(state, s.c_str()); lua_pcall(state, 0, LUA_MULTRET, 0); } diff --git a/src/systems/movement.cpp b/src/systems/movement.cpp index 1a7112a..9948e03 100644 --- a/src/systems/movement.cpp +++ b/src/systems/movement.cpp @@ -77,14 +77,6 @@ void MovementSystem::update(entityx::EntityManager &en, entityx::EventManager &e if (entity.has_component<Wander>()) { entity.component<Wander>()->script({LuaVariable("vely", direction.y), LuaVariable("velx", direction.x)}); - /*auto& countdown = entity.component<Wander>()->countdown; - - if (countdown > 0) { - countdown--; - } else { - countdown = 5000 + randGet() % 10 * 100; - direction.x = (randGet() % 3 - 1) * 0.004f; - }*/ } } }); diff --git a/src/world.cpp b/src/world.cpp index 9f57b87..6a8dad8 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -353,6 +353,7 @@ void WorldSystem::loader(void) else if (tname == "Wander") { auto script = abcd->GetText(); entity.assign<Wander>(script != nullptr ? script : ""); + //entity.component<Wander>()->script.addFunction("getpos", PlayerSystem::getPosition); } else if (tname == "Hop") entity.assign<Hop>(); else if (tname == "Health") diff --git a/xml/!town.xml b/xml/!town.xml index 03db7bb..5c66a25 100644 --- a/xml/!town.xml +++ b/xml/!town.xml @@ -27,9 +27,10 @@ <Dialog name="Bob"> <text id="0" nextid="1"> - <give name="Hunters Bow" count="1"/> + <!--<give name="Hunters Bow" count="1"/> <give name="Arrow" count="50"/> - <option name="Yes"/> + <option name="Yes"/>--> + <give name="Wood Sword" count="1"/> <content> Hey there! The name's Bob. Good to see you've finally woken up from your nap by the cliff there... lol </content> |