Overhaul of animstep, implement tangible.build
This commit is contained in:
@@ -2,32 +2,67 @@
|
|||||||
#include "luastack.hpp"
|
#include "luastack.hpp"
|
||||||
#include "animqueue.hpp"
|
#include "animqueue.hpp"
|
||||||
|
|
||||||
AnimStep::AnimStep() {}
|
AnimStep::AnimStep() {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
AnimStep::~AnimStep() {}
|
AnimStep::~AnimStep() {}
|
||||||
|
|
||||||
|
void AnimStep::clear() {
|
||||||
|
id_ = 0;
|
||||||
|
bits_ = 0;
|
||||||
|
action_ = "";
|
||||||
|
facing_ = 0;
|
||||||
|
xyz_ = util::XYZ(0,0,0);
|
||||||
|
graphic_ = "";
|
||||||
|
plane_ = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimStep::set_action(const std::string &act) {
|
||||||
|
action_ = act;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimStep::set_facing(float f) {
|
||||||
|
bits_ |= HAS_FACING;
|
||||||
|
facing_ = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimStep::set_x(float f) {
|
||||||
|
bits_ |= HAS_X;
|
||||||
|
xyz_.x = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimStep::set_y(float f) {
|
||||||
|
bits_ |= HAS_Y;
|
||||||
|
xyz_.y = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimStep::set_z(float f) {
|
||||||
|
bits_ |= HAS_Z;
|
||||||
|
xyz_.z = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimStep::set_xyz(const util::XYZ &xyz) {
|
||||||
|
bits_ |= (HAS_X | HAS_Y | HAS_Z);
|
||||||
|
xyz_ = xyz;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimStep::set_graphic(const std::string &g) {
|
||||||
|
bits_ |= HAS_GRAPHIC;
|
||||||
|
graphic_ = g;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimStep::set_plane(const std::string &p) {
|
||||||
|
bits_ |= HAS_PLANE;
|
||||||
|
plane_ = p;
|
||||||
|
}
|
||||||
|
|
||||||
AnimQueue::AnimQueue() {
|
AnimQueue::AnimQueue() {
|
||||||
size_limit_ = 10; // Default size limit.
|
size_limit_ = 10; // Default size limit.
|
||||||
clear_steps();
|
clear_steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimQueue::clear_steps() {
|
void AnimStep::from_lua(lua_State *L, int idx) {
|
||||||
steps_.clear();
|
|
||||||
steps_.emplace_back();
|
|
||||||
AnimStep &init = steps_.back();
|
|
||||||
init.id_ = 0;
|
|
||||||
init.bits_ = AnimStep::HAS_EVERYTHING;
|
|
||||||
init.facing_ = 0;
|
|
||||||
init.xyz_ = util::XYZ(0,0,0);
|
|
||||||
init.graphic_ = "nothing";
|
|
||||||
init.plane_ = "nowhere";
|
|
||||||
}
|
|
||||||
|
|
||||||
void AnimQueue::set_size_limit(int n) {
|
|
||||||
assert(n >= 2);
|
|
||||||
size_limit_ = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AnimQueue::add(int64_t id, lua_State *L, int idx) {
|
|
||||||
LuaSpecial tab(idx);
|
LuaSpecial tab(idx);
|
||||||
LuaVar value;
|
LuaVar value;
|
||||||
LuaStack LS(L, value);
|
LuaStack LS(L, value);
|
||||||
@@ -35,91 +70,123 @@ void AnimQueue::add(int64_t id, lua_State *L, int idx) {
|
|||||||
luaL_error(L, "animation spec must be a table");
|
luaL_error(L, "animation spec must be a table");
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimStep step = steps_.back();
|
|
||||||
step.id_ = id;
|
|
||||||
step.bits_ = 0;
|
|
||||||
step.action_ = "";
|
|
||||||
|
|
||||||
LS.rawget(value, tab, "action");
|
LS.rawget(value, tab, "action");
|
||||||
if (!LS.isstring(value)) {
|
if (LS.isstring(value)) {
|
||||||
luaL_error(L, "animation action is not optional and must be a string");
|
action_ = LS.ckstring(value);
|
||||||
|
} else if (!LS.isnil(value)) {
|
||||||
|
luaL_error(L, "animation action must be a string");
|
||||||
}
|
}
|
||||||
step.action_ = LS.ckstring(value);
|
|
||||||
|
|
||||||
LS.rawget(value, tab, "facing");
|
LS.rawget(value, tab, "facing");
|
||||||
if (LS.isnumber(value)) {
|
if (LS.isnumber(value)) {
|
||||||
step.facing_ = LS.cknumber(value);
|
facing_ = LS.cknumber(value);
|
||||||
step.bits_ |= AnimStep::HAS_FACING;
|
bits_ |= HAS_FACING;
|
||||||
} else if (!LS.isnil(value)) {
|
} else if (!LS.isnil(value)) {
|
||||||
luaL_error(L, "animation facing must be a number");
|
luaL_error(L, "animation facing must be a number");
|
||||||
}
|
}
|
||||||
|
|
||||||
LS.rawget(value, tab, "x");
|
LS.rawget(value, tab, "x");
|
||||||
if (LS.isnumber(value)) {
|
if (LS.isnumber(value)) {
|
||||||
step.xyz_.x = LS.cknumber(value);
|
xyz_.x = LS.cknumber(value);
|
||||||
step.bits_ |= AnimStep::HAS_XYZ;
|
bits_ |= HAS_X;
|
||||||
} else if (!LS.isnil(value)) {
|
} else if (!LS.isnil(value)) {
|
||||||
luaL_error(L, "animation X coordinate must be a number");
|
luaL_error(L, "animation X coordinate must be a number");
|
||||||
}
|
}
|
||||||
|
|
||||||
LS.rawget(value, tab, "y");
|
LS.rawget(value, tab, "y");
|
||||||
if (LS.isnumber(value)) {
|
if (LS.isnumber(value)) {
|
||||||
step.xyz_.y = LS.cknumber(value);
|
xyz_.y = LS.cknumber(value);
|
||||||
step.bits_ |= AnimStep::HAS_XYZ;
|
bits_ |= HAS_Y;
|
||||||
} else if (!LS.isnil(value)) {
|
} else if (!LS.isnil(value)) {
|
||||||
luaL_error(L, "animation Y coordinate must be a number");
|
luaL_error(L, "animation Y coordinate must be a number");
|
||||||
}
|
}
|
||||||
|
|
||||||
LS.rawget(value, tab, "z");
|
LS.rawget(value, tab, "z");
|
||||||
if (LS.isnumber(value)) {
|
if (LS.isnumber(value)) {
|
||||||
step.xyz_.z = LS.cknumber(value);
|
xyz_.z = LS.cknumber(value);
|
||||||
step.bits_ |= AnimStep::HAS_XYZ;
|
bits_ |= HAS_Z;
|
||||||
} else if (!LS.isnil(value)) {
|
} else if (!LS.isnil(value)) {
|
||||||
luaL_error(L, "animation Z coordinate must be a number");
|
luaL_error(L, "animation Z coordinate must be a number");
|
||||||
}
|
}
|
||||||
|
|
||||||
LS.rawget(value, tab, "dx");
|
|
||||||
if (LS.isnumber(value)) {
|
|
||||||
step.xyz_.x += LS.cknumber(value);
|
|
||||||
step.bits_ |= AnimStep::HAS_XYZ;
|
|
||||||
} else if (!LS.isnil(value)) {
|
|
||||||
luaL_error(L, "animation DX offset must be a number");
|
|
||||||
}
|
|
||||||
|
|
||||||
LS.rawget(value, tab, "dy");
|
|
||||||
if (LS.isnumber(value)) {
|
|
||||||
step.xyz_.y += LS.cknumber(value);
|
|
||||||
step.bits_ |= AnimStep::HAS_XYZ;
|
|
||||||
} else if (!LS.isnil(value)) {
|
|
||||||
luaL_error(L, "animation DY offset must be a number");
|
|
||||||
}
|
|
||||||
|
|
||||||
LS.rawget(value, tab, "dz");
|
|
||||||
if (LS.isnumber(value)) {
|
|
||||||
step.xyz_.z += LS.cknumber(value);
|
|
||||||
step.bits_ |= AnimStep::HAS_XYZ;
|
|
||||||
} else if (!LS.isnil(value)) {
|
|
||||||
luaL_error(L, "animation DZ offset must be a number");
|
|
||||||
}
|
|
||||||
|
|
||||||
LS.rawget(value, tab, "graphic");
|
LS.rawget(value, tab, "graphic");
|
||||||
if (LS.isstring(value)) {
|
if (LS.isstring(value)) {
|
||||||
step.graphic_ = LS.ckstring(value);
|
graphic_ = LS.ckstring(value);
|
||||||
step.bits_ |= AnimStep::HAS_GRAPHIC;
|
bits_ |= HAS_GRAPHIC;
|
||||||
} else if (!LS.isnil(value)) {
|
} else if (!LS.isnil(value)) {
|
||||||
luaL_error(L, "animation graphic must be a string");
|
luaL_error(L, "animation graphic must be a string");
|
||||||
}
|
}
|
||||||
|
|
||||||
LS.rawget(value, tab, "plane");
|
LS.rawget(value, tab, "plane");
|
||||||
if (LS.isstring(value)) {
|
if (LS.isstring(value)) {
|
||||||
step.plane_ = LS.ckstring(value);
|
plane_ = LS.ckstring(value);
|
||||||
step.bits_ |= AnimStep::HAS_PLANE;
|
bits_ |= HAS_PLANE;
|
||||||
} else if (!LS.isnil(value)) {
|
} else if (!LS.isnil(value)) {
|
||||||
luaL_error(L, "animation plane must be a string");
|
luaL_error(L, "animation plane must be a string");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
steps_.push_back(step);
|
void AnimStep::echo(const AnimStep &prev) {
|
||||||
while (int(steps_.size()) > size_limit_) {
|
if (!has_facing()) {
|
||||||
|
facing_ = prev.facing_;
|
||||||
|
}
|
||||||
|
if (!has_x()) {
|
||||||
|
xyz_.x = prev.xyz_.x;
|
||||||
|
}
|
||||||
|
if (!has_y()) {
|
||||||
|
xyz_.y = prev.xyz_.y;
|
||||||
|
}
|
||||||
|
if (!has_z()) {
|
||||||
|
xyz_.z = prev.xyz_.z;
|
||||||
|
}
|
||||||
|
if (!has_graphic()) {
|
||||||
|
graphic_ = prev.graphic_;
|
||||||
|
}
|
||||||
|
if (!has_plane()) {
|
||||||
|
plane_ = prev.plane_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AnimStep::echoes(const AnimStep &prev) const {
|
||||||
|
if (!has_facing() && (facing_ != prev.facing_)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!has_x() && (xyz_.x != prev.xyz_.x)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!has_y() && (xyz_.y != prev.xyz_.y)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!has_z() && (xyz_.z != prev.xyz_.z)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!has_graphic() && (graphic_ != prev.graphic_)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!has_plane() && (plane_ != prev.plane_)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimQueue::clear_steps() {
|
||||||
|
steps_.clear();
|
||||||
|
steps_.emplace_back();
|
||||||
|
AnimStep &init = steps_.back();
|
||||||
|
init.bits_ = AnimStep::HAS_EVERYTHING;
|
||||||
|
init.action_ = "";
|
||||||
|
init.graphic_ = "";
|
||||||
|
init.plane_ = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimQueue::set_size_limit(int n) {
|
||||||
|
assert(n >= 2);
|
||||||
|
size_limit_ = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimQueue::keep_only(int n) {
|
||||||
|
if (n < 1) n = 1;
|
||||||
|
while (int(steps_.size()) > n) {
|
||||||
steps_.pop_front();
|
steps_.pop_front();
|
||||||
}
|
}
|
||||||
AnimStep &init = steps_.front();
|
AnimStep &init = steps_.front();
|
||||||
@@ -128,44 +195,12 @@ void AnimQueue::add(int64_t id, lua_State *L, int idx) {
|
|||||||
init.bits_ = AnimStep::HAS_EVERYTHING;
|
init.bits_ = AnimStep::HAS_EVERYTHING;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimQueue::add(int64_t id, const std::string &action) {
|
void AnimQueue::add(int64_t id, const AnimStep &step) {
|
||||||
AnimStep step = steps_.back();
|
AnimStep copy = step;
|
||||||
step.id_ = id;
|
copy.echo(steps_.back());
|
||||||
step.action_ = action;
|
copy.id_ = id;
|
||||||
step.bits_ = 0;
|
steps_.push_back(copy);
|
||||||
|
keep_only(size_limit_);
|
||||||
steps_.push_back(step);
|
|
||||||
while (int(steps_.size()) > size_limit_) {
|
|
||||||
steps_.pop_front();
|
|
||||||
}
|
|
||||||
AnimStep &init = steps_.front();
|
|
||||||
init.id_ = 0;
|
|
||||||
init.action_ = "";
|
|
||||||
init.bits_ = AnimStep::HAS_EVERYTHING;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AnimQueue::set_facing(float f) {
|
|
||||||
AnimStep &last = steps_.back();
|
|
||||||
last.bits_ |= AnimStep::HAS_FACING;
|
|
||||||
last.facing_ = f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AnimQueue::set_xyz(util::XYZ xyz) {
|
|
||||||
AnimStep &last = steps_.back();
|
|
||||||
last.bits_ |= AnimStep::HAS_XYZ;
|
|
||||||
last.xyz_ = xyz;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AnimQueue::set_graphic(const std::string &g) {
|
|
||||||
AnimStep &last = steps_.back();
|
|
||||||
last.bits_ |= AnimStep::HAS_GRAPHIC;
|
|
||||||
last.graphic_ = g;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AnimQueue::set_plane(const std::string &p) {
|
|
||||||
AnimStep &last = steps_.back();
|
|
||||||
last.bits_ |= AnimStep::HAS_PLANE;
|
|
||||||
last.plane_ = p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AnimQueue::valid() {
|
bool AnimQueue::valid() {
|
||||||
@@ -185,18 +220,7 @@ bool AnimQueue::valid() {
|
|||||||
for (size_t i = 1; i < steps_.size(); i++) {
|
for (size_t i = 1; i < steps_.size(); i++) {
|
||||||
const AnimStep &prev = steps_[i - 1];
|
const AnimStep &prev = steps_[i - 1];
|
||||||
const AnimStep &curr = steps_[i];
|
const AnimStep &curr = steps_[i];
|
||||||
if (!curr.has_facing() && (curr.facing_ != prev.facing_)) {
|
if (!curr.echoes(prev)) return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!curr.has_xyz() && (curr.xyz_ != prev.xyz_)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!curr.has_graphic() && (curr.graphic_ != prev.graphic_)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!curr.has_plane() && (curr.plane_ != prev.plane_)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -212,9 +236,13 @@ void AnimQueue::serialize(StreamBuffer *sb) {
|
|||||||
if (step.has_facing()) {
|
if (step.has_facing()) {
|
||||||
sb->write_float(step.facing_);
|
sb->write_float(step.facing_);
|
||||||
}
|
}
|
||||||
if (step.has_xyz()) {
|
if (step.has_x()) {
|
||||||
sb->write_float(step.xyz_.x);
|
sb->write_float(step.xyz_.x);
|
||||||
|
}
|
||||||
|
if (step.has_y()) {
|
||||||
sb->write_float(step.xyz_.y);
|
sb->write_float(step.xyz_.y);
|
||||||
|
}
|
||||||
|
if (step.has_z()) {
|
||||||
sb->write_float(step.xyz_.z);
|
sb->write_float(step.xyz_.z);
|
||||||
}
|
}
|
||||||
if (step.has_graphic()) {
|
if (step.has_graphic()) {
|
||||||
@@ -239,9 +267,13 @@ void AnimQueue::deserialize(StreamBuffer *sb) {
|
|||||||
if (step.has_facing()) {
|
if (step.has_facing()) {
|
||||||
step.facing_ = sb->read_float();
|
step.facing_ = sb->read_float();
|
||||||
}
|
}
|
||||||
if (step.has_xyz()) {
|
if (step.has_x()) {
|
||||||
step.xyz_.x = sb->read_float();
|
step.xyz_.x = sb->read_float();
|
||||||
|
}
|
||||||
|
if (step.has_y()) {
|
||||||
step.xyz_.y = sb->read_float();
|
step.xyz_.y = sb->read_float();
|
||||||
|
}
|
||||||
|
if (step.has_z()) {
|
||||||
step.xyz_.z = sb->read_float();
|
step.xyz_.z = sb->read_float();
|
||||||
}
|
}
|
||||||
if (step.has_graphic()) {
|
if (step.has_graphic()) {
|
||||||
@@ -259,6 +291,7 @@ const AnimStep &AnimQueue::back() const {
|
|||||||
|
|
||||||
LuaDefine(unittests_animqueue, "c") {
|
LuaDefine(unittests_animqueue, "c") {
|
||||||
// Check initial state.
|
// Check initial state.
|
||||||
|
AnimStep stp;
|
||||||
AnimQueue aq;
|
AnimQueue aq;
|
||||||
StreamBuffer sb;
|
StreamBuffer sb;
|
||||||
AnimQueue aqds;
|
AnimQueue aqds;
|
||||||
@@ -272,11 +305,34 @@ LuaDefine(unittests_animqueue, "c") {
|
|||||||
LuaAssert(L, st->bits() == AnimStep::HAS_EVERYTHING);
|
LuaAssert(L, st->bits() == AnimStep::HAS_EVERYTHING);
|
||||||
LuaAssert(L, st->facing() == 0.0);
|
LuaAssert(L, st->facing() == 0.0);
|
||||||
LuaAssert(L, st->xyz() == util::XYZ(0,0,0));
|
LuaAssert(L, st->xyz() == util::XYZ(0,0,0));
|
||||||
LuaAssert(L, st->graphic() == "nothing");
|
LuaAssert(L, st->graphic() == "");
|
||||||
LuaAssert(L, st->plane() == "nowhere");
|
LuaAssert(L, st->plane() == "");
|
||||||
|
|
||||||
|
// Test the step setters.
|
||||||
|
stp.clear();
|
||||||
|
stp.set_facing(180);
|
||||||
|
LuaAssert(L, stp.facing() == 180);
|
||||||
|
LuaAssert(L, stp.bits() == AnimStep::HAS_FACING);
|
||||||
|
stp.set_x(3);
|
||||||
|
LuaAssert(L, stp.xyz() == util::XYZ(3, 0, 0));
|
||||||
|
LuaAssert(L, stp.bits() == (AnimStep::HAS_FACING | AnimStep::HAS_X));
|
||||||
|
stp.set_y(4);
|
||||||
|
LuaAssert(L, stp.xyz() == util::XYZ(3, 4, 0));
|
||||||
|
LuaAssert(L, stp.bits() == (AnimStep::HAS_FACING | AnimStep::HAS_X | AnimStep::HAS_Y));
|
||||||
|
stp.set_z(5);
|
||||||
|
LuaAssert(L, stp.xyz() == util::XYZ(3, 4, 5));
|
||||||
|
LuaAssert(L, stp.bits() == (AnimStep::HAS_FACING | AnimStep::HAS_X | AnimStep::HAS_Y | AnimStep::HAS_Z));
|
||||||
|
stp.set_plane("somewhere");
|
||||||
|
LuaAssert(L, stp.plane() == "somewhere");
|
||||||
|
LuaAssert(L, stp.bits() == (AnimStep::HAS_FACING | AnimStep::HAS_XYZ | AnimStep::HAS_PLANE));
|
||||||
|
stp.set_graphic("something");
|
||||||
|
LuaAssert(L, stp.graphic() == "something");
|
||||||
|
LuaAssert(L, stp.bits() == (AnimStep::HAS_FACING | AnimStep::HAS_XYZ | AnimStep::HAS_PLANE | AnimStep::HAS_GRAPHIC));
|
||||||
|
|
||||||
// Add a step.
|
// Add a step.
|
||||||
aq.add(12345, "walk");
|
stp.clear();
|
||||||
|
stp.set_action("walk");
|
||||||
|
aq.add(12345, stp);
|
||||||
LuaAssert(L, aq.valid());
|
LuaAssert(L, aq.valid());
|
||||||
LuaAssert(L, aq.size() == 2);
|
LuaAssert(L, aq.size() == 2);
|
||||||
st = &aq.nth(1);
|
st = &aq.nth(1);
|
||||||
@@ -285,27 +341,14 @@ LuaDefine(unittests_animqueue, "c") {
|
|||||||
LuaAssert(L, st->bits() == 0);
|
LuaAssert(L, st->bits() == 0);
|
||||||
LuaAssert(L, st->facing() == 0.0);
|
LuaAssert(L, st->facing() == 0.0);
|
||||||
LuaAssert(L, st->xyz() == util::XYZ(0,0,0));
|
LuaAssert(L, st->xyz() == util::XYZ(0,0,0));
|
||||||
LuaAssert(L, st->graphic() == "nothing");
|
LuaAssert(L, st->graphic() == "");
|
||||||
LuaAssert(L, st->plane() == "nowhere");
|
LuaAssert(L, st->plane() == "");
|
||||||
|
|
||||||
// Test the setters.
|
|
||||||
aq.set_facing(180);
|
|
||||||
LuaAssert(L, st->facing() == 180);
|
|
||||||
LuaAssert(L, st->bits() == AnimStep::HAS_FACING);
|
|
||||||
aq.set_xyz(util::XYZ(3,4,5));
|
|
||||||
LuaAssert(L, st->xyz() == util::XYZ(3, 4, 5));
|
|
||||||
LuaAssert(L, st->bits() == (AnimStep::HAS_FACING | AnimStep::HAS_XYZ));
|
|
||||||
aq.set_plane("somewhere");
|
|
||||||
LuaAssert(L, st->plane() == "somewhere");
|
|
||||||
LuaAssert(L, st->bits() == (AnimStep::HAS_FACING | AnimStep::HAS_XYZ | AnimStep::HAS_PLANE));
|
|
||||||
aq.set_graphic("something");
|
|
||||||
LuaAssert(L, st->graphic() == "something");
|
|
||||||
LuaAssert(L, st->bits() == (AnimStep::HAS_FACING | AnimStep::HAS_XYZ | AnimStep::HAS_PLANE | AnimStep::HAS_GRAPHIC));
|
|
||||||
LuaAssert(L, aq.valid());
|
|
||||||
|
|
||||||
// Exceed the length limit, dropping first element.
|
// Exceed the length limit, dropping first element.
|
||||||
aq.add(12346, "walk");
|
stp.clear();
|
||||||
aq.add(12347, "walk");
|
stp.set_action("walk");
|
||||||
|
aq.add(12346, stp);
|
||||||
|
aq.add(12347, stp);
|
||||||
LuaAssert(L, aq.size() == 3);
|
LuaAssert(L, aq.size() == 3);
|
||||||
LuaAssert(L, aq.nth(0).id() == 0);
|
LuaAssert(L, aq.nth(0).id() == 0);
|
||||||
LuaAssert(L, aq.nth(0).action() == "");
|
LuaAssert(L, aq.nth(0).action() == "");
|
||||||
@@ -317,12 +360,22 @@ LuaDefine(unittests_animqueue, "c") {
|
|||||||
// Test serialization and deserialization.
|
// Test serialization and deserialization.
|
||||||
aq.set_size_limit(5);
|
aq.set_size_limit(5);
|
||||||
aq.clear_steps();
|
aq.clear_steps();
|
||||||
aq.add(12345, "walk");
|
|
||||||
aq.set_xyz(util::XYZ(3,4,5));
|
stp.clear();
|
||||||
aq.add(12346, "setgraphic");
|
stp.set_action("walk");
|
||||||
aq.set_graphic("banana");
|
stp.set_xyz(util::XYZ(3,4,5));
|
||||||
aq.add(12347, "setfacing");
|
aq.add(12345, stp);
|
||||||
aq.set_facing(301.0);
|
|
||||||
|
stp.clear();
|
||||||
|
stp.set_action("setgraphic");
|
||||||
|
stp.set_graphic("banana");
|
||||||
|
aq.add(12346, stp);
|
||||||
|
|
||||||
|
stp.clear();
|
||||||
|
stp.set_action("setfacing");
|
||||||
|
stp.set_facing(301.0);
|
||||||
|
aq.add(12347, stp);
|
||||||
|
|
||||||
aq.serialize(&sb);
|
aq.serialize(&sb);
|
||||||
aqds.deserialize(&sb);
|
aqds.deserialize(&sb);
|
||||||
|
|
||||||
@@ -334,16 +387,16 @@ LuaDefine(unittests_animqueue, "c") {
|
|||||||
LuaAssert(L, aqds.nth(0).action() == "");
|
LuaAssert(L, aqds.nth(0).action() == "");
|
||||||
LuaAssert(L, aqds.nth(0).facing() == 0.0);
|
LuaAssert(L, aqds.nth(0).facing() == 0.0);
|
||||||
LuaAssert(L, aqds.nth(0).xyz() == util::XYZ(0,0,0));
|
LuaAssert(L, aqds.nth(0).xyz() == util::XYZ(0,0,0));
|
||||||
LuaAssert(L, aqds.nth(0).graphic() == "nothing");
|
LuaAssert(L, aqds.nth(0).graphic() == "");
|
||||||
LuaAssert(L, aqds.nth(0).plane() == "nowhere");
|
LuaAssert(L, aqds.nth(0).plane() == "");
|
||||||
|
|
||||||
LuaAssert(L, aqds.nth(1).id() == 12345);
|
LuaAssert(L, aqds.nth(1).id() == 12345);
|
||||||
LuaAssert(L, aqds.nth(1).bits() == AnimStep::HAS_XYZ);
|
LuaAssert(L, aqds.nth(1).bits() == AnimStep::HAS_XYZ);
|
||||||
LuaAssert(L, aqds.nth(1).action() == "walk");
|
LuaAssert(L, aqds.nth(1).action() == "walk");
|
||||||
LuaAssert(L, aqds.nth(1).facing() == 0.0);
|
LuaAssert(L, aqds.nth(1).facing() == 0.0);
|
||||||
LuaAssert(L, aqds.nth(1).xyz() == util::XYZ(3,4,5));
|
LuaAssert(L, aqds.nth(1).xyz() == util::XYZ(3,4,5));
|
||||||
LuaAssert(L, aqds.nth(1).graphic() == "nothing");
|
LuaAssert(L, aqds.nth(1).graphic() == "");
|
||||||
LuaAssert(L, aqds.nth(1).plane() == "nowhere");
|
LuaAssert(L, aqds.nth(1).plane() == "");
|
||||||
|
|
||||||
LuaAssert(L, aqds.nth(2).id() == 12346);
|
LuaAssert(L, aqds.nth(2).id() == 12346);
|
||||||
LuaAssert(L, aqds.nth(2).bits() == AnimStep::HAS_GRAPHIC);
|
LuaAssert(L, aqds.nth(2).bits() == AnimStep::HAS_GRAPHIC);
|
||||||
@@ -351,7 +404,7 @@ LuaDefine(unittests_animqueue, "c") {
|
|||||||
LuaAssert(L, aqds.nth(2).facing() == 0.0);
|
LuaAssert(L, aqds.nth(2).facing() == 0.0);
|
||||||
LuaAssert(L, aqds.nth(2).xyz() == util::XYZ(3,4,5));
|
LuaAssert(L, aqds.nth(2).xyz() == util::XYZ(3,4,5));
|
||||||
LuaAssert(L, aqds.nth(2).graphic() == "banana");
|
LuaAssert(L, aqds.nth(2).graphic() == "banana");
|
||||||
LuaAssert(L, aqds.nth(2).plane() == "nowhere");
|
LuaAssert(L, aqds.nth(2).plane() == "");
|
||||||
|
|
||||||
LuaAssert(L, aqds.nth(3).id() == 12347);
|
LuaAssert(L, aqds.nth(3).id() == 12347);
|
||||||
LuaAssert(L, aqds.nth(3).bits() == AnimStep::HAS_FACING);
|
LuaAssert(L, aqds.nth(3).bits() == AnimStep::HAS_FACING);
|
||||||
@@ -359,7 +412,7 @@ LuaDefine(unittests_animqueue, "c") {
|
|||||||
LuaAssert(L, aqds.nth(3).facing() == 301.0);
|
LuaAssert(L, aqds.nth(3).facing() == 301.0);
|
||||||
LuaAssert(L, aqds.nth(3).xyz() == util::XYZ(3,4,5));
|
LuaAssert(L, aqds.nth(3).xyz() == util::XYZ(3,4,5));
|
||||||
LuaAssert(L, aqds.nth(3).graphic() == "banana");
|
LuaAssert(L, aqds.nth(3).graphic() == "banana");
|
||||||
LuaAssert(L, aqds.nth(3).plane() == "nowhere");
|
LuaAssert(L, aqds.nth(3).plane() == "");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,10 +38,13 @@ class AnimStep {
|
|||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
HAS_FACING = 1,
|
HAS_FACING = 1,
|
||||||
HAS_XYZ = 2,
|
HAS_X = 2,
|
||||||
HAS_GRAPHIC = 4,
|
HAS_Y = 4,
|
||||||
HAS_PLANE = 8,
|
HAS_Z = 8,
|
||||||
HAS_EVERYTHING = 15,
|
HAS_XYZ = 14,
|
||||||
|
HAS_GRAPHIC = 16,
|
||||||
|
HAS_PLANE = 32,
|
||||||
|
HAS_EVERYTHING = 63,
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -60,17 +63,54 @@ public:
|
|||||||
|
|
||||||
int64_t id() const { return id_; }
|
int64_t id() const { return id_; }
|
||||||
int bits() const { return bits_; }
|
int bits() const { return bits_; }
|
||||||
const std::string &action() const { return action_; }
|
|
||||||
|
|
||||||
|
const std::string &action() const { return action_; }
|
||||||
double facing() const { return facing_; }
|
double facing() const { return facing_; }
|
||||||
util::XYZ xyz() const { return xyz_; }
|
float x() const { return xyz_.x; }
|
||||||
|
float y() const { return xyz_.y; }
|
||||||
|
float z() const { return xyz_.z; }
|
||||||
|
const util::XYZ &xyz() const { return xyz_; }
|
||||||
const std::string &graphic() const { return graphic_; }
|
const std::string &graphic() const { return graphic_; }
|
||||||
const std::string &plane() const { return plane_; }
|
const std::string &plane() const { return plane_; }
|
||||||
|
|
||||||
bool has_facing() const { return bits_ & AnimStep::HAS_FACING; }
|
bool has_facing() const { return bits_ & HAS_FACING; }
|
||||||
bool has_xyz() const { return bits_ & AnimStep::HAS_XYZ; }
|
bool has_x() const { return bits_ & HAS_X; }
|
||||||
|
bool has_y() const { return bits_ & HAS_Y; }
|
||||||
|
bool has_z() const { return bits_ & HAS_Z; }
|
||||||
|
bool has_xyz() const { return (bits_ & HAS_XYZ) == HAS_XYZ; }
|
||||||
bool has_graphic() const { return bits_ & AnimStep::HAS_GRAPHIC; }
|
bool has_graphic() const { return bits_ & AnimStep::HAS_GRAPHIC; }
|
||||||
bool has_plane() const { return bits_ & AnimStep::HAS_PLANE; }
|
bool has_plane() const { return bits_ & AnimStep::HAS_PLANE; }
|
||||||
|
|
||||||
|
void set_action(const std::string &action);
|
||||||
|
void set_facing(float f);
|
||||||
|
void set_x(float f);
|
||||||
|
void set_y(float f);
|
||||||
|
void set_z(float z);
|
||||||
|
void set_xyz(const util::XYZ &xyz);
|
||||||
|
void set_graphic(const std::string &g);
|
||||||
|
void set_plane(const std::string &p);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
// Create an AnimStep from a lua table.
|
||||||
|
//
|
||||||
|
// Lua stack must contain a table, which may contain:
|
||||||
|
// action: "action"
|
||||||
|
// facing: 0.0 - 360.0
|
||||||
|
// x: x-coordinate
|
||||||
|
// y: y-coordinate
|
||||||
|
// z: z-coordinate
|
||||||
|
// graphic: "graphic"
|
||||||
|
// plane: "plane"
|
||||||
|
//
|
||||||
|
void from_lua(lua_State *L, int idx);
|
||||||
|
|
||||||
|
// For any values that are unchanged in this step,
|
||||||
|
// echo the values of the previous step.
|
||||||
|
void echo(const AnimStep &prev);
|
||||||
|
|
||||||
|
// Verify that this step echoes the previous step.
|
||||||
|
bool echoes(const AnimStep &prev) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AnimQueue {
|
class AnimQueue {
|
||||||
@@ -85,37 +125,22 @@ public:
|
|||||||
size_t size() const { return steps_.size(); }
|
size_t size() const { return steps_.size(); }
|
||||||
int32_t size_limit() const { return size_limit_; }
|
int32_t size_limit() const { return size_limit_; }
|
||||||
|
|
||||||
// Clear the steps. Doesn't affect size_limit or id.
|
// Discard all but the most recent N steps.
|
||||||
|
void keep_only(int n);
|
||||||
|
|
||||||
|
// Clear the steps.
|
||||||
|
// The resulting steps aren't empty. There will be one
|
||||||
|
// step in the queue, which will be on the plane "", at (0,0,0).
|
||||||
|
// Doesn't affect size_limit.
|
||||||
void clear_steps();
|
void clear_steps();
|
||||||
|
|
||||||
// Mutators to create new steps from C++
|
// Mutator to create a new step.
|
||||||
//
|
void add(int64_t id, const AnimStep &step);
|
||||||
void add(int64_t id, const std::string &action);
|
|
||||||
void set_facing(float f);
|
|
||||||
void set_xyz(util::XYZ xyz);
|
|
||||||
void set_graphic(const std::string &g);
|
|
||||||
void set_plane(const std::string &p);
|
|
||||||
|
|
||||||
// Serialize or deserialize to a StreamBuffer
|
// Serialize or deserialize to a StreamBuffer
|
||||||
void serialize(StreamBuffer *sb);
|
void serialize(StreamBuffer *sb);
|
||||||
void deserialize(StreamBuffer *sb);
|
void deserialize(StreamBuffer *sb);
|
||||||
|
|
||||||
// Mutator to create new steps from lua.
|
|
||||||
//
|
|
||||||
// Lua stack must contain a table, which may contain:
|
|
||||||
// action: "action"
|
|
||||||
// facing: 0.0 - 360.0
|
|
||||||
// x: x-coordinate
|
|
||||||
// y: y-coordinate
|
|
||||||
// z: z-coordinate
|
|
||||||
// dx: delta-x
|
|
||||||
// dy: delta-y
|
|
||||||
// dz: delta-z
|
|
||||||
// graphic: "graphic"
|
|
||||||
// plane: "plane"
|
|
||||||
//
|
|
||||||
void add(int64_t id, lua_State *L, int idx);
|
|
||||||
|
|
||||||
// Get the final resting place after all animations are complete.
|
// Get the final resting place after all animations are complete.
|
||||||
const AnimStep &back() const;
|
const AnimStep &back() const;
|
||||||
|
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ void LuaStack::getclass(LuaSlot classtab, LuaSlot classname) const {
|
|||||||
} else {
|
} else {
|
||||||
LS.set(classtab, classname);
|
LS.set(classtab, classname);
|
||||||
if (!LS.istable(classtab)) {
|
if (!LS.istable(classtab)) {
|
||||||
luaL_error(L_, "parameter must be a class");
|
luaL_error(L_, "class can be a string or a table");
|
||||||
}
|
}
|
||||||
LS.rawget(cname, classtab, "__class");
|
LS.rawget(cname, classtab, "__class");
|
||||||
if (!LS.isstring(cname)) {
|
if (!LS.isstring(cname)) {
|
||||||
|
|||||||
@@ -76,8 +76,11 @@ void Tangible::be_a_player() {
|
|||||||
if (!id_player_pool_.fifo_enabled()) {
|
if (!id_player_pool_.fifo_enabled()) {
|
||||||
id_player_pool_.enable_fifo();
|
id_player_pool_.enable_fifo();
|
||||||
|
|
||||||
anim_queue_.add(world_->id_global_pool_.get_one(), "");
|
AnimStep asinit;
|
||||||
anim_queue_.set_graphic("player");
|
asinit.set_graphic("player");
|
||||||
|
anim_queue_.add(world_->id_global_pool_.get_one(), asinit);
|
||||||
|
anim_queue_.keep_only(1);
|
||||||
|
update_plane_item();
|
||||||
|
|
||||||
LuaVar classtab, mt, place, tangibles;
|
LuaVar classtab, mt, place, tangibles;
|
||||||
LuaStack LS(world_->state(), classtab, mt, place, tangibles);
|
LuaStack LS(world_->state(), classtab, mt, place, tangibles);
|
||||||
@@ -466,7 +469,9 @@ LuaDefine(tangible_animate, "c") {
|
|||||||
World *w = World::fetch_global_pointer(L);
|
World *w = World::fetch_global_pointer(L);
|
||||||
Tangible *tan = w->tangible_get(L, tanobj.index());
|
Tangible *tan = w->tangible_get(L, tanobj.index());
|
||||||
int64_t id = w->id_global_pool_.alloc_id_for_thread(L);
|
int64_t id = w->id_global_pool_.alloc_id_for_thread(L);
|
||||||
tan->anim_queue_.add(id, L, config.index());
|
AnimStep step;
|
||||||
|
step.from_lua(L, config.index());
|
||||||
|
tan->anim_queue_.add(id, step);
|
||||||
tan->update_plane_item();
|
tan->update_plane_item();
|
||||||
return LS.result();
|
return LS.result();
|
||||||
}
|
}
|
||||||
@@ -484,6 +489,8 @@ LuaDefine(tangible_setclass, "c") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LuaDefine(tangible_delete, "c") {
|
LuaDefine(tangible_delete, "c") {
|
||||||
|
// TODO: we need some sanity checks to make sure you're not deleting
|
||||||
|
// the current player, or anything like that.
|
||||||
LuaArg tanobj;
|
LuaArg tanobj;
|
||||||
LuaStack LS(L, tanobj);
|
LuaStack LS(L, tanobj);
|
||||||
World *w = World::fetch_global_pointer(L);
|
World *w = World::fetch_global_pointer(L);
|
||||||
@@ -492,9 +499,49 @@ LuaDefine(tangible_delete, "c") {
|
|||||||
return LS.result();
|
return LS.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
LuaDefine(tangible_make, "c") {
|
LuaDefine(tangible_build, "c") {
|
||||||
World::fetch_global_pointer(L)->tangible_make(L, 0, true);
|
LuaArg config;
|
||||||
return 1;
|
LuaVar classname, classtab, mt;
|
||||||
|
LuaRet database;
|
||||||
|
LuaStack LS(L, config, classname, classtab, database, mt);
|
||||||
|
|
||||||
|
LS.checktable(config);
|
||||||
|
// Get the class of the new tangible.
|
||||||
|
LS.rawget(classname, config, "class");
|
||||||
|
if (LS.isnil(classname)) {
|
||||||
|
luaL_error(L, "must specify a class name");
|
||||||
|
}
|
||||||
|
LS.getclass(classtab, classname);
|
||||||
|
|
||||||
|
// Parse the initial animation step.
|
||||||
|
AnimStep initstep;
|
||||||
|
initstep.from_lua(L, config.index());
|
||||||
|
if (!initstep.has_xyz()) {
|
||||||
|
luaL_error(L, "You must specify (X,Y,Z) for new tangible");
|
||||||
|
}
|
||||||
|
if (!initstep.has_plane()) {
|
||||||
|
luaL_error(L, "You must specify plane for new tangible");
|
||||||
|
}
|
||||||
|
if (!initstep.has_graphic()) {
|
||||||
|
luaL_error(L, "You must specify graphic for new tangible");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: generate error if there's extra crap in the config table.
|
||||||
|
|
||||||
|
World *w = World::fetch_global_pointer(L);
|
||||||
|
Tangible *tan = w->tangible_make(L, 0, true);
|
||||||
|
lua_replace(L, database.index());
|
||||||
|
|
||||||
|
// Update the class of the new tangible.
|
||||||
|
LS.getmetatable(mt, database);
|
||||||
|
LS.rawset(mt, "__index", classtab);
|
||||||
|
|
||||||
|
// Update the animation queue and planemap of the new tangible.
|
||||||
|
int64_t stepid = w->id_global_pool_.alloc_id_for_thread(L);
|
||||||
|
tan->anim_queue_.add(stepid, initstep);
|
||||||
|
tan->update_plane_item();
|
||||||
|
|
||||||
|
return LS.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
LuaDefine(tangible_get, "c") {
|
LuaDefine(tangible_get, "c") {
|
||||||
|
|||||||
Reference in New Issue
Block a user