Crossfire Server, Branches 1.12  R18729
cfanim.c
Go to the documentation of this file.
1 /*****************************************************************************/
2 /* Crossfire Animator v2.0a */
3 /* Contacts: yann.chachkoff@myrealbox.com, tchize@myrealbox.com */
4 /*****************************************************************************/
5 /* That code is placed under the GNU General Public Licence (GPL) */
6 /* */
7 /* (C) 2001 David Delbecq for the original code version. */
8 /*****************************************************************************/
9 /* CrossFire, A Multiplayer game for X-windows */
10 /* */
11 /* Copyright (C) 2000 Mark Wedel */
12 /* Copyright (C) 1992 Frank Tore Johansen */
13 /* */
14 /* This program is free software; you can redistribute it and/or modify */
15 /* it under the terms of the GNU General Public License as published by */
16 /* the Free Software Foundation; either version 2 of the License, or */
17 /* (at your option) any later version. */
18 /* */
19 /* This program is distributed in the hope that it will be useful, */
20 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
21 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
22 /* GNU General Public License for more details. */
23 /* */
24 /* You should have received a copy of the GNU General Public License */
25 /* along with this program; if not, write to the Free Software */
26 /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
27 /* */
28 /*****************************************************************************/
29 
30 /* First let's include the header file needed */
31 
32 #include <assert.h>
33 #include <cfanim.h>
34 #include <stdarg.h>
35 
36 static CFanimation *first_animation = NULL;
38 static int get_boolean(const char *strg, int *bl);
39 
45 static int get_dir_from_name(const char *name) {
46  if (!strcmp(name, "north"))
47  return 1;
48  if (!strcmp(name, "north_east"))
49  return 2;
50  if (!strcmp(name, "east"))
51  return 3;
52  if (!strcmp(name, "south_east"))
53  return 4;
54  if (!strcmp(name, "south"))
55  return 5;
56  if (!strcmp(name, "south_west"))
57  return 6;
58  if (!strcmp(name, "west"))
59  return 7;
60  if (!strcmp(name, "north_west"))
61  return 8;
62  return -1;
63 }
64 
65 static long int initmovement(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
66  int dir;
67 
68  dir = get_dir_from_name(name);
69  move_entity->parameters = NULL;
70  return dir;
71 }
72 
73 static anim_move_result runmovement(struct CFanimation_struct *animation, long int id, void *parameters) {
74  object *op = animation->victim;
75  int dir = id;
76 
77  if (animation->verbose)
78  cf_log(llevDebug, "CFAnim: Moving in direction %ld\n", id);
79  if (op->type == PLAYER)
80  cf_player_move(op->contr, dir);
81  else
82  cf_object_move(op, dir, op);
83  return mr_finished;
84 }
85 
86 static long int initfire(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
87  int dir;
88 
89  dir = get_dir_from_name(&(name[5]));
90  move_entity->parameters = NULL;
91  return dir;
92 }
93 
95 static anim_move_result runfire(struct CFanimation_struct *animation, long int id, void *parameters) {
96  if (animation->verbose)
97  cf_log(llevDebug, "CFAnim: Firing in direction %ld\n", id);
98  return mr_finished;
99 }
100 
101 static long int initturn(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
102  int dir;
103 
104  dir = get_dir_from_name(&(name[5]));
105  move_entity->parameters = NULL;
106  return dir;
107 }
108 
109 static anim_move_result runturn(struct CFanimation_struct *animation, long int id, void *parameters) {
110  object *op = animation->victim;
111  int dir = id;
112  int face;
113 
114  if (animation->verbose)
115  cf_log(llevDebug, "CFAnim: Turning in direction %ld\n", id);
116  op->facing = dir;
118  return mr_finished;
119 }
120 
121 static long int initcamera(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
122  int dir;
123 
124  dir = get_dir_from_name(&(name[7]));
125  move_entity->parameters = NULL;
126  return dir;
127 }
128 
130 static anim_move_result runcamera(struct CFanimation_struct *animation, long int id, void *parameters) {
131  if (animation->verbose)
132  cf_log(llevDebug, "CFAnim: Moving the camera in direction %ld\n", id);
133  return mr_finished;
134  /*if (animation->victim->type == PLAYER)
135  hook_scroll_map(animation->victim, id);
136  else
137  printf("CFAnim: Not a player\n");
138  return 1;*/
139 }
140 
141 static long int initvisible(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
142  int result;
143 
144  if (get_boolean(parameters, &result))
145  return result;
146  cf_log(llevDebug, "CFAnim: Error in animation - possible values for 'invisible' are 'yes' and 'no'\n");
147  return -1;
148 }
149 
150 static anim_move_result runvisible(struct CFanimation_struct *animation, long int id, void *parameters) {
151  if (id == -1)
152  return mr_finished;
153  animation->invisible = id;
154  return mr_finished;
155 }
156 
157 static long int initwizard(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
158  int result;
159 
160  if (get_boolean(parameters, &result))
161  return result;
162  cf_log(llevDebug, "CFAnim: Error in animation - possible values for 'wizard' are 'yes' and 'no'\n");
163  return -1;
164 }
165 
166 static anim_move_result runwizard(struct CFanimation_struct *animation, long int id, void *parameters) {
167  if (id == -1)
168  return 1;
169  animation->wizard = id;
170  return mr_finished;
171 }
172 
173 static long int initsay(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
174  if (parameters)
175  move_entity->parameters = cf_strdup_local(parameters);
176  else
177  move_entity->parameters = NULL;
178  if (move_entity->parent->verbose)
179  cf_log(llevDebug, "CFAnim: init say: parameters: %s\n", parameters ? parameters : "null");
180  return 1;
181 }
182 
183 static anim_move_result runsay(struct CFanimation_struct *animation, long int id, void *parameters) {
184  if (parameters) {
185  cf_object_say(animation->victim, parameters);
186  free(parameters);
187  } else
188  cf_log(llevDebug, "CFAnim: Error in animation: nothing to say with say function\n");
189  return mr_finished;
190 }
191 
192 static long int initapply(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
193  return 1;
194 }
195 
196 static anim_move_result runapply(struct CFanimation_struct *animation, long int id, void *parameters) {
197  object *current_container;
198 
199  if (animation->victim->type != PLAYER)
200  return mr_finished;
201  current_container = animation->victim->container;
202  animation->victim->container = NULL;
203  cf_object_apply_below(animation->victim);
204  animation->victim->container = current_container;
205  return mr_finished;
206 }
207 
208 static long int initapplyobject(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
209  move_entity->parameters = parameters ? cf_add_string(parameters) : NULL;
210  return 1;
211 }
212 
213 static anim_move_result runapplyobject(struct CFanimation_struct *animation, long int id, void *parameters) {
214  object *current;
215  int aflag;
216 
217  if (!parameters)
218  return mr_finished;
219  for (current = animation->victim->below; current; current = current->below)
220  if (current->name == parameters)
221  break;
222  if (!current)
223  for (current = animation->victim->inv; current; current = current->below)
224  if (current->name == parameters)
225  break;
226  if (!current) {
227  cf_free_string(parameters);
228  return mr_finished;
229  }
230  aflag = AP_APPLY;
231  cf_object_apply(animation->victim, current, aflag);
232  cf_free_string(parameters);
233  return mr_finished;
234 }
235 
236 static long int initdropobject(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
237  move_entity->parameters = parameters ? cf_strdup_local(parameters) : NULL;
238  return 1;
239 }
240 
241 static anim_move_result rundropobject(struct CFanimation_struct *animation, long int id, void *parameters) {
242  if (!parameters)
243  return mr_finished;
244  cf_object_drop(animation->victim, parameters);
245  cf_free_string(parameters);
246  return mr_finished;
247 }
248 
249 static long int initpickup(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
250  return 1;
251 }
252 
253 static anim_move_result runpickup(struct CFanimation_struct *animation, long int id, void *parameters) {
254  object *current;
255 
256  current = animation->victim->below;
257  if (!current)
258  return mr_finished;
259  cf_object_pickup(animation->victim, current);
260  return mr_finished;
261 }
262 
263 static long int initpickupobject(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
264  move_entity->parameters = parameters ? cf_add_string(parameters) : NULL;
265  return 1;
266 }
267 
268 static anim_move_result runpickupobject(struct CFanimation_struct *animation, long int id, void *parameters) {
269  object *current;
270 
271  if (!parameters)
272  return mr_finished;
273  for (current = animation->victim->below; current; current = current->below)
274  if (current->name == parameters)
275  break;
276  if (current)
277  cf_object_pickup(animation->victim, current);
278  cf_free_string(parameters);
279  return mr_finished;
280 }
281 
282 static long int initghosted(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
283  int result;
284 
285  if (get_boolean(parameters, &result))
286  return result;
287  cf_log(llevDebug, "CFAnim: Error in animation: possible values for 'ghosted' are 'yes' and 'no'\n");
288  return -1;
289 }
290 
291 static anim_move_result runghosted(struct CFanimation_struct *animation, long int id, void *parameters) {
292  object *corpse;
293 
294  if ((id && animation->ghosted)
295  || (!id && !animation->ghosted))
296  runghosted(animation, !id, parameters);
297  if (id) { /*Create a ghost/corpse pair*/
298  corpse = cf_object_clone(animation->victim, 1);
299  corpse->x = animation->victim->x;
300  corpse->y = animation->victim->y;
301  corpse->type = 0;
302  CLEAR_FLAG(corpse, FLAG_WIZ);
303  corpse->contr = NULL;
304  cf_map_insert_object_there(corpse, animation->victim->map, NULL, 0);
305  animation->wizard = 1;
306  animation->invisible = 1;
307  animation->corpse = corpse;
308  } else { /*Remove a corpse, make current player visible*/
309  animation->wizard = 0;
310  animation->invisible = 0;
311  cf_object_remove(animation->corpse);
312  cf_object_free(animation->corpse);
313  animation->corpse = NULL;
314  animation->victim->invisible = 0;
315  cf_player_move(animation->victim->contr, 0);
316  }
317  animation->ghosted = id;
318  return mr_finished;
319 }
320 
321 typedef struct {
322  char *mapname;
323  int mapx;
324  int mapy;
326 
327 static long int initteleport(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
328  char *mapname;
329  int mapx;
330  int mapy;
332 
333  move_entity->parameters = NULL;
334  cf_log(llevDebug, ".(%s)\n", parameters);
335  if (!parameters) {
336  cf_log(llevDebug, "CFAnim: Error - no parameters for teleport\n");
337  return 0;
338  }
339  mapname = strstr(parameters, " ");
340  cf_log(llevDebug, ".(%s)\n", parameters);
341  if (!mapname)
342  return 0;
343  *mapname = '\0';
344  mapx = atoi(parameters);
345  mapname++;
346  parameters = mapname;
347  if (!parameters) {
348  cf_log(llevDebug, "CFAnim: Error - not enough parameters for teleport\n");
349  return 0;
350  }
351  cf_log(llevDebug, ".(%s)\n", parameters);
352  mapname = strstr(parameters, " ");
353  cf_log(llevDebug, ".\n");
354  if (!mapname)
355  return 0;
356  *mapname = '\0';
357  mapy = atoi(parameters);
358  mapname++;
359  if (mapname[0] == '\0')
360  return 0;
361  teleport = (teleport_params *)malloc(sizeof(teleport_params));
362  teleport->mapname = cf_strdup_local(mapname);
363  teleport->mapx = mapx;
364  teleport->mapy = mapy;
365  move_entity->parameters = teleport;
366  return 1;
367 }
368 
369 static anim_move_result runteleport(struct CFanimation_struct *animation, long int id, void *parameters) {
370  teleport_params *teleport = (teleport_params *)parameters;
371 
372  if (!parameters)
373  return mr_finished;
374  cf_object_teleport(animation->victim, cf_map_get_map(teleport->mapname, 0), teleport->mapx, teleport->mapy);
375  free(parameters);
376  return mr_finished;
377 }
378 
379 static long int initnotice(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
380  move_entity->parameters = parameters ? cf_strdup_local(parameters) : NULL;
381  return 1;
382 }
383 static anim_move_result runnotice(struct CFanimation_struct *animation, long int id, void *parameters) {
384  int val;
385 
386  val = NDI_NAVY|NDI_UNIQUE;
387 
388  cf_player_message(animation->victim, parameters, val);
389  return mr_finished;
390 }
391 
392 static long int initstop(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
393  return 1;
394 }
395 
397 static anim_move_result runstop(struct CFanimation_struct *animation, long int id, void *parameters) {
398  if (animation->verbose)
399  cf_log(llevDebug, "CFAnim: stop encountered\n");
400  return mr_finished;
401 }
402 
404 typedef struct {
405  int x, y;
406 } param_moveto;
407 
408 static long int initmoveto(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
409  param_moveto *moveto;
410  int x, y;
411 
412  if (sscanf(parameters, "%d %d", &x, &y) != 2)
413  return 0;
414 
415  moveto = (param_moveto *)calloc(1, sizeof(param_moveto));
416  moveto->x = x;
417  moveto->y = y;
418  move_entity->parameters = moveto;
419 
420  return 1;
421 }
422 
423 static anim_move_result runmoveto(struct CFanimation_struct *animation, long int id, void *parameters) {
424  int move;
425  param_moveto *dest = (param_moveto *)parameters;
426 
427  if (!dest)
428  return mr_finished;
429 
430  move = cf_object_move_to(animation->victim, dest->x, dest->y);
431 
432  if (animation->victim->x == dest->x && animation->victim->y == dest->y) {
433  free(parameters);
434  return mr_finished;
435  }
436 
437  if (move == 1)
438  return mr_again;
439 
440  return mr_finished;
441 }
442 
443 static long int initmessage(const char *name, char *parameters, struct CFmovement_struct *move_entity) {
444  if (parameters)
445  move_entity->parameters = strdup(parameters);
446  else
447  move_entity->parameters = NULL;
448  return 1;
449 }
450 
451 static anim_move_result runmessage(struct CFanimation_struct *animation, long int id, void *parameters) {
452  if (parameters && animation->victim->map) {
453  cf_map_message(animation->victim->map, (const char *)parameters, NDI_UNIQUE|NDI_GREEN);
454  free(parameters);
455  }
456 
457  return mr_finished;
458 }
459 
462  { "north", initmovement, runmovement },
463  { "north_east", initmovement, runmovement },
464  { "east", initmovement, runmovement },
465  { "south_east", initmovement, runmovement },
466  { "south", initmovement, runmovement },
467  { "south_west", initmovement, runmovement },
468  { "west", initmovement, runmovement },
469  { "north_west", initmovement, runmovement },
470  { "fire_north", initfire, runfire },
471  { "fire_north_east", initfire, runfire },
472  { "fire_east", initfire, runfire },
473  { "fire_south_east", initfire, runfire },
474  { "fire_south", initfire, runfire },
475  { "fire_south_west", initfire, runfire },
476  { "fire_west", initfire, runfire },
477  { "fire_north_west", initfire, runfire },
478  { "turn_north", initturn, runturn },
479  { "turn_north_east", initturn, runturn },
480  { "turn_east", initturn, runturn },
481  { "turn_south_east", initturn, runturn },
482  { "turn_south", initturn, runturn },
483  { "turn_south_west", initturn, runturn },
484  { "turn_west", initturn, runturn },
485  { "turn_north_west", initturn, runturn },
486  { "camera_north", initcamera, runcamera },
487  { "camera_north_east", initcamera, runcamera },
488  { "camera_east", initcamera, runcamera },
489  { "camera_south_east", initcamera, runcamera },
490  { "camera_south", initcamera, runcamera },
491  { "camera_south_west", initcamera, runcamera },
492  { "camera_west", initcamera, runcamera },
493  { "camera_north_west", initcamera, runcamera },
494  { "invisible", initvisible, runvisible },
495  { "wizard", initwizard, runwizard },
496  { "say", initsay, runsay },
497  { "apply", initapply, runapply },
498  { "apply_object", initapplyobject, runapplyobject },
499  { "drop_object", initdropobject, rundropobject },
500  { "pickup", initpickup, runpickup },
501  { "pickup_object", initpickupobject, runpickupobject },
502  { "ghosted", initghosted, runghosted },
503  { "teleport", initteleport, runteleport },
504  { "notice", initnotice, runnotice },
505  { "stop", initstop, runstop },
506  { "moveto", initmoveto, runmoveto },
507  { "message", initmessage, runmessage }
508 };
509 
511 
512 static int ordered_commands = 0;
513 
514 static int compareAnims(const void *a, const void *b) {
515  return strcmp(((const CFanimationHook *)a)->name, ((const CFanimationHook *)b)->name);
516 }
517 
518 static void prepare_commands(void) {
519  qsort(animationbox, animationcount, sizeof(CFanimationHook), compareAnims);
520  ordered_commands = 1;
521 }
522 
523 static CFanimationHook *get_command(char *command) {
524  CFanimationHook dummy;
525 
526  dummy.name = command;
527  if (!ordered_commands)
529  return (CFanimationHook *)bsearch(&dummy, animationbox, animationcount, sizeof(CFanimationHook), compareAnims);
530 }
531 
540 static CFmovement *parse_animation_block(char *buffer, size_t buffer_size, FILE *fichier, CFanimation *parent) {
541  CFmovement *first = NULL;
542  CFmovement *current = NULL;
543  CFmovement *next;
544  char *time;
545  char *name;
546  char *parameters;
547  int tick;
548  CFanimationHook *animationhook;
549 
550  if (parent->verbose)
551  cf_log(llevDebug, "CFAnim: In parse block for %s\n", buffer);
552  while (fgets(buffer, buffer_size, fichier)) {
553  if (buffer[0] == '[')
554  break;
555  if (buffer[0] == '#')
556  continue;
557  buffer[strlen(buffer)-strlen("\n")] = '\0';
558  while (buffer[strlen(buffer)-1] == ' ')
559  buffer[strlen(buffer)-1] = '\0';
560  if (strlen(buffer) <= 0)
561  continue;
562  time = buffer;
563 
564  name = strstr(buffer, " ");
565  if (!name)
566  continue;
567  *name = '\0';
568  name++;
569  while (*name == ' ')
570  name++;
571 
572  tick = atoi(time);
573  if (tick < 0)
574  continue;
575 
576  parameters = strstr(name, " ");
577  if (parameters) { /*Parameters may be nul*/
578  *parameters = '\0';
579  parameters++;
580  while (*parameters == ' ')
581  parameters++;
582  if (*parameters == '\0')
583  parameters = NULL;
584  }
585  animationhook = get_command(name);
586  if (parent->verbose) {
587  if (!animationhook)
588  cf_log(llevDebug, "CFAnim: %s - Unknown animation command\n", name);
589  else
590  cf_log(llevDebug, "CFAnim: Parsed %s -> %p\n", name, animationhook);
591  }
592  if (!animationhook) {
593  if (parent->errors_allowed)
594  continue;
595  else
596  break;
597  }
598  next = (CFmovement *)malloc(sizeof(CFmovement));
599  if (!next)
600  continue;
601  next->parent = parent;
602  next->tick = tick;
603  next->next = NULL;
604  if (animationhook->funcinit)
605  next->id = animationhook->funcinit(name, parameters, next);
606  next->func = animationhook->funcrun;
607  if (current)
608  current->next = next;
609  else
610  first = next;
611  current = next;
612  }
613  return first;
614 }
615 
626 static int equality_split(char *buffer, char **variable, char **value) {
627  if (!strcmp(&buffer[strlen(buffer)-strlen("\n")], "\n"))
628  buffer[strlen(buffer)-strlen("\n")] = '\0';
629  *value = strstr(buffer, "=");
630  if (!*value)
631  return 0;
632  **value = '\0';
633  *variable = buffer;
634  (*value)++;
635  while ((strlen(*variable) > 0) && ((*variable)[strlen(*variable)-1] == ' '))
636  (*variable)[strlen(*variable)-1] = '\0';
637  while ((strlen(*value) > 0) && ((*value)[strlen(*value)-1] == ' '))
638  (*value)[strlen(*value)-1] = '\0';
639  while (**value == ' ')
640  (*value)++;
641  if ((**variable == '\0') || (**value == '\0'))
642  return 0;
643  return 1;
644 }
645 
657 static int get_boolean(const char *strg, int *bl) {
658  if (!strncmp(strg, "y", 1))
659  *bl = 1;
660  else if (!strncmp(strg, "n", 1))
661  *bl = 0;
662  else if (!strncmp(strg, "Y", 1))
663  *bl = 1;
664  else if (!strncmp(strg, "N", 1))
665  *bl = 0;
666  else if (!strncmp(strg, "1", 1))
667  *bl = 1;
668  else if (!strncmp(strg, "0", 1))
669  *bl = 0;
670  else
671  return 0;
672  return 1;
673 }
674 
680 static int is_animated_player(object *pl) {
681  CFanimation *current;
682 
683  for (current = first_animation; current; current++)
684  if ((current->victim == pl) && (current->paralyze)) {
685  if (current->verbose)
686  cf_log(llevDebug, "CFAnim: Getting a command for a paralyzed player %s.\n", pl->name);
687  return 1;
688  }
689  return 0;
690 }
691 
697  CFanimation *new;
698  CFanimation *current;
699 
700  new = (CFanimation *)malloc(sizeof(CFanimation));
701  if (!new)
702  return NULL;
703  new->name = NULL;
704  new->victim = NULL;
705  new->nextmovement = NULL;
706  new->nextanimation = NULL;
707  for (current = first_animation; (current && current->nextanimation); current = current->nextanimation)
708  ;
709  if (!current)
710  first_animation = new;
711  else
712  current->nextanimation = new;
713  return new;
714 }
715 
716 static object *find_by_name(object *origin, const char *name) {
717  int x, y, w, h;
718  mapstruct *map;
719  const char *sname;
720  object *ob;
721 
722  sname = cf_find_string(name);
723  if (!sname)
724  return NULL;
725 
726  while (origin && !origin->map)
727  origin = origin->env;
728 
729  if (!origin || !origin->map)
730  return NULL;
731 
732  map = origin->map;
733 
734  w = cf_map_get_width(map);
735  h = cf_map_get_height(map);
736 
737  for (x = 0; x < w; x++) {
738  for (y = 0; y < h; y++) {
739  for (ob = GET_MAP_OB(map, x, y); ob; ob = ob->above) {
740  if (/*cf_object_get_sstring_property(ob, CFAPI_OBJECT_PROP_NAME)*/ob->name == sname)
741  return ob;
742  }
743  }
744  }
745 
746  return NULL;
747 }
748 
760 static int start_animation(object *who, object *activator, object *event, const char *file, const char *message) {
761  FILE *fichier;
762  char *name = NULL;
763  int victimtype = 0;
764  object *victim = NULL;
765  int unique = 0;
766  int always_delete = 0;
767  int parallel = 0;
768  int paralyzed = 1;
769  int invisible = 0;
770  int wizard = 0;
771  enum time_enum timetype;
772  int errors_allowed = 0;
773  int verbose = 0;
774  const char *animationitem;
775  char buffer[HUGE_BUF];
776  char *variable;
777  char *value;
778  int errors_found = 0;
779  CFanimation *current_anim;
780 
781  fichier = fopen(file, "r");
782  if (fichier == NULL) {
783  cf_log(llevDebug, "CFAnim: Unable to open %s\n", file);
784  return 0;
785  }
786  while (fgets(buffer, HUGE_BUF, fichier)) {
787  if (buffer[0] == '[')
788  break;
789  if (buffer[0] == '#')
790  continue;
791  if (!strcmp(buffer, "\n"))
792  continue;
793  errors_found = 1;
794  cf_log(llevDebug, "CFAnim: '%s' has an invalid syntax.\n", buffer);
795  }
796  if (feof(fichier))
797  return 0;
798  if (strncmp(buffer, "[Config]", 8)) {
799  cf_log(llevDebug, "CFAnim: Fatal error in %s: [Config] must be the first group defined.\n", file);
800  return 0;
801  }
802  while (fgets(buffer, HUGE_BUF, fichier)) {
803  if (buffer[0] == '[')
804  break;
805  if (buffer[0] == '#')
806  continue;
807  if (!strcmp(buffer, "\n"))
808  continue;
809  if (!equality_split(buffer, &variable, &value))
810  errors_found = 1;
811  else {
812  if (!strcmp(variable, "name")) {
813  if (*value == '"')
814  value++;
815  if (value[strlen(value)-1] == '"')
816  value[strlen(value)-1] = '\0';
817  name = cf_strdup_local(value);
818  } else if (!strcmp(variable, "victimtype")) {
819  if (!strcmp(value, "player"))
820  victimtype = 0;
821  else if (!strcmp(value, "object"))
822  victimtype = 1;
823  else if (!strcmp(value, "any"))
824  victimtype = 2;
825  else if (!strcmp(value, "byname"))
826  victimtype = 3;
827  else
828  errors_found = 1;
829  } else if (!strcmp(variable, "victim")) {
830  cf_log(llevDebug, "CFAnim: Setting victim to %s\n", value);
831  if (!strcmp(value, "who"))
832  victim = who;
833  else if (!strcmp(value, "activator"))
834  victim = activator;
835  else if (!strcmp(value, "who_owner"))
836  if (!who) {
837  errors_found = 1;
838  cf_log(llevDebug, "CFAnim: Warning: object \"who\" doesn't exist and you're victimized it's owner\n");
839  } else
840  victim = who->env;
841  else if (!strcmp(value, "activator_owner"))
842  if (!activator) {
843  errors_found = 1;
844  cf_log(llevDebug, "CFAnim: Warning: object \"activator\" doesn't exist and you're victimized it's owner\n");
845  }
846  else
847  victim = activator->env;
848  else if (victimtype == 3) {
849  victim = find_by_name(who, value);
850  } else
851  errors_found = 1;
852  } else if (!strcmp(variable, "unique")) {
853  if (!get_boolean(value, &unique))
854  errors_found = 1;
855  } else if (!strcmp(variable, "always_delete")) {
856  if (!get_boolean(value, &always_delete))
857  errors_found = 1;
858  } else if (!strcmp(variable, "parallel")) {
859  if (!get_boolean(value, &parallel))
860  errors_found = 1;
861  } else if (!strcmp(variable, "paralyzed")) {
862  if (!get_boolean(value, &paralyzed))
863  errors_found = 1;
864  } else if (!strcmp(variable, "invisible")) {
865  if (!get_boolean(value, &invisible))
866  errors_found = 1;
867  } else if (!strcmp(variable, "wizard")) {
868  if (!get_boolean(value, &wizard))
869  errors_found = 1;
870  } else if (!strcmp(variable, "errors_allowed")) {
871  if (!get_boolean(value, &errors_allowed))
872  errors_found = 1;
873  } else if (!strcmp(variable, "verbose")) {
874  if (!get_boolean(value, &verbose))
875  errors_found = 1;
876  } else if (!strcmp(variable, "time_representation")) {
877  if (!strcmp(value, "second"))
878  timetype = time_second;
879  else if (!strcmp(value, "tick"))
880  timetype = time_tick;
881  else
882  errors_found = 1;
883  } else if (!strcmp(variable, "animation")) {
884  animationitem = cf_add_string(value);
885  } else
886  errors_found = 1;
887  }
888  }
889 
890  if (message && message[0] != '\0') {
891  cf_free_string(animationitem);
892  animationitem = cf_add_string(message);
893  }
894 
895  if (buffer[0] == '\0') {
896  if (animationitem)
897  cf_free_string(animationitem);
898  cf_log(llevDebug, "CFAnim: Errors occurred during the parsing of %s\n", file);
899  return 0;
900  }
901  if (!victim) {
902  if (animationitem)
903  cf_free_string(animationitem);
904  cf_log(llevDebug, "CFAnim: Fatal error - victim is NULL");
905  return 0;
906  }
907  if (!(current_anim = create_animation())) {
908  if (animationitem)
909  cf_free_string(animationitem);
910  cf_log(llevDebug, "CFAnim: Fatal error - Not enough memory.\n");
911  return 0;
912  }
913  if (always_delete) {
914  /*if (verbose) printf("CFAnim: Freeing event nr. %d for %s.\n", current_event, who->name);*/
915  cf_object_remove(event);
916  }
917  if (((victim->type == PLAYER) && (victimtype == 1))
918  || ((victim->type != PLAYER) && (victimtype == 0))
919  || (errors_found && !errors_allowed)) {
920  if (verbose)
921  cf_log(llevDebug, "CFAnim: No correct victim found or errors found, aborting.\n");
922  if (animationitem)
923  cf_free_string(animationitem);
924  return 0;
925  }
926  if (unique && !always_delete) {
927  /*if (verbose) printf("CFAnim: Freeing event nr. %d for %s.\n", current_event, who->name);*/
928  cf_object_remove(event);
929  }
930  current_anim->name = name;
931  current_anim->victim = victim;
932  current_anim->paralyze = paralyzed;
933  current_anim->invisible = invisible;
934  current_anim->wizard = wizard;
935  current_anim->unique = unique;
936  current_anim->ghosted = 0;
937  current_anim->corpse = NULL;
938  current_anim->time_representation = timetype;
939  current_anim->verbose = verbose;
940  current_anim->tick_left = 0;
941  current_anim->errors_allowed = errors_allowed;
942 
943  while (buffer[0] == '[') {
944  while (strncmp(&buffer[1], animationitem, strlen(animationitem))) {
945  while ((value = fgets(buffer, HUGE_BUF, fichier)) != NULL)
946  if (buffer[0] == '[')
947  break;
948  if (value == NULL) {
949  cf_log(llevDebug, "CFAnim: no matching animation %s in file.\n", animationitem);
950  cf_free_string(animationitem);
951  return 0;
952  }
953  }
954  current_anim->nextmovement = parse_animation_block(buffer, HUGE_BUF, fichier, current_anim);
955  if (current_anim->nextmovement)
956  break;
957  }
958  fclose(fichier);
959  return 1;
960 }
961 
967 static void animate_one(CFanimation *animation, long int milliseconds) {
968  CFmovement *current;
969  int mult = 1;
970  anim_move_result result;
971 
972  if (animation->time_representation == time_second) {
973  animation->tick_left += milliseconds;
974  mult = 1000;
975  }
976  else
977  animation->tick_left++;
978 
979  if (animation->verbose)
980  cf_log(llevDebug, "CFAnim: Ticking %s for %s. Tickleft is %ld\n", animation->name, animation->victim->name, animation->tick_left);
981  if (animation->invisible)
982  animation->victim->invisible = 10;
983  if (animation->wizard && animation->victim->type == PLAYER) {
984  /* setting FLAG_WIZ *on non player leads to issues, as many functions expect contr to not be NULL in this case. */
985  if (animation->verbose)
986  cf_log(llevDebug, "CFAnim: Setting wizard flags\n");
987  cf_object_set_flag(animation->victim, FLAG_WIZPASS, 1);
988  cf_object_set_flag(animation->victim, FLAG_WIZCAST, 1);
989  cf_object_set_flag(animation->victim, FLAG_WIZ, 1);
990  if (animation->verbose)
991  cf_log(llevDebug, "CFAnim: Setting wizard flags done\n");
992 
993  }
994  if (animation->paralyze)
995  animation->victim->speed_left = -99999;
996 
998 
999  if (animation->nextmovement)
1000  while (animation->tick_left > animation->nextmovement->tick*mult) {
1001  animation->tick_left -= animation->nextmovement->tick*mult;
1002  result = animation->nextmovement->func(animation, animation->nextmovement->id, animation->nextmovement->parameters);
1003  if (result == mr_again)
1004  continue;
1005 
1006  current = animation->nextmovement;
1007  animation->nextmovement = animation->nextmovement->next;
1008  free(current);
1009  if (!animation->nextmovement)
1010  break;
1011  }
1012  cf_object_set_flag(animation->victim, FLAG_WIZPASS, 0);
1013  cf_object_set_flag(animation->victim, FLAG_WIZCAST, 0);
1014  cf_object_set_flag(animation->victim, FLAG_WIZ, 0);
1015 }
1016 
1020 static void animate(void) {
1021  CFanimation *current;
1022  CFanimation *next;
1023  CFanimation *previous_anim = NULL;
1024  struct timeval now;
1025  static struct timeval yesterday;
1026  static int already_passed = 0;
1027  long int delta_milli;
1028 
1029  (void)GETTIMEOFDAY(&now);
1030  if (!already_passed) {
1031  already_passed = 1;
1032  memcpy(&yesterday, &now, sizeof(struct timeval));
1033  return;
1034  }
1035  delta_milli = (now.tv_sec-yesterday.tv_sec)*1000+(now.tv_usec/1000-yesterday.tv_usec/1000);
1036  /*printf("Working for %ld milli seconds\n", delta_milli);*/
1037  memcpy(&yesterday, &now, sizeof(struct timeval));
1038  for (current = first_animation; current; current = current->nextanimation)
1039  animate_one(current, delta_milli);
1040  current = first_animation;
1041  while (current) {
1042  if (!current->nextmovement) {
1043  if (current->paralyze)
1044  current->victim->speed_left = current->victim->speed;
1045  next = current->nextanimation;
1046  if (first_animation == current)
1047  first_animation = next;
1048  else {
1049  previous_anim->nextanimation = next;
1050  }
1051  if (current->name)
1052  free(current->name);
1053  free(current);
1054  current = next;
1055  } else {
1056  previous_anim = current;
1057  current = current->nextanimation;
1058  }
1059  }
1060 }
1061 
1068 CF_PLUGIN int initPlugin(const char *iversion, f_plug_api gethooksptr) {
1069  cf_init_plugin(gethooksptr);
1070  cf_log(llevDebug, "CFAnim 2.0a init\n");
1071 
1072  /* Place your initialization code here */
1073  return 0;
1074 }
1075 
1076 CF_PLUGIN void *getPluginProperty(int *type, ...) {
1077  va_list args;
1078  const char *propname;
1079  char *buf;
1080  int size;
1081 
1082  va_start(args, type);
1083  propname = va_arg(args, const char *);
1084 
1085  if (!strcmp(propname, "Identification")) {
1086  buf = va_arg(args, char *);
1087  size = va_arg(args, int);
1088  va_end(args);
1089  snprintf(buf, size, PLUGIN_NAME);
1090  return NULL;
1091  } else if (!strcmp(propname, "FullName")) {
1092  buf = va_arg(args, char *);
1093  size = va_arg(args, int);
1094  va_end(args);
1095  snprintf(buf, size, PLUGIN_VERSION);
1096  return NULL;
1097  }
1098  va_end(args);
1099  return NULL;
1100 }
1101 
1103  return -1;
1104 }
1105 
1107  cf_log(llevDebug, "CFAnim 2.0a post init\n");
1108  /* Pick the global events you want to monitor from this plugin */
1110  return 0;
1111 }
1112 
1113 CF_PLUGIN void *cfanim_globalEventListener(int *type, ...) {
1114  va_list args;
1115  static int rv = 0;
1116  int event_code;
1117 
1118  va_start(args, type);
1119  event_code = va_arg(args, int);
1120  assert(event_code == EVENT_CLOCK);
1121 
1122  animate();
1123 
1124  va_end(args);
1125 
1126  return &rv;
1127 }
1128 
1129 CF_PLUGIN void *eventListener(int *type, ...) {
1130  static int rv = 0;
1131  va_list args;
1132  char *buf, message[MAX_BUF], script[MAX_BUF];
1133  object *who, *activator, *third, *event;
1134 
1135  va_start(args, type);
1136 
1137  who = va_arg(args, object *);
1138  activator = va_arg(args, object *);
1139  third = va_arg(args, object *);
1140  buf = va_arg(args, char *);
1141 
1142  if (buf != NULL)
1143  strcpy(message, buf);
1144  else
1145  message[0] = '\0';
1146 
1147  va_arg(args, int); /* 'fix', ignored */
1148  event = va_arg(args, object *);
1149 
1151  cf_get_maps_directory(event->slaying, script, sizeof(script));
1152  va_end(args);
1153 
1154  /* Put your plugin action(s) here */
1155  if (activator != NULL) {
1156  cf_log(llevDebug, "CFAnim: %s called animator script %s\n", activator->name, script);
1157  } else if (who != NULL) {
1158  activator = who;
1159  cf_log(llevDebug, "CFAnim: %s called animator script %s\n", who->name, script);
1160  }
1161 
1162  rv = start_animation(who, activator, event, script, message);
1163 
1164  return &rv;
1165 }
1166 
1168  cf_log(llevDebug, "CFAnim 2.0a closing\n");
1169  return 0;
1170 }
static long int initteleport(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:327
static int get_dir_from_name(const char *name)
Definition: cfanim.c:45
void * parameters
Definition: cfanim.h:64
Definition: player.h:146
CF_PLUGIN void * cfanim_globalEventListener(int *type,...)
Definition: cfanim.c:1113
#define CFAPI_OBJECT_PROP_ANIMATION
Definition: plugin.h:264
CF_PLUGIN int initPlugin(const char *iversion, f_plug_api gethooksptr)
Definition: cfanim.c:1068
void cf_map_message(mapstruct *m, const char *msg, int color)
int teleport(object *teleporter, uint8 tele_type, object *user)
Definition: move.c:244
static CFmovement * parse_animation_block(char *buffer, size_t buffer_size, FILE *fichier, CFanimation *parent)
Definition: cfanim.c:540
static long int initnotice(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:379
static long int initmovement(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:65
CFAnimInitFunc funcinit
Definition: cfanim.h:91
void cf_free_string(sstring str)
static int start_animation(object *who, object *activator, object *event, const char *file, const char *message)
Definition: cfanim.c:760
CF_PLUGIN anim_move_result cfanim_runPluginCommand(object *op, char *params)
Definition: cfanim.c:1102
static int get_boolean(const char *strg, int *bl)
Definition: cfanim.c:657
static object * find_by_name(object *origin, const char *name)
Definition: cfanim.c:716
long int id
Definition: cfanim.h:65
CF_PLUGIN int postInitPlugin(void)
Definition: cfanim.c:1106
void cf_object_set_flag(object *ob, int flag, int value)
static long int initapply(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:192
struct obj * container
Definition: object.h:149
static long int initfire(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:86
CFAnimRunFunc func
Definition: cfanim.h:63
static void animate(void)
Definition: cfanim.c:1020
static long int initmoveto(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:408
#define HUGE_BUF
Definition: define.h:83
static void animate_one(CFanimation *animation, long int milliseconds)
Definition: cfanim.c:967
static long int initturn(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:101
sint16 invisible
Definition: object.h:211
const char * slaying
Definition: object.h:172
void *(* f_plug_api)(int *type,...)
Definition: plugin.h:121
int cf_map_get_height(mapstruct *map)
CFAnimRunFunc funcrun
Definition: cfanim.h:92
static anim_move_result runturn(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:109
void cf_object_apply_below(object *pl)
void cf_object_update(object *op, int flags)
struct obj * above
Definition: object.h:146
int cf_player_move(player *pl, int dir)
static int ordered_commands
Definition: cfanim.c:512
static anim_move_result runghosted(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:291
static anim_move_result runstop(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:397
sint16 x
Definition: object.h:179
void cf_system_register_global_event(int event, const char *name, f_plug_api hook)
object * victim
Definition: cfanim.h:73
sstring cf_add_string(const char *str)
enum time_enum time_representation
Definition: cfanim.h:83
#define AP_APPLY
Definition: define.h:1009
static anim_move_result runmessage(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:451
#define PLAYER
Definition: define.h:113
static CFanimationHook * get_command(char *command)
Definition: cfanim.c:523
CF_PLUGIN void * eventListener(int *type,...)
Definition: cfanim.c:1129
void cf_log(LogLevel logLevel, const char *format,...)
#define NDI_NAVY
Definition: newclient.h:197
static long int initcamera(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:121
static int is_animated_player(object *pl)
Definition: cfanim.c:680
static anim_move_result runvisible(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:150
char * cf_strdup_local(const char *str)
int cf_init_plugin(f_plug_api getHooks)
struct CFanimation_struct * parent
Definition: cfanim.h:62
float speed_left
Definition: object.h:182
void cf_object_set_int_property(object *op, int propcode, int value)
static long int initghosted(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:282
struct mapdef * map
Definition: object.h:155
CF_PLUGIN void * getPluginProperty(int *type,...)
Definition: cfanim.c:1076
object * corpse
Definition: cfanim.h:81
static anim_move_result runmovement(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:73
mapstruct * cf_map_get_map(const char *name, int flags)
sstring cf_find_string(const char *str)
#define PLUGIN_NAME
Definition: cfanim.h:32
#define NDI_GREEN
Definition: newclient.h:202
const char * name
Definition: object.h:167
struct obj * env
Definition: object.h:151
static long int initpickup(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:249
struct obj * below
Definition: object.h:145
void cf_object_say(object *op, char *msg)
anim_move_result
Definition: cfanim.h:48
static int equality_split(char *buffer, char **variable, char **value)
Definition: cfanim.c:626
sint8 facing
Definition: object.h:186
sint16 y
Definition: object.h:179
struct pl * contr
Definition: object.h:134
static anim_move_result runnotice(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:383
static anim_move_result runteleport(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:369
struct CFanimation_struct * nextanimation
Definition: cfanim.h:85
static anim_move_result runwizard(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:166
static anim_move_result runsay(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:183
char * cf_get_maps_directory(const char *name, char *buf, int size)
static CFanimation * create_animation(void)
Definition: cfanim.c:696
float speed
Definition: object.h:181
#define CLEAR_FLAG(xyz, p)
Definition: define.h:512
#define FLAG_WIZ
Definition: define.h:527
#define MAX_BUF
Definition: define.h:81
static anim_move_result runfire(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:95
static anim_move_result rundropobject(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:241
void cf_object_remove(object *op)
static long int initvisible(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:141
static long int initmessage(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:443
int cf_object_apply(object *op, object *author, int flags)
struct CFmovement_struct * nextmovement
Definition: cfanim.h:84
#define EVENT_CLOCK
Definition: plugin.h:80
int snprintf(char *dest, int max, const char *format,...)
Definition: porting.c:498
void cf_player_message(object *op, char *txt, int flags)
static int compareAnims(const void *a, const void *b)
Definition: cfanim.c:514
#define UP_OBJ_CHANGE
Definition: object.h:355
#define CF_PLUGIN
Definition: plugin_common.h:35
int cf_object_move(object *op, int dir, object *originator)
#define FLAG_WIZCAST
Definition: define.h:586
static long int initpickupobject(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:263
void cf_object_pickup(object *op, object *what)
void cf_object_drop(object *op, object *author)
static CFanimation * first_animation
Definition: cfanim.c:36
CF_PLUGIN int closePlugin(void)
Definition: cfanim.c:1167
static anim_move_result runapplyobject(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:213
static long int initwizard(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:157
static long int initapplyobject(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:208
#define GETTIMEOFDAY(last_time)
Definition: global.h:442
CFanimationHook animationbox[]
Definition: cfanim.c:461
const char * name
Definition: cfanim.h:90
static anim_move_result runapply(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:196
#define GET_MAP_OB(M, X, Y)
Definition: map.h:193
static anim_move_result runpickup(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:253
struct obj * inv
Definition: object.h:148
#define NDI_UNIQUE
Definition: newclient.h:219
int cf_object_teleport(object *ob, mapstruct *map, int x, int y)
long int tick_left
Definition: cfanim.h:82
static void prepare_commands(void)
Definition: cfanim.c:518
object * cf_object_clone(object *op, int clonetype)
int animationcount
Definition: cfanim.c:510
static anim_move_result runcamera(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:130
struct CFmovement_struct * next
Definition: cfanim.h:67
static long int initsay(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:173
static anim_move_result runmoveto(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:423
Definition: map.h:346
static long int initstop(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:392
void cf_object_free(object *ob)
#define FLAG_WIZPASS
Definition: define.h:611
char * mapname
Definition: cfanim.c:322
object * cf_map_insert_object_there(object *op, mapstruct *m, object *originator, int flag)
int cf_map_get_width(mapstruct *map)
int cf_object_move_to(object *op, int x, int y)
int errors_allowed
Definition: cfanim.h:80
time_enum
Definition: cfanim.h:42
static anim_move_result runpickupobject(struct CFanimation_struct *animation, long int id, void *parameters)
Definition: cfanim.c:268
uint8 type
Definition: object.h:189
static long int initdropobject(const char *name, char *parameters, struct CFmovement_struct *move_entity)
Definition: cfanim.c:236
#define PLUGIN_VERSION
Definition: cfanim.h:33