]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
more lua scripting
authorClyne Sullivan <tullivan99@gmail.com>
Thu, 12 Oct 2017 12:32:21 +0000 (08:32 -0400)
committerClyne Sullivan <tullivan99@gmail.com>
Thu, 12 Oct 2017 12:32:21 +0000 (08:32 -0400)
config/items.xml
include/attack.hpp
include/components/hit.hpp
include/systems/lua.hpp
src/attack.cpp
src/inventory.cpp
src/player.cpp
src/systems/lua.cpp
src/systems/movement.cpp
src/world.cpp
xml/!town.xml

index 6225062d5ef15f096e98e7b4d3131bcfbaef9fd8..cac7eb1a2c537c2231f3c962640f67c83ac0a3b2 100644 (file)
 
 <!-- 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"/>
 
index 941e3d75f72d6d7fcd925b8164e50103dd67c5b9..deea4185c991e6ca5cdf93427b72ece942882533 100644 (file)
@@ -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_
index 334712bfa1ad7e6078c5ec62e64ffa25004847a1..45e646687463c3614e0299cb8eb13a06591c8bf9 100644 (file)
@@ -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 {
index 8c4698a7102644ce92b8cfdff47caf8c71b3537a..2df038aa00b54b3027467684140d71d1d4312517 100644 (file)
@@ -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 {
index 720e2f222ac306dc922e7e7d70ce236d9226742b..c4ad95bb7b099bb2df5925f78d0438c463fcd8b2 100644 (file)
@@ -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,
index 41fe6615a7adc8182e35df36684472c489b7187c..0ed5dc7f3671b7f67911a9a6e5c6ecdb8fb5d9fc 100644 (file)
@@ -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);
                }
 
index 9611d0e68196ee4b7a703271c8cc7ea980c63e2f..5d4d89b27977e14daa10d28115f90be68934f59e 100644 (file)
@@ -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;
                        }
index fa1e93e3d524cda764946a7a8a3445d7098f5fb4..e412334f043844fb554315b1b946fe763d9cc3e5 100644 (file)
@@ -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);
 }
 
index 1a7112a8f6f6a0a17070e3399dc0240eace3d990..9948e0348fddc16ceb9a0e76062f85813ac1faa2 100644 (file)
@@ -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;
-                               }*/
                        }
                }
        });
index 9f57b87bdee4a5c6511343fb018c46b6e1e4f00b..6a8dad84e5e8b1e39155e5eee65789d550e34412 100644 (file)
@@ -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")
index 03db7bb35a7a679fdfb819acc13de568f2f4e772..5c66a256146a8ff17f67ebf43724ec2bd2060827 100644 (file)
 
 <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>