summary refs log tree commit diff stats
path: root/src/sprite.h
blob: 86474caa7658bcfc76e7351ec2d8750b26b086cf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#ifndef SPRITE_H_70503825
#define SPRITE_H_70503825

#include <deque>
#include <map>
#include <string_view>
#include <vector>
#include "direction.h"
#include "renderer.h"
#include "vector.h"
#include "step_type.h"

enum class SpriteLayer {
  Mask,
  Normal,
  Above,
  NUM_SPRITE_LAYERS // do not use
};

struct SpriteFrame {
  SDL_Rect srcRect;
  vec2i center;
  vec2i size;
};

struct Animation {
  bool looping = true;
  std::vector<int> frameIndices;
  int timerNum = 0;
};

enum class CharacterState {
  Still,
  Walking,
  Crouching,
  Running
};

enum class CharacterMedium {
  Normal,
  Ladder,
  Water
};

enum class BehaviourType {
  None,
  Wander,
  Path,
  Follow
};

enum class MirrorType {
  None,
  Vertical
};

struct Movement {
  vec2i pos;
  Direction dir;
  CharacterMedium medium;
};

struct PathfindingInstruction {
  Direction dir;
  vec2i endpoint;
};

class Sprite {
public:

  std::string alias;
  bool persistent = false;
  bool paused = false;

  // Transform
  vec2i loc { 0, 0 };
  SpriteLayer layer = SpriteLayer::Normal;
  bool collidable = false;
  bool solid = false;
  vec2i collisionOffset;
  vec2i collisionSize;
  std::string interactionScript;
  std::string walkthroughScript;
  std::string bumpPlayerScript;
  std::string enclosureZone;
  bool sliding = false;
  bool floating = false;

  // Animation (internals)
  bool isAnimated = false;
  std::string spritesheet;
  Direction dir = Direction::down;
  std::string animationName = "still";
  int animationId = 0;
  int animationFrame = 0;
  std::vector<SpriteFrame> frames;
  std::vector<Animation> animations;
  std::map<std::string, std::map<Direction, int>> nameDirToAnim;
  bool animFinished = false;
  bool hasShadow = false;
  int bobAmount = 0;
  bool bobbingDown = false;
  int animSlowdownProgress = 0;

  // Animation (controls)
  bool normallyHasShadow = false;
  bool animPaused = false;
  bool bobbing = false;
  int animSlowdown = 1; // Animation will only advance every X frames (so, 1 means it's disabled)
  double opacity = 1.0;
  bool shouldBeFadedIn = true;

  // Character
  bool orientable = false;
  int movementSpeed = 0; // 1 is slow (good for NPCs), 2 is Lucas's default walking speed
  std::vector<int> followers;
  int leaderId = -1;
  std::deque<Movement> trail;
  bool trailsAreHalved = false;
  CharacterState characterState = CharacterState::Still;
  CharacterMedium characterMedium = CharacterMedium::Normal;
  Direction movementDir = Direction::down;
  StepType stepType = StepType::none;
  int runningSfxChannel = -1;
  bool clipping = false;
  bool cantCrouch = false; // Use this to prevent running
  bool bobsWhenNormal = false; // If enabled, sets the animation bobbing flag whenever medium is Normal

  // Input
  bool controllable = false;
  bool player = false;

  // Behaviour
  BehaviourType behaviourType = BehaviourType::None;
  vec2i pathfindingDestination;
  bool cardinalDirectionsOnly = false;
  bool moonwalking = false;
  std::deque<PathfindingInstruction> path;
  int followSpriteId = -1;

  // Mirror
  MirrorType mirrorType = MirrorType::None;
  int mirroredSpriteId = -1;
  int mirrorAxis = 0;
};

#endif /* end of include guard: SPRITE_H_70503825 */