Crossfire Server, Trunk  1.75.0
anim.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
19 #include "global.h"
20 
21 #include <assert.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "assets.h"
28 #include "AssetsManager.h"
29 
44 void animate_object(object *op, int dir) {
45  int max_state; /* Max animation state object should be drawn in */
46  int base_state; /* starting index # to draw from */
47  uint16_t oldface = op->face->number;
48 
49  if (!op->animation || !NUM_ANIMATIONS(op)) {
50  StringBuffer *sb;
51  char *diff;
52 
53  LOG(llevError, "Object lacks animation.\n");
54  sb = stringbuffer_new();
55  object_dump(op, sb);
56  diff = stringbuffer_finish(sb);
57  LOG(llevError, "%s", diff);
58  free(diff);
59  return;
60  }
61 
62  if (op->head) {
63  dir = op->head->direction;
64 
65  if (NUM_ANIMATIONS(op) == NUM_ANIMATIONS(op->head))
66  op->state = op->head->state;
67  } else if (QUERY_FLAG(op, FLAG_IS_TURNABLE)) {
68  dir = op->direction;
69  }
70 
71  /* If object is turning, then max animation state is half through the
72  * animations. Otherwise, we can use all the animations.
73  */
74  max_state = NUM_ANIMATIONS(op)/NUM_FACINGS(op);
75  base_state = 0;
76  /* at least in the older aniamtions that used is_turning, the first half
77  * of the animations were left facing, the second half right facing.
78  * Note in old the is_turning, it was set so that the animation for a monster
79  * was always towards the enemy - now it is whatever direction the monster
80  * is facing.
81  */
82  if (NUM_FACINGS(op) == 2) {
83  if (dir < 5)
84  base_state = 0;
85  else
86  base_state = NUM_ANIMATIONS(op)/2;
87  } else if (NUM_FACINGS(op) == 4) {
88  if (dir == 0)
89  base_state = 0;
90  else
91  base_state = ((dir-1)/2)*(NUM_ANIMATIONS(op)/4);
92  } else if (NUM_FACINGS(op) == 8) {
93  if (dir == 0)
94  base_state = 0;
95  else
96  base_state = (dir-1)*(NUM_ANIMATIONS(op)/8);
97  } else if (QUERY_FLAG(op, FLAG_IS_TURNABLE)) {
98  base_state = (NUM_ANIMATIONS(op) / 9) * (dir);
99  max_state = NUM_ANIMATIONS(op) / 9;
100  }
101 
102  /* If beyond drawable states, reset */
103  if (op->state >= max_state) {
104  op->state = 0;
105  if (op->temp_animation) {
106  op->temp_animation = 0;
107  animate_object(op, dir);
108  return;
109  }
110  }
111  SET_ANIMATION(op, op->state+base_state);
112 
113  if (op->face == blank_face)
114  op->invisible = 1;
115 
116  /* This block covers monsters (eg, pixies) which are supposed to
117  * cycle from visible to invisible and back to being visible.
118  * as such, disable it for players, as then players would become
119  * visible.
120  */
121  else if (op->type != PLAYER && QUERY_FLAG((&op->arch->clone), FLAG_ALIVE)) {
122  if (op->face->number == 0) {
123  op->invisible = 1;
124  CLEAR_FLAG(op, FLAG_ALIVE);
125  } else if (op->temp_animation ? op->temp_animation->has_blank : op->animation->has_blank) {
126  op->invisible = 0;
127  SET_FLAG(op, FLAG_ALIVE);
128  }
129  }
130 
131  if (op->more)
132  animate_object(op->more, dir);
133 
134  /* object_update() will also recursively update all the pieces.
135  * as such, we call it last, and only call it for the head
136  * piece, and not for the other tail pieces.
137  */
138  if (!op->head && (oldface != op->face->number))
140 }
141 
150 void apply_anim_suffix(object *who, const char *suffix) {
151  const Animations *anim;
152  object *head, *orig;
153  char buf[MAX_BUF];
154 
155  assert(who);
156  assert(suffix);
157 
158  if (who->temp_animation)
159  /* don't overlap animation, let the current one finish. */
160  return;
161 
162  head = HEAD(who);
163  orig = head;
164  snprintf(buf, MAX_BUF, "%s_%s", (head->animation ? head->animation->name : ""), suffix);
165  anim = try_find_animation(buf);
166  if (anim) {
167  for (; head != NULL; head = head->more) {
168  head->temp_animation = anim;
169  head->temp_anim_speed = anim->num_animations / anim->facings;
170  head->last_anim = 0;
171  head->state = 0;
172  }
173  animate_object(orig, orig->facing);
174  }
175 }
176 
180 void dump_animations(void) {
181  fprintf(stderr, "id name faces\n");
182  getManager()->animations()->each([] (const auto anim) { fprintf(stderr, "%5d %50s %5d%s\n", anim->num, anim->name,
183  anim->num_animations, anim->has_blank ? " (with blank)" : ""); });
184 }
UP_OBJ_FACE
#define UP_OBJ_FACE
Only thing that changed was the face.
Definition: object.h:533
PLAYER
@ PLAYER
Definition: object.h:112
global.h
llevError
@ llevError
Error, serious thing.
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:58
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
AssetsManager.h
FLAG_IS_TURNABLE
#define FLAG_IS_TURNABLE
Object can change face with direction.
Definition: define.h:256
object::arch
struct archetype * arch
Pointer to archetype.
Definition: object.h:424
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Create a new string buffer.
Definition: stringbuffer.cpp:57
object::invisible
int16_t invisible
How much longer the object will be invis.
Definition: object.h:370
AssetsManager::animations
AllAnimations * animations()
Get animations.
Definition: AssetsManager.h:49
SET_ANIMATION
#define SET_ANIMATION(ob, newanim)
Definition: global.h:164
object::direction
int8_t direction
Means the object is moving that way.
Definition: object.h:344
blank_face
const Face * blank_face
Following can just as easily be pointers, but it is easier to keep them like this.
Definition: image.cpp:36
buf
StringBuffer * buf
Definition: readable.cpp:1565
getManager
AssetsManager * getManager()
Definition: assets.cpp:304
FLAG_ALIVE
#define FLAG_ALIVE
Object can fight (or be fought)
Definition: define.h:230
NUM_FACINGS
#define NUM_FACINGS(ob)
Definition: global.h:174
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Deallocate the string buffer instance and return the string.
Definition: stringbuffer.cpp:76
object_update
void object_update(object *op, int action)
object_update() updates the array which represents the map.
Definition: object.cpp:1434
object::temp_anim_speed
uint8_t temp_anim_speed
Ticks between temporary animation-frames.
Definition: object.h:432
Face::number
uint16_t number
This is the image unique identifier.
Definition: face.h:15
archetype::clone
object clone
An object from which to do object_copy()
Definition: object.h:487
object_dump
void object_dump(const object *op, StringBuffer *sb)
Dumps an object.
Definition: object.cpp:645
apply_anim_suffix
void apply_anim_suffix(object *who, const char *suffix)
Applies a compound animation to an object.
Definition: anim.cpp:150
HEAD
#define HEAD(op)
Returns the head part of an object.
Definition: object.h:607
object::face
const Face * face
Face with colors.
Definition: object.h:341
object::last_anim
uint8_t last_anim
Last sequence used to draw face.
Definition: object.h:430
object::type
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
Animations::facings
uint8_t facings
How many facings (1,2,4,8).
Definition: face.h:28
AssetsCollection::each
void each(std::function< void(T *)> op)
Apply a function to each asset.
Definition: AssetsCollection.h:158
object::facing
int8_t facing
Object is oriented/facing that way.
Definition: object.h:345
object::animation
const Animations * animation
Animation of this item, NULL if not animated.
Definition: object.h:428
Animations::num_animations
uint8_t num_animations
How many different faces to animate, size of the faces array.
Definition: face.h:27
MAX_BUF
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
object::head
object * head
Points to the main object of a large body.
Definition: object.h:304
try_find_animation
Animations * try_find_animation(const char *name)
Definition: assets.cpp:277
StringBuffer
A buffer that will be expanded as content is added to it.
Definition: stringbuffer.cpp:25
Animations::has_blank
bool has_blank
If this animation contains a blank face or not, used for invisibility.
Definition: face.h:31
Animations
This represents one animation.
Definition: face.h:25
animate_object
void animate_object(object *op, int dir)
Updates the face-variable of an object.
Definition: anim.cpp:44
assets.h
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
NUM_ANIMATIONS
#define NUM_ANIMATIONS(ob)
Definition: global.h:173
dump_animations
void dump_animations(void)
Dump all animations to stderr, for debugging purposes.
Definition: anim.cpp:180
object::state
uint8_t state
How the object was last drawn (animation)
Definition: object.h:359
object::more
object * more
Pointer to the rest of a large body of objects.
Definition: object.h:303
object::temp_animation
const Animations * temp_animation
A temporary animation.
Definition: object.h:431
Animations::name
sstring name
Name of the animation sequence.
Definition: face.h:26