Add support for animate replace=true

This commit is contained in:
2023-10-03 18:17:24 -04:00
parent c1594a1d83
commit edea43839f
3 changed files with 187 additions and 122 deletions

View File

@@ -45,85 +45,85 @@ LuaDefine(tangible_animdebug, "tan",
return LS.result();
}
LuaDefine(tangible_animstate, "tan",
"|Return the animation state variables of the tangible as a table."
LuaDefine(tangible_animfinal, "tan",
"|Return the final step in the animation queue."
"|"
"|The animation system stores 'animation state variables. "
"|There are several builtin animation state variables. The"
"|following is a list, along with some example values that"
"|might be used if the object were a pirate treasure chest."
"|The animation queue stores animation steps. This function returns"
"|the final animation step. An animation step consists of key-value"
"|pairs. Some of those key-value pairs describe the last thing that"
"|happened to the tangible. Others describe the final resting place"
"|of the tangible."
"|"
"|For example, if the tangible were a pirate chest, the key-value"
"|pairs might be:"
"|"
"| action='open' # last thing the chest did"
"| xyz={1,2,3} # xyz coordinate"
"| plane='earth' # plane where the chest is located"
"| facing=0 # rotation of the chest"
"| bp='BP_piratechest' # name of an unreal blueprint"
"| model='SM_piratechest' # name of an unreal mesh"
"|"
"|There can also be user-defined animation state variables."
"|For example, for a pirate chest, you might want to add two"
"|more state variables:"
"|"
"| open=true # chest can be open or closed"
"| fullness=0.8 # how big the heap of coins is"
"|"
"|All state variables must be one of four types: number, string,"
"|boolean, or coordinate. All state variables must have simple"
"|identifiers for names."
"|"
"|Animation state variables are updated when you use"
"|tangible.animate to create an animation record. For example,"
"|suppose your character is initialized at xyz={1,1,1}. Then"
"|he walks to xyz={2,2,2}, then he walks to xyz={3,3,3}."
"|The animation queue now contains three animation steps:"
"|"
"|Animation Queue:"
"| Step 1: action:initialize xyz={1,1,1} ..."
"| Step 2: action:walkto xyz={2,2,2} ..."
"| Step 3: action:walkto xyz={3,3,3} ..."
"|"
"|Notice that the state variable xyz is stored three times, once"
"|in each animation step. All animation state variables are stored"
"|in every animation step. When you use tangible.animstate to fetch"
"|the current value of the animation state variables, you're"
"|actually fetching the state variables from the last step in"
"|the animation queue."
"|"
"|You can use this function, tangible.animstate, to view the"
"|current set of state variables. You can use tangible.animinit"
"|to reconfigure the set of user-defined state variables. You"
"|can use tangible.animate to create animation steps, which can"
"|alter any of the state variables."
"|See doc(tangible.animinit) for more information about animation queues."
"|") {
LuaArg tanobj;
LuaRet result;
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_persistent();
AnimState state = tan->anim_queue_.get_final_everything();
state.to_lua(LS, result, true);
return LS.result();
}
LuaDefine(tangible_animinit, "tan,config",
"|Reinitialize the animation queue."
"|Reinitialize the animation queue and specify persistent state."
"|"
"|The animation queue stores certain animation state variables."
"|See doc(tangible.animstate) for more information about animation"
"|state variables."
"|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"
"|three feet in the air, you might find this animation step in the"
"|animation queue:"
"|"
"| action='jump' - the name of the animation to perform"
"| height=3.0 - the height to which you want him to jump"
"| xyz={1,2,3} - person's xyz coordinate during the jump"
"| plane=earth - plane where the jump takes place"
"|"
"|Some of those key-value pairs are 'persistent'. For example, xyz is"
"|persistent. That means that the player must always have an xyz"
"|coordinate. Every single animation step in the queue must"
"|contain a value for xyz. Likewise, 'plane' is a persistent variable."
"|The player must always be on some plane or another."
"|"
"|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}))"
"|"
"|This adds a step to the animation queue. That step contains"
"|xyz and plane, even though we didn't specify xyz and plane in"
"|the 'animate' command above. The values for xyz and plane will be"
"|copied over from the previous animation step. In this way, those values"
"|get persisted: they stay the same unless you change them in"
"|the 'animate' command."
"|"
"|There are five hardwired persistent variables: plane,xyz,facing,bp,model."
"|These five variables are persistent no matter what. This function,"
"|tangible.animinit, optionally allows you to create more persistent"
"|variables. For example, let's say you have a pirate chest. You might"
"|want to add two persistent variables in addition to the usual set:"
"|"
"| open=true - whether the chest is open or closed"
"| heapsize=0.8 - the size of the heap of coins"
"|"
"|Making a variable persistent means that it will always have a value"
"|no matter what you do."
"|"
"|This function, tangible.animinit, is used to reconfigure the set of"
"|user-defined state variables. The config table that you pass in must"
"|be key-value pairs. Keys must be simple identifiers. Values can be"
"|numbers, strings, booleans, or coordinates."
"|"
"|After tangible.animinit, the tangible's animation state variables will"
"|consist of the user-defined variables listed in the config table,"
"|plus all the builtin animation state variables."
"|"
"|Optionally, the config table can also supply values for some or all"
"|of the builtin state variables. For example, you could supply xyz"
"|in the config table. If you do, the tangible will move to a new xyz"
"|coordinate. If not, the tangible will retain its old xyz coordinate."
"|persistent state variables that are retained by the tangible's"
"|animation queue. You must provide a table containing all the"
"|persistent values you want, and their initial values."
"|") {
LuaArg tanobj, config;
LuaDefStack LS(L, tanobj, config);
@@ -144,46 +144,65 @@ LuaDefine(tangible_animinit, "tan,config",
return LS.result();
}
LuaDefine(tangible_animate, "tan,config",
LuaDefine(tangible_animate, "tan,options,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."
"|"
"|It might be useful to read about 'animation state variables' before"
"|reading this explanation. See doc(tangible.animstate)."
"|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"
"|identifiers. Values can be numbers, strings, booleans, or"
"|coordinates."
"|"
"|Some of the key-value pairs may match the name of an animation state"
"|Some of the key-value pairs may match the name of a persistent"
"|variable. If so, that key-value pair permanently changes the"
"|value of that animation state variable. The new value will"
"|value of that persistent variable. The new value will"
"|be retained for all future animation steps."
"|"
"|Some of the key-value pairs may NOT match the name of any animation"
"|state variable. If so, that key-value pair is part of the"
"|Some of the key-value pairs may not match the name of any persistent"
"|variable. If so, that key-value pair is part of the"
"|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, config;
LuaDefStack LS(L, tanobj, config);
LuaArg tanobj, options, steptab;
LuaVar option;
LuaDefStack LS(L, option, tanobj, options, steptab);
bool replace = false;
if (!LS.isnil(options)) {
LuaKeywordParser kp(LS, options);
if (kp.parse(option, "replace")) {
replace = LS.ckboolean(option);
}
}
World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_get(LS, tanobj, false);
AnimState state = tan->anim_queue_.get_final_persistent();
eng::string error = state.apply_lua(LS, config, false);
eng::string error = state.apply_lua(LS, steptab, false);
if (!error.empty()) {
luaL_error(L, "%s", error.c_str());
}
tan->anim_queue_.add(state);
if (replace) {
tan->anim_queue_.replace(state);
} else {
tan->anim_queue_.add(state);
}
tan->update_plane_item();
return LS.result();
}
LuaDefine(tangible_setclass, "tan,class",
"|Set the class of the tangible."
"|The class can be a 'class table' (ie, a table of methods), "