aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <tullivan99@gmail.com>2017-10-12 08:32:21 -0400
committerClyne Sullivan <tullivan99@gmail.com>2017-10-12 08:32:21 -0400
commitb709a392436d4ed17e214cd9e302ddbd23d71c21 (patch)
tree9ad8dd18d26ab6aa907b182170c08f26bea10585
parentdbf47c4e8e7731519bec212419f70e08b139be0f (diff)
more lua scripting
-rw-r--r--config/items.xml14
-rw-r--r--include/attack.hpp5
-rw-r--r--include/components/hit.hpp8
-rw-r--r--include/systems/lua.hpp18
-rw-r--r--src/attack.cpp40
-rw-r--r--src/inventory.cpp7
-rw-r--r--src/player.cpp2
-rw-r--r--src/systems/lua.cpp52
-rw-r--r--src/systems/movement.cpp8
-rw-r--r--src/world.cpp1
-rw-r--r--xml/!town.xml5
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>