Crossfire Server, Trunk
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;
125  } else if (op->temp_animation ? op->temp_animation->has_blank : op->animation->has_blank) {
126  op->invisible = 0;
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);
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
Definition: object.h:533
PLAYER
@ PLAYER
Definition: object.h:112
global.h
llevError
@ llevError
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
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
Definition: define.h:256
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.cpp:57
AssetsManager::animations
AllAnimations * animations()
Definition: AssetsManager.h:49
SET_ANIMATION
#define SET_ANIMATION(ob, newanim)
Definition: global.h:162
blank_face
const Face * blank_face
Definition: image.cpp:36
buf
StringBuffer * buf
Definition: readable.cpp:1565
getManager
AssetsManager * getManager()
Definition: assets.cpp:305
FLAG_ALIVE
#define FLAG_ALIVE
Definition: define.h:230
autojail.who
who
Definition: autojail.py:3
NUM_FACINGS
#define NUM_FACINGS(ob)
Definition: global.h:172
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.cpp:76
object_update
void object_update(object *op, int action)
Definition: object.cpp:1434
object::temp_anim_speed
uint8_t temp_anim_speed
Definition: object.h:432
object_dump
void object_dump(const object *op, StringBuffer *sb)
Definition: object.cpp:645
apply_anim_suffix
void apply_anim_suffix(object *who, const char *suffix)
Definition: anim.cpp:150
HEAD
#define HEAD(op)
Definition: object.h:607
object::last_anim
uint8_t last_anim
Definition: object.h:430
AssetsCollection::each
void each(std::function< void(T *)> op)
Definition: AssetsCollection.h:158
animate.anim
string anim
Definition: animate.py:20
object::facing
int8_t facing
Definition: object.h:345
object::animation
const Animations * animation
Definition: object.h:428
MAX_BUF
#define MAX_BUF
Definition: define.h:35
try_find_animation
Animations * try_find_animation(const char *name)
Definition: assets.cpp:278
StringBuffer
Definition: stringbuffer.cpp:25
give.op
op
Definition: give.py:33
Animations
Definition: face.h:25
animate_object
void animate_object(object *op, int dir)
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:171
dump_animations
void dump_animations(void)
Definition: anim.cpp:180
object::state
uint8_t state
Definition: object.h:359
object::more
object * more
Definition: object.h:303
object::temp_animation
const Animations * temp_animation
Definition: object.h:431
Animations::name
sstring name
Definition: face.h:26
castle_read.suffix
string suffix
Definition: castle_read.py:30