Crossfire Server, Trunk
anim.c
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 
43 void animate_object(object *op, int dir) {
44  int max_state; /* Max animation state object should be drawn in */
45  int base_state; /* starting index # to draw from */
46  uint16_t oldface = op->face->number;
47 
48  if (!op->animation || !NUM_ANIMATIONS(op)) {
49  StringBuffer *sb;
50  char *diff;
51 
52  LOG(llevError, "Object lacks animation.\n");
53  sb = stringbuffer_new();
54  object_dump(op, sb);
55  diff = stringbuffer_finish(sb);
56  LOG(llevError, "%s", diff);
57  free(diff);
58  return;
59  }
60 
61  if (op->head) {
62  dir = op->head->direction;
63 
64  if (NUM_ANIMATIONS(op) == NUM_ANIMATIONS(op->head))
65  op->state = op->head->state;
66  } else if (QUERY_FLAG(op, FLAG_IS_TURNABLE)) {
67  dir = op->direction;
68  }
69 
70  /* If object is turning, then max animation state is half through the
71  * animations. Otherwise, we can use all the animations.
72  */
73  max_state = NUM_ANIMATIONS(op)/NUM_FACINGS(op);
74  base_state = 0;
75  /* at least in the older aniamtions that used is_turning, the first half
76  * of the animations were left facing, the second half right facing.
77  * Note in old the is_turning, it was set so that the animation for a monster
78  * was always towards the enemy - now it is whatever direction the monster
79  * is facing.
80  */
81  if (NUM_FACINGS(op) == 2) {
82  if (dir < 5)
83  base_state = 0;
84  else
85  base_state = NUM_ANIMATIONS(op)/2;
86  } else if (NUM_FACINGS(op) == 4) {
87  if (dir == 0)
88  base_state = 0;
89  else
90  base_state = ((dir-1)/2)*(NUM_ANIMATIONS(op)/4);
91  } else if (NUM_FACINGS(op) == 8) {
92  if (dir == 0)
93  base_state = 0;
94  else
95  base_state = (dir-1)*(NUM_ANIMATIONS(op)/8);
96  } else if (QUERY_FLAG(op, FLAG_IS_TURNABLE)) {
97  base_state = (NUM_ANIMATIONS(op) / 9) * (dir);
98  max_state = NUM_ANIMATIONS(op) / 9;
99  }
100 
101  /* If beyond drawable states, reset */
102  if (op->state >= max_state) {
103  op->state = 0;
104  if (op->temp_animation) {
105  op->temp_animation = 0;
106  animate_object(op, dir);
107  return;
108  }
109  }
110  SET_ANIMATION(op, op->state+base_state);
111 
112  if (op->face == blank_face)
113  op->invisible = 1;
114 
115  /* This block covers monsters (eg, pixies) which are supposed to
116  * cycle from visible to invisible and back to being visible.
117  * as such, disable it for players, as then players would become
118  * visible.
119  */
120  else if (op->type != PLAYER && QUERY_FLAG((&op->arch->clone), FLAG_ALIVE)) {
121  if (op->face->number == 0) {
122  op->invisible = 1;
124  } else {
125  op->invisible = 0;
127  }
128  }
129 
130  if (op->more)
131  animate_object(op->more, dir);
132 
133  /* object_update() will also recursively update all the pieces.
134  * as such, we call it last, and only call it for the head
135  * piece, and not for the other tail pieces.
136  */
137  if (!op->head && (oldface != op->face->number))
139 }
140 
149 void apply_anim_suffix(object *who, const char *suffix) {
150  const Animations *anim;
151  object *head, *orig;
152  char buf[MAX_BUF];
153 
154  assert(who);
155  assert(suffix);
156 
157  if (who->temp_animation)
158  /* don't overlap animation, let the current one finish. */
159  return;
160 
161  head = HEAD(who);
162  orig = head;
163  snprintf(buf, MAX_BUF, "%s_%s", (head->animation ? head->animation->name : ""), suffix);
165  if (anim) {
166  for (; head != NULL; head = head->more) {
167  head->temp_animation = anim;
168  head->temp_anim_speed = anim->num_animations / anim->facings;
169  head->last_anim = 0;
170  head->state = 0;
171  }
172  animate_object(orig, orig->facing);
173  }
174 }
175 
176 static void do_anim(const Animations *anim) {
177  fprintf(stderr, "%5d %50s %5d\n", anim->num, anim->name, anim->num_animations);
178 }
179 
183 void dump_animations(void) {
184  fprintf(stderr, "id name faces\n");
186 }
UP_OBJ_FACE
#define UP_OBJ_FACE
Definition: object.h:520
PLAYER
@ PLAYER
Definition: object.h:107
global.h
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:57
llevError
@ llevError
Definition: logger.h:11
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
object_update
void object_update(object *op, int action)
Definition: object.c:1407
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
do_anim
static void do_anim(const Animations *anim)
Definition: anim.c:176
FLAG_IS_TURNABLE
#define FLAG_IS_TURNABLE
Definition: define.h:256
obj::last_anim
uint8_t last_anim
Definition: object.h:422
animations_for_each
void animations_for_each(anim_op op)
Definition: assets.cpp:298
blank_face
const Face * blank_face
Definition: image.c:35
SET_ANIMATION
#define SET_ANIMATION(ob, newanim)
Definition: global.h:160
FLAG_ALIVE
#define FLAG_ALIVE
Definition: define.h:230
animate_object
void animate_object(object *op, int dir)
Definition: anim.c:43
autojail.who
who
Definition: autojail.py:3
NUM_FACINGS
#define NUM_FACINGS(ob)
Definition: global.h:170
object_dump
void object_dump(const object *op, StringBuffer *sb)
Definition: object.c:638
HEAD
#define HEAD(op)
Definition: object.h:594
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:76
animate.anim
string anim
Definition: animate.py:20
obj::animation
const Animations * animation
Definition: object.h:420
MAX_BUF
#define MAX_BUF
Definition: define.h:35
try_find_animation
Animations * try_find_animation(const char *name)
Definition: assets.cpp:294
StringBuffer
Definition: stringbuffer.c:25
animations_struct::name
sstring name
Definition: face.h:26
animations_struct
Definition: face.h:25
obj::temp_animation
const Animations * temp_animation
Definition: object.h:423
obj::state
uint8_t state
Definition: object.h:352
obj::facing
int8_t facing
Definition: object.h:338
apply_anim_suffix
void apply_anim_suffix(object *who, const char *suffix)
Definition: anim.c:149
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
give.op
op
Definition: give.py:33
obj::temp_anim_speed
uint8_t temp_anim_speed
Definition: object.h:424
dump_animations
void dump_animations(void)
Definition: anim.c:183
assets.h
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
buf
StringBuffer * buf
Definition: readable.c:1606
NUM_ANIMATIONS
#define NUM_ANIMATIONS(ob)
Definition: global.h:169
obj::more
struct obj * more
Definition: object.h:296
castle_read.suffix
string suffix
Definition: castle_read.py:30