156 lines
4.4 KiB
C++
156 lines
4.4 KiB
C++
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// ANIMATION QUEUES
|
|
//
|
|
// 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 has an "action" which is usually the name of an animation,
|
|
// or it's a special token like "walk" or "warp." Each animation step shows the
|
|
// resulting AnimState that the player finds himself in after executing the
|
|
// action.
|
|
//
|
|
// The first step in an animation queue always has id=0 and action="". This step
|
|
// represents the initial state of the sprite before any animations or
|
|
// movements.
|
|
//
|
|
// To add new items to the AnimQueue, use this process: first, call add(id,
|
|
// action). This adds a new step to the queue. Then, call set_xyz, set_facing,
|
|
// set_plane, or an other setter. These setters are meant to only be used
|
|
// immediately after calling 'add' to populate the new step.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef ANIMQUEUE_HPP
|
|
#define ANIMQUEUE_HPP
|
|
|
|
#include <set>
|
|
#include <string>
|
|
#include <deque>
|
|
#include <cassert>
|
|
#include <unordered_map>
|
|
#include "streambuffer.hpp"
|
|
#include "util.hpp"
|
|
|
|
|
|
class AnimStep {
|
|
friend class AnimQueue;
|
|
public:
|
|
enum {
|
|
HAS_FACING = 1,
|
|
HAS_X = 2,
|
|
HAS_Y = 4,
|
|
HAS_Z = 8,
|
|
HAS_XYZ = 14,
|
|
HAS_GRAPHIC = 16,
|
|
HAS_PLANE = 32,
|
|
HAS_EVERYTHING = 63,
|
|
};
|
|
|
|
private:
|
|
int64_t id_;
|
|
int16_t bits_;
|
|
std::string action_;
|
|
|
|
float facing_;
|
|
util::XYZ xyz_;
|
|
std::string graphic_;
|
|
std::string plane_;
|
|
|
|
public:
|
|
AnimStep();
|
|
~AnimStep();
|
|
|
|
int64_t id() const { return id_; }
|
|
int bits() const { return bits_; }
|
|
|
|
const std::string &action() const { return action_; }
|
|
double facing() const { return facing_; }
|
|
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 &plane() const { return plane_; }
|
|
|
|
bool has_facing() const { return bits_ & HAS_FACING; }
|
|
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_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 {
|
|
private:
|
|
int32_t size_limit_;
|
|
std::deque<AnimStep> steps_;
|
|
|
|
public:
|
|
AnimQueue();
|
|
|
|
const AnimStep &nth(int n) const { return steps_[n]; }
|
|
size_t size() const { return steps_.size(); }
|
|
int32_t size_limit() const { return size_limit_; }
|
|
|
|
// 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();
|
|
|
|
// Mutator to create a new step.
|
|
void add(int64_t id, const AnimStep &step);
|
|
|
|
// Serialize or deserialize to a StreamBuffer
|
|
void serialize(StreamBuffer *sb);
|
|
void deserialize(StreamBuffer *sb);
|
|
|
|
// Get the final resting place after all animations are complete.
|
|
const AnimStep &back() const;
|
|
|
|
// (For testing): change the size limit.
|
|
void set_size_limit(int32_t n);
|
|
|
|
// (For testing): make sure the invariants are preserved.
|
|
bool valid();
|
|
};
|
|
|
|
#endif // ANIMQUEUE_HPP
|
|
|