Improved Docs, AnimationStepApplyMesh+Materials, some other minor tweaks

This commit is contained in:
2026-02-06 17:34:26 -05:00
parent a2e179e15b
commit 56765fdc16
28 changed files with 731 additions and 165 deletions

View File

@@ -85,11 +85,11 @@ static AnimValue parse_anim_value(LuaCoreStack &LS, LuaSlot val) {
return result;
}
void AnimState::set_persistent(const eng::string &name) {
void AnimStepEditor::set_persistent(const eng::string &name) {
map_[name].persistent = true;
}
void AnimState::print_debug_string(eng::ostringstream &oss) {
void AnimStepEditor::print_debug_string(eng::ostringstream &oss) {
bool first = true;
if (map_.empty()) {
oss << "[empty]";
@@ -117,13 +117,13 @@ void AnimState::print_debug_string(eng::ostringstream &oss) {
}
}
eng::string AnimState::debug_string() {
eng::string AnimStepEditor::debug_string() {
eng::ostringstream oss;
print_debug_string(oss);
return oss.str();
}
eng::string AnimState::encode() const {
eng::string AnimStepEditor::encode() const {
StreamBuffer sb;
for (const auto &pair : map_) {
const eng::string &name = pair.first;
@@ -135,7 +135,7 @@ eng::string AnimState::encode() const {
return eng::string(sb.view());
}
void AnimState::decode(std::string_view s) {
void AnimStepEditor::decode(std::string_view s) {
map_.clear();
StreamBuffer sb(s);
while (!sb.empty()) {
@@ -146,7 +146,7 @@ void AnimState::decode(std::string_view s) {
}
}
void AnimState::decode_persistent(std::string_view s) {
void AnimStepEditor::decode_persistent(std::string_view s) {
map_.clear();
StreamBuffer sb(s);
AnimValue dummy;
@@ -163,7 +163,7 @@ void AnimState::decode_persistent(std::string_view s) {
}
}
eng::string AnimState::add_default(const eng::string &name, const AnimValue &def, const AnimState *other) {
eng::string AnimStepEditor::add_default(const eng::string &name, const AnimValue &def, const AnimStepEditor *other) {
AnimValue &value = map_[name];
value.persistent = true;
if (value.type == SimpleDynamicTag::UNINITIALIZED) {
@@ -185,7 +185,7 @@ eng::string AnimState::add_default(const eng::string &name, const AnimValue &def
return "";
}
eng::string AnimState::add_defaults(const AnimState *other) {
eng::string AnimStepEditor::add_defaults(const AnimStepEditor *other) {
eng::string err;
AnimValue defval;
@@ -209,7 +209,7 @@ eng::string AnimState::add_defaults(const AnimState *other) {
}
eng::string AnimState::from_lua(LuaCoreStack &LS0, LuaSlot tab, bool persistent, bool allowauto) {
eng::string AnimStepEditor::from_lua(LuaCoreStack &LS0, LuaSlot tab, bool persistent, bool allowauto) {
LuaVar key, val;
LuaExtStack LS(LS0.state(), key, val);
util::DXYZ xyz;
@@ -241,7 +241,7 @@ eng::string AnimState::from_lua(LuaCoreStack &LS0, LuaSlot tab, bool persistent,
return "";
}
eng::string AnimState::merge(const AnimState &previous, const AnimState &update) {
eng::string AnimStepEditor::merge(const AnimStepEditor &previous, const AnimStepEditor &update) {
// Copy everything over from the previous entry.
map_ = previous.map_;
@@ -286,7 +286,7 @@ eng::string AnimState::merge(const AnimState &previous, const AnimState &update)
}
void AnimState::to_lua(LuaCoreStack &LS0, LuaSlot tab, bool transient, bool persistent) {
void AnimStepEditor::to_lua(LuaCoreStack &LS0, LuaSlot tab, bool transient, bool persistent) {
LuaVar name, val;
LuaExtStack LS(LS0.state(), name, val);
LS.newtable(tab);
@@ -319,7 +319,7 @@ void AnimState::to_lua(LuaCoreStack &LS0, LuaSlot tab, bool transient, bool pers
// The syntax used by this parser is not general enough to represent all
// possible strings. That's OK, though, since it's just for unit testing.
void AnimState::parse(std::string_view config) {
void AnimStepEditor::parse(std::string_view config) {
while (true) {
config = sv::ltrim(config);
if (config.empty()) break;
@@ -336,7 +336,7 @@ void AnimState::parse(std::string_view config) {
}
}
void AnimState::clear_and_parse(std::string_view config) {
void AnimStepEditor::clear_and_parse(std::string_view config) {
map_.clear();
parse(config);
}
@@ -442,15 +442,15 @@ void AnimQueue::update_encqueue(int limit, bool add, std::string_view add_enc, i
}
AnimQueue::AnimQueue() {
update_encqueue(10, true, AnimState().encode(), 0, 0);
update_encqueue(10, true, AnimStepEditor().encode(), 0, 0);
}
void AnimQueue::clear(const AnimState &state) {
void AnimQueue::clear(const AnimStepEditor &state) {
update_encqueue(get_size_limit(), true, state.encode(), 0, 0);
}
void AnimQueue::clear() {
update_encqueue(get_size_limit(), true, AnimState().encode(), 0, 0);
update_encqueue(get_size_limit(), true, AnimStepEditor().encode(), 0, 0);
}
void AnimQueue::set_limit(int limit) {
@@ -458,12 +458,12 @@ void AnimQueue::set_limit(int limit) {
update_encqueue(limit, false, std::string_view(), 0, limit);
}
void AnimQueue::add(const AnimState &state) {
void AnimQueue::add(const AnimStepEditor &state) {
int limit = get_size_limit();
update_encqueue(limit, true, state.encode(), 0, limit - 1);
}
void AnimQueue::replace(const AnimState &state) {
void AnimQueue::replace(const AnimStepEditor &state) {
int limit = get_size_limit();
update_encqueue(limit, true, state.encode(), 1, limit);
}
@@ -528,7 +528,7 @@ void AnimQueue::print_debug_string(eng::ostringstream &oss, bool full) const {
assert(sb.empty());
for (int i = encsteps.size() - 1; i >= 0; i --) {
if (!first) oss << "; ";
AnimState state(encsteps[i]);
AnimStepEditor state(encsteps[i]);
state.print_debug_string(oss);
first = false;
}
@@ -553,16 +553,16 @@ AnimCoreState AnimQueue::get_final_core_state() const {
return result;
}
AnimState AnimQueue::get_final_persistent() const {
AnimStepEditor AnimQueue::get_final_persistent() const {
std::string_view encstep = get_final_encstep();
AnimState result;
AnimStepEditor result;
result.decode_persistent(encstep);
return result;
}
AnimState AnimQueue::get_final_everything() const {
AnimStepEditor AnimQueue::get_final_everything() const {
std::string_view encstep = get_final_encstep();
AnimState result;
AnimStepEditor result;
result.decode(encstep);
return result;
}
@@ -571,44 +571,44 @@ LuaDefine(unittests_animqueue, "", "some unit tests") {
// Useful objects.
AnimQueue aq, aqs;
StreamBuffer sb;
AnimState astate;
AnimStepEditor astate;
eng::string enc;
AnimCoreState core;
// Debug string of a newly initialized queue
LuaAssertStrEq(L, aq.full_debug_string(), "limit=10; [empty]");
// Test AnimState simple setters.
// Test AnimStepEditor simple setters.
astate.set_string("color", "blue");
astate.set_dxyz("xyz", util::DXYZ(1,2,3));
astate.set_number("half", 0.5);
astate.set_boolean("nice", true);
LuaAssertStrEq(L, astate.debug_string(), "color:blue half:0.5 nice:true xyz:1,2,3");
// // Test AnimState simple getters.
// // Test AnimStepEditor simple getters.
// LuaAssert(L, astate.get_string("color") == "blue");
// LuaAssert(L, astate.get_xyz("xyz") == util::DXYZ(1,2,3));
// LuaAssert(L, astate.get_number("half") == 0.5);
// LuaAssert(L, astate.get_boolean("nice") == true);
// // Test AnimState simple getters on nonexistent data.
// // Test AnimStepEditor simple getters on nonexistent data.
// LuaAssert(L, astate.get_string("q") == "");
// LuaAssert(L, astate.get_xyz("q") == util::DXYZ(0,0,0));
// LuaAssert(L, astate.get_number("q") == 0.0);
// LuaAssert(L, astate.get_boolean("q") == false);
// // Test AnimState simple getters on wrong-type data.
// // Test AnimStepEditor simple getters on wrong-type data.
// LuaAssert(L, astate.get_string("half") == "");
// LuaAssert(L, astate.get_xyz("half") == util::DXYZ(0,0,0));
// LuaAssert(L, astate.get_number("color") == 0.0);
// LuaAssert(L, astate.get_boolean("color") == false);
// Test AnimState persistence manipulation.
// Test AnimStepEditor persistence manipulation.
astate.set_persistent("color");
astate.set_persistent("nice");
LuaAssertStrEq(L, astate.debug_string(), "color=blue half:0.5 nice=true xyz:1,2,3");
// Test AnimState parser.
// Test AnimStepEditor parser.
astate.clear_and_parse("color:green mean=true pos=3,4,5 ok:false");
LuaAssertStrEq(L, astate.debug_string(), "color:green mean=true ok:false pos=3,4,5");

View File

@@ -1,13 +1,15 @@
///////////////////////////////////////////////////////////////////
//
// ANIMATION QUEUES
// ANIMATION QUEUES AND ANIMATION STEPS
//
// See "Animation Queues and Tangible Actors.md" for an overview.
//
// An animation queue is a fifo queue of animation steps. New animations are
// pushed on the back, and old ones are popped from the front.
//
// An animation step is a set of key-value pairs, where each key is an
// identifier, and each value is either a number, a boolean, an XYZ coordinate,
// or a string. A key-value pair can be either persistent or nonpersistent.
// identifier, and each value is either a number, boolean, vector,
// token, or string. A key-value pair can be either persistent or nonpersistent.
// So a typical animation step might be:
//
// action=walk [nonpersistent]
@@ -22,9 +24,34 @@
// by mixing the hash value of the previous step with the hash value
// of the encoded string of key-value pairs.
//
//
///////////////////////////////////////////////////////////////////
//
// SERIALIZED STORAGE
// Class AnimStepEditor is used to read+write animation steps.
//
// Note: this class is not used for storage of animation steps.
// Animation steps are stored in class AnimQueue. AnimStepEditor
// is only used when you want to extract animation steps from
// an AnimQueue, or insert new animation steps into an AnimQueue.
//
// Class AnimStepEditor is quite simple: it's a map from Key to
// AnimValue. AnimValue is a container that can hold a number,
// string, vector, token, or boolean. Class AnimStepEditor provides
// a variety of accessors to set key-value pairs.
//
// For example, you can populate an animation step by setting
// key-value pairs directly. You can import key-value pairs
// from a lua table. You can also merge key-value pairs from
// a different AnimStepEditor.
//
// When importing from a lua_table or a from another AnimStepEditor,
// there are rules for resolving conflicts between any key-value
// pairs that are already in the builder with those being imported.
// See the documentation for those functions for more information.
//
///////////////////////////////////////////////////////////////////
//
// Class AnimQueue stores animation queues.
//
// The entired animation queue is stored in a serialized format,
// as a shared string. This means that the animation queue can be
@@ -118,7 +145,7 @@ struct AnimValue : public SimpleDynamicValue {
};
class AnimState
class AnimStepEditor
{
private:
using Map = eng::map<eng::string, AnimValue>;
@@ -126,7 +153,7 @@ private:
// Set the default value, internal
//
eng::string add_default(const eng::string &name, const AnimValue &v, const AnimState *other);
eng::string add_default(const eng::string &name, const AnimValue &v, const AnimStepEditor *other);
public:
// Clear everything
@@ -160,7 +187,7 @@ public:
// Constructs an empty state.
//
AnimState() {}
AnimStepEditor() {}
// Convert to an encoded string.
//
@@ -188,7 +215,7 @@ public:
// - If no default value can be found in 'other', then a hardwired
// default value is provided.
//
eng::string add_defaults(const AnimState *other);
eng::string add_defaults(const AnimStepEditor *other);
// Parse an animstate from a Lua Table.
//
@@ -199,7 +226,7 @@ public:
//
// If 'allowauto' is true, then the lua table may contain a key-value
// pair of the form (key, math.auto). These keys will be stored in the
// AnimState map with mapentry.type == SimpleDynamicTag::AUTO.
// AnimStepEditor map with mapentry.type == SimpleDynamicTag::AUTO.
// This is done to express an intent that the value should be
// automatically computer later.
//
@@ -207,7 +234,7 @@ public:
// Generate a merged animstate using a previous state and an update.
//
// Keys from both previous and update are combined to create this AnimState.
// Keys from both previous and update are combined to create this AnimStepEditor.
// Values from 'update' override values from 'previous'. Persistent flags
// are taken from 'previous'. If a key exists in both previous and update,
// and the key is persistent in 'previous', then the types must match,
@@ -218,7 +245,7 @@ public:
// a rule to compute that value automatically. Failure to find a rule
// results in an error.
//
eng::string merge(const AnimState &previous, const AnimState &update);
eng::string merge(const AnimStepEditor &previous, const AnimStepEditor &update);
// Convert an animstate to a lua table.
//
@@ -250,7 +277,7 @@ public:
// Constructor from an encoded string.
//
AnimState(std::string_view s) { decode(s); }
AnimStepEditor(std::string_view s) { decode(s); }
};
struct AnimCoreState
@@ -271,7 +298,7 @@ public:
// Clear the steps to an initial state.
//
void clear();
void clear(const AnimState &initial);
void clear(const AnimStepEditor &initial);
// Change the size limit.
//
@@ -282,14 +309,14 @@ public:
// Note: add does not automatically compose the step with the previous
// step, you have to do that yourself.
//
void add(const AnimState &state);
void add(const AnimStepEditor &state);
// Replace the most recent animation step.
//
// Note: replace does not automatically compose the step with the previous
// step, you have to do that yourself.
//
void replace(const AnimState &state);
void replace(const AnimStepEditor &state);
// Serialize or deserialize to a StreamBuffer
//
@@ -324,11 +351,11 @@ public:
// Get the final entry, all persistent variables.
//
AnimState get_final_persistent() const;
AnimStepEditor get_final_persistent() const;
// Get the final entry, everything persistent and non-persistent.
//
AnimState get_final_everything() const;
AnimStepEditor get_final_everything() const;
// Get a serialized representation of the animation queue.
//

View File

@@ -256,22 +256,22 @@
// either.
//
// Lua has a datatype called 'lightuserdata'. A lightuserdata holds an
// int64. That gives me an option: I can store json null as
// lightuserdata(0x6E756C6C00000000). When we see this lightuserdata
// value, we would know we have a json null. Why 0x6E756C6C00000000?
// Because if you interpret those 8 bytes as 8 ascii characters, it's the
// string "null".
// int64. That gives me an option: I can store json null as a
// lightuserdata. When we see this lightuserdata value, we would know
// we have a json null.
//
// So that finally brings me to what a "token" is. A token is a lightuserdata
// containing up to 8 ascii characters. So in effect, it's a short string,
// but it's a string that's distinguishable from a normal lua string. It
// doesn't have the same type as a lua string (it shows up as a lightuserdata).
// containing a short string encoded as a base36 number. Tokens may only
// contain the characters a-z and 0-9, and can be up to 12 characters long
// (since 36^12 fits in 64 bits). In effect, it's a short string, but it's
// a string that's distinguishable from a normal lua string. It doesn't have
// the same type as a lua string (it shows up as a lightuserdata).
// The purpose of tokens is to represent special unique values, like json null.
//
// To make working with tokens easy, I've created a C++ class 'LuaToken'.
// To make working with tokens easy, I've created a C++ struct 'LuaToken'.
// It stores an int64. You can construct a LuaToken in two different ways:
//
// LuaToken(0x6E756C6C00000000)
// LuaToken(0x10FAA9)
// LuaToken("null")
//
// Those are equivalent. The second form is just as fast as the first,

View File

@@ -74,14 +74,19 @@ LuaDefine(tangible_animfinal, "tan",
LuaDefStack LS(L, tanobj, result);
World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_get(LS, tanobj, false);
AnimState state = tan->anim_queue_.get_final_everything();
state.to_lua(LS, result, true, true);
AnimStepEditor step = tan->anim_queue_.get_final_everything();
step.to_lua(LS, result, true, true);
return LS.result();
}
LuaDefine(tangible_animinit, "tan,config",
LuaDefine(tangible_animinit, "config",
"|Reinitialize the animation queue and specify persistent state."
"|"
"|The configuration table must contain the following keywords:"
"|"
"| tan: the tangible to reinitialize."
"| anim: a table of key-value pairs for the initial animation state."
"|"
"|Every tangible has an animation queue. The queue consists of a"
"|sequence of animation steps. Each step consists of a list of"
"|key-value pairs. For example, if you want a human person to jump"
@@ -102,7 +107,7 @@ LuaDefine(tangible_animinit, "tan,config",
"|When you add an animation step to the animation queue, you do not have"
"|to always specify xyz and plane. For example, you can legally say:"
"|"
"| tangible.animate(a, nil, {action='jump', height=3.0}))"
"| tangible.animate{tan=a, anim={action='jump', height=3.0}}"
"|"
"|This adds a step to the animation queue. That step contains"
"|xyz and plane, even though we didn't specify xyz and plane in"
@@ -125,39 +130,51 @@ LuaDefine(tangible_animinit, "tan,config",
"|"
"|This function, tangible.animinit, is used to reconfigure the set of"
"|persistent state variables that are retained by the tangible's"
"|animation queue. You must provide a table containing all the"
"|animation queue. You must provide an anim table containing all the"
"|persistent values you want, and their initial values."
"|") {
LuaArg tanobj, config;
LuaDefStack LS(L, tanobj, config);
LuaArg config;
LuaVar tanobj, animtab;
LuaDefStack LS(L, config, tanobj, animtab);
LuaKeywordParser kp(LS, config);
kp.required(tanobj, "tan");
kp.required(animtab, "anim");
kp.check_throw();
World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_get(LS, tanobj, false);
AnimState state;
eng::string error = state.from_lua(LS, config, true, false);
AnimStepEditor step;
eng::string error = step.from_lua(LS, animtab, true, false);
if (!error.empty()) {
luaL_error(L, "%s", error.c_str());
}
AnimState defsource = tan->anim_queue_.get_final_persistent();
error = state.add_defaults(&defsource);
AnimStepEditor defsource = tan->anim_queue_.get_final_persistent();
error = step.add_defaults(&defsource);
if (!error.empty()) {
luaL_error(L, "%s", error.c_str());
}
tan->anim_queue_.clear(state);
tan->anim_queue_.clear(step);
tan->update_plane_item();
return LS.result();
}
LuaDefine(tangible_animate, "tan,options,config",
LuaDefine(tangible_animate, "config",
"|Add an animation step to the tangible."
"|"
"|The animation queue stores animation steps. This function, "
"|tangible.animate, adds one new animation step to the queue."
"|The configuration table must contain the following keywords:"
"|"
"| tan: the tangible to animate."
"| anim: a table of key-value pairs for the animation step."
"| replace: (optional) if true, the last step in the queue is"
"| removed, and the new animation replaces it. Persistent"
"| state is carried over from the step that was replaced."
"|"
"|It might be useful to read doc(tangible.animinit) before reading"
"|more."
"|"
"|An animation step is just a list of key-value pairs. Therefore,"
"|the config table must be key-value pairs. Keys must be simple"
"|the anim table must be key-value pairs. Keys must be simple"
"|identifiers. Values can be numbers, strings, booleans, or"
"|coordinates."
"|"
@@ -171,34 +188,29 @@ LuaDefine(tangible_animate, "tan,options,config",
"|animation step, but nothing is propagated forward to future animation"
"|steps."
"|"
"|The options can be nil, or options can be a table containing"
"|the following flags:"
"|"
"| replace: if true, then the last step in the queue is removed,"
"| and the new animation replaces it. Persistent state is carried"
"| over from the step that was replaced."
"|"
"|") {
LuaArg tanobj, options, steptab;
LuaVar option;
LuaDefStack LS(L, option, tanobj, options, steptab);
LuaArg config;
LuaVar tanobj, animtab, option;
LuaDefStack LS(L, config, tanobj, animtab, option);
LuaKeywordParser kp(LS, config);
kp.required(tanobj, "tan");
kp.required(animtab, "anim");
bool replace = false;
if (!LS.isnil(options)) {
LuaKeywordParser kp(LS, options);
if (kp.optional(option, "replace")) {
replace = LS.ckboolean(option);
}
kp.final_check_throw();
if (kp.optional(option, "replace")) {
replace = LS.ckboolean(option);
}
kp.check_throw();
World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_get(LS, tanobj, false);
AnimState previous = tan->anim_queue_.get_final_persistent();
AnimState update;
eng::string error = update.from_lua(LS, steptab, false, true);
AnimStepEditor previous = tan->anim_queue_.get_final_persistent();
AnimStepEditor update;
eng::string error = update.from_lua(LS, animtab, false, true);
if (!error.empty()) {
luaL_error(L, "%s", error.c_str());
}
AnimState merge;
AnimStepEditor merge;
error = merge.merge(previous, update);
if (!error.empty()) {
luaL_error(L, "%s", error.c_str());
@@ -291,16 +303,13 @@ LuaDefine(tangible_build, "config",
"|Build a new tangible object."
"|"
"|The configuration table must contain the keyword 'class', which"
"|must be the name of a class created with 'makeclass'. It may also"
"|contain the following values:"
"|"
"| bp - the unreal blueprint, defaults to class name."
"| plane - the plane, defaults to actor.plane"
"| xyz - the xyz coordinate, defaults to actor.xyz"
"| facing - the rotation, defaults to actor.facing"
"|"
"|Tangible.build will create an initial animstate containing only"
"|bp, plane, xyz, and facing."
"|must be the name of a class created with 'makeclass'. It may"
"|optionally contain the keyword 'anim', which is a table of"
"|key-value pairs for the initial animation step. The anim table"
"|may contain any key-value pairs that tangible.animate accepts."
"|The mandatory keys (bp, plane, xyz, facing) will be defaulted"
"|from the actor if not specified. If bp is not specified, it"
"|defaults to the class name."
"|"
"|After creating the tangible and setting up the initial animation"
"|state, build will call the constructor for the tangible."
@@ -315,17 +324,14 @@ LuaDefine(tangible_build, "config",
"|The constructor is not allowed to block."
){
LuaArg config;
LuaVar classname, classtab, bp, plane, xyz, facing, mt, func;
LuaVar classname, classtab, animtab, mt, func;
LuaRet database;
LuaDefStack LS(L, config, classname, classtab, bp, plane, xyz, facing, mt, func, database);
LuaDefStack LS(L, config, classname, classtab, animtab, mt, func, database);
World *w = World::fetch_global_pointer(L);
LuaKeywordParser kp(LS, config);
kp.required(classname, "class");
kp.optional(bp, "bp");
kp.optional(plane, "plane");
kp.optional(xyz, "xyz");
kp.optional(facing, "facing");
kp.optional(animtab, "anim");
kp.check_throw();
// Verify the class.
@@ -335,41 +341,38 @@ LuaDefine(tangible_build, "config",
}
// Calculate the initial animation state.
AnimState state;
if (!LS.isnil(bp)) {
state.set_string("bp", LS.ckstring(bp));
} else {
state.set_string("bp", LS.classname(classtab));
AnimStepEditor step;
if (!LS.isnil(animtab)) {
err = step.from_lua(LS, animtab, true, false);
if (err != "") {
luaL_error(L, "%s", err.c_str());
}
}
if (!LS.isnil(plane)) {
state.set_string("plane", LS.ckstring(plane));
}
if (!LS.isnil(xyz)) {
state.set_dxyz("xyz", LS.ckxyz(xyz));
}
if (!LS.isnil(facing)) {
state.set_number("facing", LS.cknumber(facing));
// Default bp to the class name if not specified.
if (!step.contains("bp")) {
step.set_string("bp", LS.classname(classtab));
}
// Add default values from the actor. Set persistent flags.
Tangible *actor = w->tangible_get(w->lthread_actor_id_);
AnimState actorstate = actor->anim_queue_.get_final_persistent();
err = state.add_defaults(&actorstate);
AnimStepEditor actorstate = actor->anim_queue_.get_final_persistent();
err = step.add_defaults(&actorstate);
if (err != "") {
luaL_error(L, "%s", err.c_str());
}
int64_t new_id = w->alloc_id_predictable();
Tangible *tan = w->tangible_make(LS, database, new_id);
// Update the class of the new tangible.
LS.getmetatable(mt, database);
LS.rawset(mt, "__index", classtab);
// Initialize the animstate of the new tangible.
tan->anim_queue_.clear(state);
tan->anim_queue_.clear(step);
tan->update_plane_item();
// Call the constructor and finish.
LS.rawget(func, classtab, "init");
if (!LS.isfunction(func)) {

View File

@@ -227,7 +227,7 @@ Tangible *World::tangible_make(const LuaCoreStack &LS0, LuaSlot database, int64_
t->delete_on_disconnect_ = false;
// AnimQueue initializes itself to a valid default state.
AnimState state;
AnimStepEditor state;
state.add_defaults(nullptr);
t->anim_queue_.clear(state);
t->update_plane_item();

View File

@@ -7,7 +7,7 @@
void World::tangible_clear_anim_queue_to_empty(int64_t id) {
Tangible *t = tangible_get(id);
assert(t != nullptr);
AnimState state;
AnimStepEditor state;
t->anim_queue_.clear(state);
t->update_plane_item();
}
@@ -16,7 +16,7 @@ void World::tangible_clear_anim_queue_to_empty(int64_t id) {
void World::tangible_clear_plane_and_xyz(int64_t id, const eng::string &plane, const util::DXYZ &xyz) {
Tangible *t = tangible_get(id);
assert(t != nullptr);
AnimState state;
AnimStepEditor state;
state.set_string("plane", plane);
state.set_dxyz("xyz", xyz);
state.set_persistent("plane");
@@ -28,7 +28,7 @@ void World::tangible_clear_plane_and_xyz(int64_t id, const eng::string &plane, c
void World::tangible_walkto(int64_t id, float x, float y) {
Tangible *t = tangible_get(id);
assert(t != nullptr);
AnimState state = t->anim_queue_.get_final_persistent();
AnimStepEditor state = t->anim_queue_.get_final_persistent();
state.set_string("action", "walkto");
state.set_dxyz("xyz", util::DXYZ(x,y,0.0));
t->anim_queue_.add(state);
@@ -71,7 +71,7 @@ eng::string World::tangibles_near_debug_string(int64_t actor, int64_t distance)
LS.rawget(tanobj, tangibles, id);
LS.tangetclass(classtab, tanobj);
eng::string cname = LS.classname(classtab);
AnimState state = tan->anim_queue_.get_final_persistent();
AnimStepEditor state = tan->anim_queue_.get_final_persistent();
result << id << " (" << cname << "): " << state.debug_string() << std::endl;
}
return result.str();