Crossfire Server, Trunk
cfanim.cpp
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 <stdarg.h>
34 #include <stdlib.h>
35 #include <string.h>
36 
37 #include "cfanim.h"
38 #include "svnversion.h"
39 
41 
42 static CFanimation *first_animation = NULL;
44 static int get_boolean(const char *strg, int *bl);
45 
51 static int get_dir_from_name(const char *name) {
52  if (!strcmp(name, "north"))
53  return 1;
54  if (!strcmp(name, "north_east"))
55  return 2;
56  if (!strcmp(name, "east"))
57  return 3;
58  if (!strcmp(name, "south_east"))
59  return 4;
60  if (!strcmp(name, "south"))
61  return 5;
62  if (!strcmp(name, "south_west"))
63  return 6;
64  if (!strcmp(name, "west"))
65  return 7;
66  if (!strcmp(name, "north_west"))
67  return 8;
68  return -1;
69 }
70 
71 static long int initmovement(const char *name, char *parameters, CFmovement *move_entity) {
72  int dir;
74 
75  dir = get_dir_from_name(name);
76  move_entity->parameters = NULL;
77  return dir;
78 }
79 
80 static anim_move_result runmovement(CFanimation *animation, long int id, void *parameters) {
81  object *op = animation->victim;
82  int dir = id;
84 
85  if (animation->verbose)
86  cf_log(llevDebug, "CFAnim: Moving in direction %ld\n", id);
87  if (op->type == PLAYER)
88  cf_player_move(op->contr, dir);
89  else
90  cf_object_move(op, dir, op);
91  return mr_finished;
92 }
93 
94 static long int initfire(const char *name, char *parameters, CFmovement *move_entity) {
95  int dir;
97 
98  dir = get_dir_from_name(&(name[5]));
99  move_entity->parameters = NULL;
100  return dir;
101 }
102 
104 static anim_move_result runfire(CFanimation *animation, long int id, void *parameters) {
105  (void)parameters;
106  if (animation->verbose)
107  cf_log(llevDebug, "CFAnim: Firing in direction %ld\n", id);
108  return mr_finished;
109 }
110 
111 static long int initturn(const char *name, char *parameters, CFmovement *move_entity) {
112  int dir;
113  (void)parameters;
114 
115  dir = get_dir_from_name(&(name[5]));
116  move_entity->parameters = NULL;
117  return dir;
118 }
119 
120 static anim_move_result runturn(CFanimation *animation, long int id, void *parameters) {
121  object *op = animation->victim;
122  int dir = id;
123  (void)parameters;
124  /*int face;*/
125 
126  if (animation->verbose)
127  cf_log(llevDebug, "CFAnim: Turning in direction %ld\n", id);
128  op->facing = dir;
130 /* cf_object_set_int_property(op, CFAPI_OBJECT_PROP_ANIMATION, face);*/
131  return mr_finished;
132 }
133 
134 static long int initcamera(const char *name, char *parameters, CFmovement *move_entity) {
135  int dir;
136  (void)parameters;
137 
138  dir = get_dir_from_name(&(name[7]));
139  move_entity->parameters = NULL;
140  return dir;
141 }
142 
144 static anim_move_result runcamera(CFanimation *animation, long int id, void *parameters) {
145  (void)parameters;
146  if (animation->verbose)
147  cf_log(llevDebug, "CFAnim: Moving the camera in direction %ld\n", id);
148  return mr_finished;
149  /*if (animation->victim->type == PLAYER)
150  hook_scroll_map(animation->victim, id);
151  else
152  printf("CFAnim: Not a player\n");
153  return 1;*/
154 }
155 
156 static long int initvisible(const char *name, char *parameters, CFmovement *move_entity) {
157  int result;
158  (void)name;
159  (void)move_entity;
160 
162  return result;
163  cf_log(llevError, "CFAnim: Error in animation - possible values for 'invisible' are 'yes' and 'no'\n");
164  return -1;
165 }
166 
167 static anim_move_result runvisible(CFanimation *animation, long int id, void *parameters) {
168  (void)parameters;
169  if (id == -1)
170  return mr_finished;
171  animation->invisible = id;
172  return mr_finished;
173 }
174 
175 static long int initwizard(const char *name, char *parameters, CFmovement *move_entity) {
176  int result;
177  (void)name;
178  (void)move_entity;
179 
181  return result;
182  cf_log(llevError, "CFAnim: Error in animation - possible values for 'wizard' are 'yes' and 'no'\n");
183  return mr_finished;
184 }
185 
186 static anim_move_result runwizard(CFanimation *animation, long int id, void *parameters) {
187  (void)parameters;
188  if (id == -1)
189  return mr_finished;
190  animation->wizard = id;
191  return mr_finished;
192 }
193 
194 static long int initsay(const char *name, char *parameters, CFmovement *move_entity) {
195  (void)name;
196  if (parameters)
197  move_entity->parameters = cf_strdup_local(parameters);
198  else
199  move_entity->parameters = NULL;
200  if (move_entity->parent->verbose)
201  cf_log(llevDebug, "CFAnim: init say: parameters: %s\n", parameters ? parameters : "null");
202  return 1;
203 }
204 
205 static anim_move_result runsay(CFanimation *animation, long int id, void *parameters) {
206  (void)id;
207  if (parameters) {
208  cf_object_say(animation->victim, static_cast<const char *>(parameters));
209  free(parameters);
210  } else
211  cf_log(llevError, "CFAnim: Error in animation: nothing to say with say function\n");
212  return mr_finished;
213 }
214 
215 static long int initapply(const char *name, char *parameters, CFmovement *move_entity) {
216  (void)name;
217  (void)parameters;
218  (void)move_entity;
219  return 1;
220 }
221 
222 static anim_move_result runapply(CFanimation *animation, long int id, void *parameters) {
223  object *current_container;
224  (void)id;
225  (void)parameters;
226 
227  if (animation->victim->type != PLAYER)
228  return mr_finished;
229  current_container = animation->victim->container;
230  animation->victim->container = NULL;
231  cf_object_apply_below(animation->victim);
232  animation->victim->container = current_container;
233  return mr_finished;
234 }
235 
236 static long int initapplyobject(const char *name, char *parameters, CFmovement *move_entity) {
237  (void)name;
238  move_entity->parameters = parameters ? (void*)cf_add_string(static_cast<sstring>(parameters)) : NULL;
239  return 1;
240 }
241 
242 static anim_move_result runapplyobject(CFanimation *animation, long int id, void *parameters) {
243  object *current;
244  int aflag;
245  (void)id;
246 
247  if (!parameters)
248  return mr_finished;
249  current = animation->victim->below;
251  if (current->name == parameters)
252  break;
253  }
255  if (!current)
256  current = cf_object_find_by_name(animation->victim, static_cast<char *>(parameters));
257  if (!current) {
258  cf_free_string(static_cast<sstring>(parameters));
259  return mr_finished;
260  }
261  aflag = AP_APPLY;
262  cf_object_apply(animation->victim, current, aflag);
263  cf_free_string(static_cast<sstring>(parameters));
264  return mr_finished;
265 }
266 
267 static long int initdropobject(const char *name, char *parameters, CFmovement *move_entity) {
268  (void)name;
269  move_entity->parameters = parameters ?
270  (void *)cf_add_string(static_cast<sstring>(parameters)) : NULL;
271  return 1;
272 }
273 
274 static anim_move_result rundropobject(CFanimation *animation, long int id, void *parameters) {
275  object *what;
276  (void)id;
277  if (!parameters)
278  return mr_finished;
279  what = cf_object_find_by_name(animation->victim, static_cast<sstring>(parameters));
280  if (what != NULL)
281  cf_object_drop(what, animation->victim);
282  cf_free_string(static_cast<sstring>(parameters));
283  return mr_finished;
284 }
285 
286 static long int initpickup(const char *name, char *parameters, CFmovement *move_entity) {
287  (void)name;
288  (void)parameters;
289  (void)move_entity;
290  return 1;
291 }
292 
293 static anim_move_result runpickup(CFanimation *animation, long int id, void *parameters) {
294  object *current;
295  (void)id;
296  (void)parameters;
297 
298  current = animation->victim->below;
299  if (!current)
300  return mr_finished;
301  cf_object_pickup(animation->victim, current);
302  return mr_finished;
303 }
304 
305 static long int initpickupobject(const char *name, char *parameters, CFmovement *move_entity) {
306  (void)name;
307  move_entity->parameters = parameters ? (void*)cf_add_string(static_cast<sstring>(parameters)) : NULL;
308  return 1;
309 }
310 
311 static anim_move_result runpickupobject(CFanimation *animation, long int id, void *parameters) {
312  (void)id;
313  if (!parameters)
314  return mr_finished;
315  FOR_BELOW_PREPARE(animation->victim, current)
316  if (current->name == parameters) {
317  cf_object_pickup(animation->victim, current);
318  break;
319  }
321  cf_free_string(static_cast<sstring>(parameters));
322  return mr_finished;
323 }
324 
325 static long int initghosted(const char *name, char *parameters, CFmovement *move_entity) {
326  int result;
327  (void)name;
328  (void)move_entity;
329 
331  return result;
332  cf_log(llevError, "CFAnim: Error in animation: possible values for 'ghosted' are 'yes' and 'no'\n");
333  return -1;
334 }
335 
336 static anim_move_result runghosted(CFanimation *animation, long int id, void *parameters) {
337  object *corpse;
338 
339  if ((id && animation->ghosted)
340  || (!id && !animation->ghosted))
341  runghosted(animation, !id, parameters);
342  if (id) { /*Create a ghost/corpse pair*/
343  corpse = cf_object_clone(animation->victim, 1);
344  corpse->x = animation->victim->x;
345  corpse->y = animation->victim->y;
346  corpse->type = 0;
347  CLEAR_FLAG(corpse, FLAG_WIZ);
348  corpse->contr = NULL;
349  cf_map_insert_object_there(corpse, animation->victim->map, NULL, 0);
350  animation->wizard = 1;
351  animation->invisible = 1;
352  animation->corpse = corpse;
353  } else { /*Remove a corpse, make current player visible*/
354  animation->wizard = 0;
355  animation->invisible = 0;
356  cf_object_remove(animation->corpse);
358  animation->corpse = NULL;
359  animation->victim->invisible = 0;
360  cf_player_move(animation->victim->contr, 0);
361  }
362  animation->ghosted = id;
363  return mr_finished;
364 }
365 
367  char *mapname;
368  int mapx;
369  int mapy;
370 };
371 
372 static long int initteleport(const char *name, char *parameters, CFmovement *move_entity) {
373  char *mapname;
374  int mapx;
375  int mapy;
377  (void)name;
378 
379  move_entity->parameters = NULL;
380  cf_log(llevDebug, ".(%s)\n", parameters);
381  if (!parameters) {
382  cf_log(llevError, "CFAnim: Error - no parameters for teleport\n");
383  return 0;
384  }
385  mapname = strstr(parameters, " ");
386  cf_log(llevDebug, ".(%s)\n", parameters);
387  if (!mapname)
388  return 0;
389  *mapname = '\0';
390  mapx = atoi(parameters);
391  mapname++;
393  assert(parameters != NULL);
394  cf_log(llevDebug, ".(%s)\n", parameters);
395  mapname = strstr(parameters, " ");
396  cf_log(llevDebug, ".\n");
397  if (!mapname)
398  return 0;
399  *mapname = '\0';
400  mapy = atoi(parameters);
401  mapname++;
402  if (mapname[0] == '\0')
403  return 0;
404  teleport = (teleport_params *)malloc(sizeof(teleport_params));
405  teleport->mapname = cf_strdup_local(mapname);
406  teleport->mapx = mapx;
407  teleport->mapy = mapy;
408  move_entity->parameters = teleport;
409  return 1;
410 }
411 
412 static anim_move_result runteleport(CFanimation *animation, long int id, void *parameters) {
414  (void)id;
415 
416  if (!parameters)
417  return mr_finished;
418  cf_object_teleport(animation->victim, cf_map_get_map(teleport->mapname, 0), teleport->mapx, teleport->mapy);
419  free(parameters);
420  return mr_finished;
421 }
422 
423 static long int initnotice(const char *name, char *parameters, CFmovement *move_entity) {
424  (void)name;
425  move_entity->parameters = parameters ? cf_strdup_local(parameters) : NULL;
426  return 1;
427 }
428 static anim_move_result runnotice(CFanimation *animation, long int id, void *parameters) {
429  int val;
430  (void)id;
431 
432  val = NDI_NAVY|NDI_UNIQUE;
433 
434  cf_player_message(animation->victim, static_cast<char *>(parameters), val);
435  return mr_finished;
436 }
437 
438 static long int initstop(const char *name, char *parameters, CFmovement *move_entity) {
439  (void)name;
440  (void)parameters;
441  (void)move_entity;
442  return 1;
443 }
444 
446 static anim_move_result runstop(CFanimation *animation, long int id, void *parameters) {
447  (void)id;
448  (void)parameters;
449  if (animation->verbose)
450  cf_log(llevDebug, "CFAnim: stop encountered\n");
451  return mr_finished;
452 }
453 
455 struct param_moveto {
456  int x, y;
457 };
458 
459 static long int initmoveto(const char *name, char *parameters, CFmovement *move_entity) {
460  param_moveto *moveto;
461  int x, y;
462  (void)name;
463 
464  if (sscanf(parameters, "%d %d", &x, &y) != 2)
465  return 0;
466 
467  moveto = (param_moveto *)calloc(1, sizeof(param_moveto));
468  moveto->x = x;
469  moveto->y = y;
470  move_entity->parameters = moveto;
471 
472  return 1;
473 }
474 
475 static anim_move_result runmoveto(CFanimation *animation, long int id, void *parameters) {
476  int move;
478  (void)id;
479 
480  if (!dest)
481  return mr_finished;
482 
483  move = cf_object_move_to(animation->victim, dest->x, dest->y);
484 
485  if (animation->victim->x == dest->x && animation->victim->y == dest->y) {
486  free(parameters);
487  return mr_finished;
488  }
489 
490  if (move == 1)
491  return mr_again;
492 
493  return mr_finished;
494 }
495 
496 static long int initmessage(const char *name, char *parameters, CFmovement *move_entity) {
497  (void)name;
498  if (parameters)
499  move_entity->parameters = strdup(parameters);
500  else
501  move_entity->parameters = NULL;
502  return 1;
503 }
504 
505 static anim_move_result runmessage(CFanimation *animation, long int id, void *parameters) {
506  (void)id;
507  if (parameters && animation->victim->map) {
508  cf_map_message(animation->victim->map, (const char *)parameters, NDI_UNIQUE|NDI_GREEN);
509  free(parameters);
510  }
511 
512  return mr_finished;
513 }
514 
515 static long int inittrigger(const char *name, char *parameters, CFmovement *move_entity) {
516  long int connection;
517  (void)name;
518 
519  move_entity->parameters = NULL;
520  if (sscanf(parameters, "%ld", &connection) != 1 || connection <= 0) {
521  cf_log(llevError, "CFAnim: invalid connection %s\n", parameters);
522  return 0;
523  }
524  return connection;
525 }
526 
527 static anim_move_result runtrigger(CFanimation *animation, long int id, void *parameters) {
528  oblinkpt *olp;
529  mapstruct *map;
530  objectlink *ol = NULL;
531  (void)parameters;
532 
533  if (animation->victim == NULL || animation->victim->map == NULL) {
534  cf_log(llevError, "CFAnim: trigger for victim not on map or NULL.\n");
535  return mr_finished;
536  }
537 
538  map = animation->victim->map;
539 
540  /* locate objectlink for this connected value */
541  if (!map->buttons) {
542  cf_log(llevError, "Map %s called for trigger on connected %d but there ain't any button list for that map!\n", cf_map_get_sstring_property(map, CFAPI_MAP_PROP_PATH), id);
543  return mr_finished;
544  }
545  for (olp = map->buttons; olp; olp = olp->next) {
546  if (olp->value == id) {
547  ol = olp->link;
548  break;
549  }
550  }
551  if (ol == NULL) {
552  cf_log(llevError, "Map %s called for trigger on connected %d but there ain't any button list for that map!\n", cf_map_get_sstring_property(map, CFAPI_MAP_PROP_PATH), id);
553  return mr_finished;
554  }
555  /* run the object link */
556  cf_map_trigger_connected(ol, NULL, 1);
557 
558  return mr_finished;
559 }
560 
563  { "north", initmovement, runmovement },
564  { "north_east", initmovement, runmovement },
565  { "east", initmovement, runmovement },
566  { "south_east", initmovement, runmovement },
567  { "south", initmovement, runmovement },
568  { "south_west", initmovement, runmovement },
569  { "west", initmovement, runmovement },
570  { "north_west", initmovement, runmovement },
571  { "fire_north", initfire, runfire },
572  { "fire_north_east", initfire, runfire },
573  { "fire_east", initfire, runfire },
574  { "fire_south_east", initfire, runfire },
575  { "fire_south", initfire, runfire },
576  { "fire_south_west", initfire, runfire },
577  { "fire_west", initfire, runfire },
578  { "fire_north_west", initfire, runfire },
579  { "turn_north", initturn, runturn },
580  { "turn_north_east", initturn, runturn },
581  { "turn_east", initturn, runturn },
582  { "turn_south_east", initturn, runturn },
583  { "turn_south", initturn, runturn },
584  { "turn_south_west", initturn, runturn },
585  { "turn_west", initturn, runturn },
586  { "turn_north_west", initturn, runturn },
587  { "camera_north", initcamera, runcamera },
588  { "camera_north_east", initcamera, runcamera },
589  { "camera_east", initcamera, runcamera },
590  { "camera_south_east", initcamera, runcamera },
591  { "camera_south", initcamera, runcamera },
592  { "camera_south_west", initcamera, runcamera },
593  { "camera_west", initcamera, runcamera },
594  { "camera_north_west", initcamera, runcamera },
595  { "invisible", initvisible, runvisible },
596  { "wizard", initwizard, runwizard },
597  { "say", initsay, runsay },
598  { "apply", initapply, runapply },
599  { "apply_object", initapplyobject, runapplyobject },
600  { "drop_object", initdropobject, rundropobject },
601  { "pickup", initpickup, runpickup },
602  { "pickup_object", initpickupobject, runpickupobject },
603  { "ghosted", initghosted, runghosted },
604  { "teleport", initteleport, runteleport },
605  { "notice", initnotice, runnotice },
606  { "stop", initstop, runstop },
607  { "moveto", initmoveto, runmoveto },
608  { "message", initmessage, runmessage },
609  { "trigger", inittrigger, runtrigger }
610 };
611 
613 
614 static int ordered_commands = 0;
615 
616 static int compareAnims(const void *a, const void *b) {
617  return strcmp(((const CFanimationHook *)a)->name, ((const CFanimationHook *)b)->name);
618 }
619 
620 static void prepare_commands(void) {
622  ordered_commands = 1;
623 }
624 
626  CFanimationHook dummy;
627 
628  dummy.name = command;
629  if (!ordered_commands)
631  return (CFanimationHook *)bsearch(&dummy, animationbox, animationcount, sizeof(CFanimationHook), compareAnims);
632 }
633 
642 static CFmovement *parse_animation_block(char *buffer, size_t buffer_size, FILE *fichier, CFanimation *parent) {
643  CFmovement *first = NULL;
644  CFmovement *current = NULL;
645  CFmovement *next;
646  char *time;
647  char *name;
648  char *parameters;
649  int tick;
650  CFanimationHook *animationhook;
651 
652  if (parent->verbose)
653  cf_log(llevDebug, "CFAnim: In parse block for %s\n", buffer);
654  while (fgets(buffer, buffer_size, fichier)) {
655  if (buffer[0] == '[')
656  break;
657  if (buffer[0] == '#')
658  continue;
659  buffer[strlen(buffer)-strlen("\n")] = '\0';
660  while (buffer[strlen(buffer)-1] == ' ')
661  buffer[strlen(buffer)-1] = '\0';
662  if (strlen(buffer) <= 0)
663  continue;
664  time = buffer;
665 
666  name = strstr(buffer, " ");
667  if (!name)
668  continue;
669  *name = '\0';
670  name++;
671  while (*name == ' ')
672  name++;
673 
674  tick = atoi(time);
675  if (tick < 0)
676  continue;
677 
678  parameters = strstr(name, " ");
679  if (parameters) { /*Parameters may be nul*/
680  *parameters = '\0';
681  parameters++;
682  while (*parameters == ' ')
683  parameters++;
684  if (*parameters == '\0')
685  parameters = NULL;
686  }
687  animationhook = get_command(name);
688  if (!animationhook)
689  cf_log(llevError, "CFAnim: %s - Unknown animation command\n", name);
690  else if (parent->verbose) {
691  cf_log(llevDebug, "CFAnim: Parsed %s -> %p\n", name, animationhook);
692  }
693  if (!animationhook) {
694  if (parent->errors_allowed)
695  continue;
696  else
697  break;
698  }
699  next = (CFmovement *)malloc(sizeof(CFmovement));
700  if (!next)
701  continue;
702  next->parent = parent;
703  next->tick = tick;
704  next->next = NULL;
705  if (animationhook->funcinit)
706  next->id = animationhook->funcinit(name, parameters, next);
707  next->func = animationhook->funcrun;
708  if (current)
709  current->next = next;
710  else
711  first = next;
712  current = next;
713  }
714  return first;
715 }
716 
727 static int equality_split(char *buffer, char **variable, char **value) {
728  if (!strcmp(&buffer[strlen(buffer)-strlen("\n")], "\n"))
729  buffer[strlen(buffer)-strlen("\n")] = '\0';
730  *value = strstr(buffer, "=");
731  if (!*value)
732  return 0;
733  **value = '\0';
734  *variable = buffer;
735  (*value)++;
736  while ((strlen(*variable) > 0) && ((*variable)[strlen(*variable)-1] == ' '))
737  (*variable)[strlen(*variable)-1] = '\0';
738  while ((strlen(*value) > 0) && ((*value)[strlen(*value)-1] == ' '))
739  (*value)[strlen(*value)-1] = '\0';
740  while (**value == ' ')
741  (*value)++;
742  if ((**variable == '\0') || (**value == '\0'))
743  return 0;
744  return 1;
745 }
746 
758 static int get_boolean(const char *strg, int *bl) {
759  /*
760  * We're only parsing the first character, so we
761  * really don't need to call strncmp().
762  * Should future checks need to check multiple characters,
763  * strncmp() would be a good choice. For that reason,
764  * I won't optimize this down to a switch statement.
765  * It makes it clearer how to handle multi-character checks.
766  */
767  if (*strg == 'y')
768  *bl = 1;
769  else if (*strg == 'n')
770  *bl = 0;
771  else if (*strg == 'Y')
772  *bl = 1;
773  else if (*strg == 'N')
774  *bl = 0;
775  else if (*strg == '1')
776  *bl = 1;
777  else if (*strg == '0')
778  *bl = 0;
779  else
780  return 0;
781  return 1;
782 }
783 
789 static int is_animated_object(const object *ob) {
791 
792  for (current = first_animation; current; current = current->nextanimation)
793  if (current->victim == ob) {
794  return 1;
795  }
796  return 0;
797 }
798 
804  CFanimation *anim;
806 
807  anim = (CFanimation *)malloc(sizeof(CFanimation));
808  if (!anim)
809  return NULL;
810  anim->name = NULL;
811  anim->victim = NULL;
812  anim->event = NULL;
813  anim->nextmovement = NULL;
814  anim->nextanimation = NULL;
815  anim->delete_end = 0;
816  for (current = first_animation; (current && current->nextanimation); current = current->nextanimation)
817  ;
818  if (!current)
820  else
821  current->nextanimation = anim;
822  return anim;
823 }
824 
825 static object *find_by_name(object *origin, const char *name) {
826  int x, y, w, h;
827  mapstruct *map;
828  const char *sname;
829 
830  sname = cf_find_string(name);
831  if (!sname)
832  return NULL;
833 
834  while (origin && !origin->map)
835  origin = origin->env;
836 
837  if (!origin || !origin->map)
838  return NULL;
839 
840  map = origin->map;
841 
842  w = cf_map_get_width(map);
843  h = cf_map_get_height(map);
844 
845  for (x = 0; x < w; x++) {
846  for (y = 0; y < h; y++) {
847  FOR_MAP_PREPARE(map, x, y, ob) {
848  if (/*cf_object_get_sstring_property(ob, CFAPI_OBJECT_PROP_NAME)*/ob->name == sname)
849  return ob;
850  } FOR_MAP_FINISH();
851  }
852  }
853 
854  return NULL;
855 }
856 
868 static int start_animation(object *who, object *activator, object *event, const char *file, const char *message) {
869  FILE *fichier;
870  char *name = NULL;
871  int victimtype = 0;
872  object *victim = NULL;
873  int unique = 0;
874  int always_delete = 0;
875  int delete_end = 0;
876  int parallel = 0;
877  int paralyzed = 1;
878  int invisible = 0;
879  int wizard = 0;
880  enum time_enum timetype = time_second;
881  int errors_allowed = 0;
882  int verbose = 0;
883  const char *animationitem = NULL;
884  char buffer[HUGE_BUF];
885  char *variable;
886  char *value;
887  int errors_found = 0;
888  CFanimation *current_anim;
889 
890  fichier = fopen(file, "r");
891  if (fichier == NULL) {
892  cf_log(llevDebug, "CFAnim: Unable to open %s\n", file);
893  return 0;
894  }
895  while (fgets(buffer, HUGE_BUF, fichier)) {
896  if (buffer[0] == '[')
897  break;
898  if (buffer[0] == '#')
899  continue;
900  if (!strcmp(buffer, "\n"))
901  continue;
902  errors_found = 1;
903  cf_log(llevError, "CFAnim: '%s' has an invalid syntax.\n", buffer);
904  }
905  if (feof(fichier)) {
906  fclose(fichier);
907  return 0;
908  }
909  if (strncmp(buffer, "[Config]", 8)) {
910  cf_log(llevError, "CFAnim: Fatal error in %s: [Config] must be the first group defined.\n", file);
911  fclose(fichier);
912  return 0;
913  }
914  while (fgets(buffer, HUGE_BUF, fichier)) {
915  if (buffer[0] == '[')
916  break;
917  if (buffer[0] == '#')
918  continue;
919  if (!strcmp(buffer, "\n"))
920  continue;
921  if (!equality_split(buffer, &variable, &value))
922  errors_found = 1;
923  else {
924  if (!strcmp(variable, "name")) {
925  if (*value == '"')
926  value++;
927  if (value[strlen(value)-1] == '"')
928  value[strlen(value)-1] = '\0';
930  } else if (!strcmp(variable, "victimtype")) {
931  if (!strcmp(value, "player"))
932  victimtype = 0;
933  else if (!strcmp(value, "object"))
934  victimtype = 1;
935  else if (!strcmp(value, "any"))
936  victimtype = 2;
937  else if (!strcmp(value, "byname"))
938  victimtype = 3;
939  else
940  errors_found = 1;
941  } else if (!strcmp(variable, "victim")) {
942  cf_log(llevDebug, "CFAnim: Setting victim to %s\n", value);
943  if (!strcmp(value, "who"))
944  victim = who;
945  else if (!strcmp(value, "activator"))
946  victim = activator;
947  else if (!strcmp(value, "who_owner"))
948  if (!who) {
949  errors_found = 1;
950  cf_log(llevError, "CFAnim: Warning: object \"who\" doesn't exist and you're victimized it's owner\n");
951  } else
952  victim = who->env;
953  else if (!strcmp(value, "activator_owner"))
954  if (!activator) {
955  errors_found = 1;
956  cf_log(llevError, "CFAnim: Warning: object \"activator\" doesn't exist and you're victimized it's owner\n");
957  } else
958  victim = activator->env;
959  else if (victimtype == 3) {
961  } else
962  errors_found = 1;
963  } else if (!strcmp(variable, "unique")) {
964  if (!get_boolean(value, &unique))
965  errors_found = 1;
966  } else if (!strcmp(variable, "always_delete")) {
967  if (!get_boolean(value, &always_delete))
968  errors_found = 1;
969  } else if (!strcmp(variable, "delete_event_end")) {
970  if (!get_boolean(value, &delete_end))
971  errors_found = 1;
972  } else if (!strcmp(variable, "parallel")) {
973  if (!get_boolean(value, &parallel))
974  errors_found = 1;
975  } else if (!strcmp(variable, "paralyzed")) {
976  if (!get_boolean(value, &paralyzed))
977  errors_found = 1;
978  } else if (!strcmp(variable, "invisible")) {
979  if (!get_boolean(value, &invisible))
980  errors_found = 1;
981  } else if (!strcmp(variable, "wizard")) {
982  if (!get_boolean(value, &wizard))
983  errors_found = 1;
984  } else if (!strcmp(variable, "errors_allowed")) {
985  if (!get_boolean(value, &errors_allowed))
986  errors_found = 1;
987  } else if (!strcmp(variable, "verbose")) {
988  if (!get_boolean(value, &verbose))
989  errors_found = 1;
990  } else if (!strcmp(variable, "time_representation")) {
991  if (!strcmp(value, "second"))
992  timetype = time_second;
993  else if (!strcmp(value, "tick"))
994  timetype = time_tick;
995  else
996  errors_found = 1;
997  } else if (!strcmp(variable, "animation")) {
998  animationitem = cf_add_string(value);
999  } else
1000  errors_found = 1;
1001  }
1002  }
1003 
1004  if (message && message[0] != '\0') {
1005  cf_free_string(animationitem);
1006  animationitem = cf_add_string(message);
1007  }
1008 
1009  if (buffer[0] == '\0') {
1010  if (animationitem)
1011  cf_free_string(animationitem);
1012  cf_log(llevError, "CFAnim: Errors occurred during the parsing of %s\n", file);
1013  fclose(fichier);
1014  return 0;
1015  }
1016  if (!animationitem) {
1017  cf_log(llevError, "CFAnim: no animation specified when using %s\n", file);
1018  fclose(fichier);
1019  return 0;
1020  }
1021  if (!victim) {
1022  if (animationitem)
1023  cf_free_string(animationitem);
1024  cf_log(llevError, "CFAnim: Fatal error - victim is NULL");
1025  fclose(fichier);
1026  return 0;
1027  }
1028  if (!(current_anim = create_animation())) {
1029  if (animationitem)
1030  cf_free_string(animationitem);
1031  cf_log(llevError, "CFAnim: Fatal error - Not enough memory.\n");
1032  fclose(fichier);
1033  return 0;
1034  }
1035  if (always_delete) {
1036  /*if (verbose) printf("CFAnim: Freeing event nr. %d for %s.\n", current_event, who->name);*/
1038  event = NULL;
1039  }
1040  if (((victim->type == PLAYER) && (victimtype == 1))
1041  || ((victim->type != PLAYER) && (victimtype == 0))
1042  || (errors_found && !errors_allowed)) {
1043  if (verbose)
1044  cf_log(llevError, "CFAnim: No correct victim found or errors found, aborting.\n");
1045  if (animationitem)
1046  cf_free_string(animationitem);
1047  free(current_anim);
1048  fclose(fichier);
1049  return 0;
1050  }
1051  if (unique && !always_delete) {
1052  /*if (verbose) printf("CFAnim: Freeing event nr. %d for %s.\n", current_event, who->name);*/
1054  event = NULL;
1055  }
1056  current_anim->name = name;
1057  current_anim->victim = victim;
1058  current_anim->event = event;
1059  current_anim->paralyze = paralyzed;
1060  current_anim->invisible = invisible;
1061  current_anim->wizard = wizard;
1062  current_anim->unique = unique;
1063  current_anim->delete_end = delete_end;
1064  current_anim->ghosted = 0;
1065  current_anim->corpse = NULL;
1066  current_anim->time_representation = timetype;
1067  current_anim->verbose = verbose;
1068  current_anim->tick_left = 0;
1069  current_anim->errors_allowed = errors_allowed;
1070 
1071  while (buffer[0] == '[') {
1072  while (strncmp(&buffer[1], animationitem, strlen(animationitem))) {
1073  while ((value = fgets(buffer, HUGE_BUF, fichier)) != NULL)
1074  if (buffer[0] == '[')
1075  break;
1076  if (value == NULL) {
1077  cf_log(llevError, "CFAnim: no matching animation %s in file.\n", animationitem);
1078  cf_free_string(animationitem);
1079  fclose(fichier);
1080  return 0;
1081  }
1082  }
1083  current_anim->nextmovement = parse_animation_block(buffer, HUGE_BUF, fichier, current_anim);
1084  if (current_anim->nextmovement)
1085  break;
1086  }
1087  fclose(fichier);
1088  return 1;
1089 }
1090 
1096 static void animate_one(CFanimation *animation, long int milliseconds) {
1098  int mult = 1;
1100 
1101  if (animation->time_representation == time_second) {
1102  animation->tick_left += milliseconds;
1103  mult = 1000;
1104  } else
1105  animation->tick_left++;
1106 
1107  if (animation->verbose)
1108  cf_log(llevDebug, "CFAnim: Ticking %s for %s. Tickleft is %ld\n", animation->name, animation->victim->name, animation->tick_left);
1109  if (animation->invisible)
1110  animation->victim->invisible = 10;
1111  if (animation->wizard && animation->victim->type == PLAYER) {
1112  /* setting FLAG_WIZ *on non player leads to issues, as many functions expect contr to not be NULL in this case. */
1113  if (animation->verbose)
1114  cf_log(llevDebug, "CFAnim: Setting wizard flags\n");
1115  cf_object_set_flag(animation->victim, FLAG_WIZPASS, 1);
1116  cf_object_set_flag(animation->victim, FLAG_WIZCAST, 1);
1117  cf_object_set_flag(animation->victim, FLAG_WIZ, 1);
1118  if (animation->verbose)
1119  cf_log(llevDebug, "CFAnim: Setting wizard flags done\n");
1120 
1121  }
1122  if (animation->paralyze)
1123  animation->victim->speed_left = -99999;
1124 
1125  cf_object_update(animation->victim, UP_OBJ_CHANGE);
1126 
1127  if (animation->nextmovement)
1128  while (animation->tick_left > animation->nextmovement->tick*mult) {
1129  animation->tick_left -= animation->nextmovement->tick*mult;
1130  result = animation->nextmovement->func(animation, animation->nextmovement->id, animation->nextmovement->parameters);
1131  if (result == mr_again)
1132  continue;
1133 
1134  current = animation->nextmovement;
1135  animation->nextmovement = animation->nextmovement->next;
1136  free(current);
1137  if (!animation->nextmovement)
1138  break;
1139  }
1140  cf_object_set_flag(animation->victim, FLAG_WIZPASS, 0);
1141  cf_object_set_flag(animation->victim, FLAG_WIZCAST, 0);
1142  cf_object_set_flag(animation->victim, FLAG_WIZ, 0);
1143 }
1144 
1149 long usec_elapsed(struct timespec first, struct timespec second) {
1150  time_t sec_elapsed = second.tv_sec - first.tv_sec;
1151  long nsec_elapsed = second.tv_nsec - first.tv_nsec;
1152  return (sec_elapsed * 1e6) + (nsec_elapsed / 1e3);
1153 }
1154 
1158 static void animate(void) {
1160  CFanimation *next;
1161  CFanimation *previous_anim = NULL;
1162  struct timespec now;
1163  static struct timespec yesterday;
1164  static int already_passed = 0;
1165  long int delta_milli;
1166 
1167  clock_gettime(CLOCK_MONOTONIC, &now);
1168  if (!already_passed) {
1169  already_passed = 1;
1170  yesterday = now;
1171  return;
1172  }
1173  delta_milli = usec_elapsed(yesterday, now) / 1e3;
1174  /*printf("Working for %ld milli seconds\n", delta_milli);*/
1175  yesterday = now;
1176  for (current = first_animation; current; current = current->nextanimation)
1177  animate_one(current, delta_milli);
1179  while (current) {
1180  if (!current->nextmovement) {
1181  if (current->paralyze)
1182  current->victim->speed_left = current->victim->speed;
1183  next = current->nextanimation;
1184  if (first_animation == current)
1186  else {
1187  previous_anim->nextanimation = next;
1188  }
1189  if (current->delete_end && current->event != NULL)
1190  cf_object_remove(current->event);
1191  free(current->name);
1192  free(current);
1193  current = next;
1194  } else {
1195  previous_anim = current;
1196  current = current->nextanimation;
1197  }
1198  }
1199 }
1200 
1207 extern "C"
1208 CF_PLUGIN int initPlugin(const char *iversion, f_plug_api gethooksptr) {
1209  (void)iversion;
1210  cf_init_plugin(gethooksptr);
1211  cf_log(llevDebug, "CFAnim 2.0a init\n");
1212 
1213  /* Place your initialization code here */
1214  return 0;
1215 }
1216 
1217 extern "C"
1219  va_list args;
1220  const char *propname;
1221  char *buf;
1222  int size;
1223 
1224  va_start(args, type);
1225  propname = va_arg(args, const char *);
1226 
1227  if (!strcmp(propname, "Identification")) {
1228  buf = va_arg(args, char *);
1229  size = va_arg(args, int);
1230  va_end(args);
1231  snprintf(buf, size, PLUGIN_NAME);
1232  return NULL;
1233  } else if (!strcmp(propname, "FullName")) {
1234  buf = va_arg(args, char *);
1235  size = va_arg(args, int);
1236  va_end(args);
1237  snprintf(buf, size, PLUGIN_VERSION);
1238  return NULL;
1239  }
1240  va_end(args);
1241  return NULL;
1242 }
1243 
1244 extern "C"
1246  (void)op;
1247  (void)params;
1248  return mr_finished;
1249 }
1250 
1251 extern "C"
1253  cf_log(llevDebug, "CFAnim 2.0a post init\n");
1254  /* Pick the global events you want to monitor from this plugin */
1256  return 0;
1257 }
1258 
1259 extern "C"
1261  va_list args;
1262  int rv = 0;
1263  int event_code;
1264 
1265  va_start(args, type);
1266  event_code = va_arg(args, int);
1267  assert(event_code == EVENT_CLOCK);
1268 
1269  animate();
1270 
1271  va_end(args);
1272 
1273  return rv;
1274 }
1275 
1276 extern "C"
1277 CF_PLUGIN int eventListener(int *type, ...) {
1278  int rv = 0;
1279  va_list args;
1280  char *buf, message[MAX_BUF], script[MAX_BUF];
1281  object *who, *activator/*, *third*/, *event;
1282  int query;
1283 
1284  va_start(args, type);
1285 
1286  who = va_arg(args, object *);
1287  activator = va_arg(args, object *);
1288  /*third =*/ va_arg(args, object *);
1289  buf = va_arg(args, char *);
1290 
1291  if (buf != NULL) {
1292  snprintf(message, sizeof(message), "%s", buf);
1293  } else {
1294  message[0] = '\0';
1295  }
1296 
1297  query = va_arg(args, int); /* 'fix', ignored */
1298  event = va_arg(args, object *);
1299 
1300  if (query == 1 && strcmp(message, "query_object_is_animated") == 0) {
1301  rv = is_animated_object(who);
1302  va_end(args);
1303  return rv;
1304  }
1305 
1307  cf_get_maps_directory(event->slaying, script, sizeof(script));
1308  va_end(args);
1309 
1310  /* Put your plugin action(s) here */
1311  if (activator != NULL) {
1312  cf_log(llevDebug, "CFAnim: %s called animator script %s\n", activator->name, script);
1313  } else if (who != NULL) {
1314  activator = who;
1315  cf_log(llevDebug, "CFAnim: %s called animator script %s\n", who->name, script);
1316  }
1317 
1319 
1320  return rv;
1321 }
1322 
1323 extern "C"
1325  cf_log(llevDebug, "CFAnim 2.0a closing\n");
1326  return 0;
1327 }
mr_again
@ mr_again
Definition: cfanim.h:47
give.next
def next
Definition: give.py:44
animate_one
static void animate_one(CFanimation *animation, long int milliseconds)
Definition: cfanim.cpp:1096
September
Release notes for Crossfire September
Definition: Release_notes.txt:1
only
**Media tags please refer to the protocol file in doc Developers protocol Quick for your pleasure only
Definition: media-tags.txt:13
skills
Player Stats effect how well a character can survie and interact inside the crossfire world This section discusses the various what they and how they effect the player s actions Also in this section are the stat modifiers that specific classes professions bring Player and sps the current and maximum the Current and Maximum The Current Sp can go somewhat negative When Sp is negative not all spells can be and a more negative Sp makes spell casting less likey to succeed can affect Damage and how the characters as well as how often the character can attack this affects the prices when buying and selling items if this drops the player will start losing hit points wd Cleric or Dwarf sm Elf wd Fireborn ft Human ra Mage C Monk se Ninja hi Priest C Quetzalcoatl mw Swashbuckler si Thief st Viking ba Warrior or Wizard C Wraith C Class Prof Str Dex Con Wis Cha Int Pow Net Skills Enclosed are codes used for the skills above The ones in and fighting should all be pretty self explanatory For the other skills
Definition: stats.txt:126
PLAYER
@ PLAYER
Definition: object.h:112
initsay
static long int initsay(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:194
cf_log
void cf_log(LogLevel logLevel, const char *format,...)
Definition: plugin_common.cpp:1522
server
Release notes for Crossfire This is see the Changelog file included with the software Major changes since but slower than players without that skill *weather system is hopefully fixed *misc bug fixes Once you have installed the server
Definition: Release_notes.txt:25
cf_map_get_height
int cf_map_get_height(mapstruct *map)
Definition: plugin_common.cpp:1404
Files
Install Bug reporting Credits but rather whatever guild name you are using *With the current map and server there are three they and GreenGoblin *Whatever name you give the folder should but it will still use GUILD_TEMPLATE *You can change what guild it uses by editing the map files Modify Map Files
Definition: README.txt:17
cf_add_string
sstring cf_add_string(const char *str)
Definition: plugin_common.cpp:1167
FOR_MAP_FINISH
#define FOR_MAP_FINISH()
Definition: define.h:730
cf_map_get_sstring_property
sstring cf_map_get_sstring_property(mapstruct *map, int propcode)
Definition: plugin_common.cpp:270
options
static struct Command_Line_Options options[]
Definition: init.cpp:376
occurs
pluglist shows those as well as a short text describing each the list will simply appear empty The keyword for the Python plugin is Python plugout< keyword > Unloads a given identified by its _keyword_ So if you want to unload the Python you need to do plugout Python plugin< libname > Loads a given whose _filename_ is libname So in the case of you d have to do a plugin cfpython so Note that all filenames are relative to the default plugin it tries to load all available files in the SHARE plugins directory as plugin libraries It first displays the Initializing the plugin has the opportunity to signal itself by a message on the console Then the server displays an informative message containing both the plugin content and its keyword For the Python the standard load process thus GreenGoblin When a plugin has been it can request to be warned whenever a global event occurs(global events are 'shout', 'login', 'death', and so on). A complete list of events is available in the include/plugin.h file. Specific notes related to the Python plugin. -------------------------------------------- The Python plugin supports all global events. The const ant PYTHON_DEBUG defined at the start of the plugin_python.c file increases the verbosity of the plugin. Global event scripts go into SHARE/maps/python/events/< event name >
AP_APPLY
#define AP_APPLY
Definition: define.h:574
llevError
@ llevError
Definition: logger.h:11
it
**Media tags please refer to the protocol file in doc Developers protocol Quick for your pleasure an example[/b][i] This is an old full of dirt and partially destroyed[hand] My dear as you two years i had to leave quickly Words have come to me of powerful magic scrolls discovered in an old temple by my uncle I have moved to study them I not forgot your knowledge in ancient languages I need your help for[print][b] Some parts of document are to damaged to be readable[/b][arcane] Arghis[color=Red] k h[color=dark slate blue] ark[color=#004000] fido[/color][hand] please come as fast as possible my friend[print][b] The bottom of letter seems deliberatly shredded What is it
Definition: media-tags.txt:28
cf_object_teleport
int cf_object_teleport(object *ob, mapstruct *map, int x, int y)
Definition: plugin_common.cpp:1360
C
Player Stats effect how well a character can survie and interact inside the crossfire world This section discusses the various what they and how they effect the player s actions Also in this section are the stat modifiers that specific classes professions bring Player and sps the current and maximum the Current and Maximum The Current Sp can go somewhat negative When Sp is negative not all spells can be and a more negative Sp makes spell casting less likey to succeed can affect Damage and how the characters as well as how often the character can attack this affects the prices when buying and selling items if this drops the player will start losing hit points wd Cleric or Dwarf sm Elf wd Fireborn ft Human ra Mage C Monk se Ninja hi Priest C Quetzalcoatl mw Swashbuckler si Thief st Viking ba Warrior or Wizard C Wraith C Class Prof Str Dex Con Wis Cha Int Pow Net Skills Enclosed are codes used for the skills above The ones in and fighting should all be pretty self explanatory For the other a brief description is for a more detailed look at the skills doc file Skill remove use magic items C
Definition: stats.txt:133
cf_object_apply_below
void cf_object_apply_below(object *pl)
Definition: plugin_common.cpp:553
player
Definition: player.h:105
runsay
static anim_move_result runsay(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:205
eventListener
CF_PLUGIN int eventListener(int *type,...)
Definition: cfanim.cpp:1277
diamondslots.x
x
Definition: diamondslots.py:15
time_enum
time_enum
Definition: cfanim.h:39
this
set linux kernel mode for anything in usr src linux *setq auto mode and these comments tend to be worth noticing As discussed on the preferred style for expressions is like this
Definition: style-guide.txt:193
say.previous
dictionary previous
Definition: say.py:205
cfanim_runPluginCommand
CF_PLUGIN anim_move_result cfanim_runPluginCommand(object *op, char *params)
Definition: cfanim.cpp:1245
oblinkpt::next
oblinkpt * next
Definition: object.h:463
NDI_GREEN
#define NDI_GREEN
Definition: newclient.h:238
initapply
static long int initapply(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:215
prepare_commands
static void prepare_commands(void)
Definition: cfanim.cpp:620
ordered_commands
static int ordered_commands
Definition: cfanim.cpp:614
runmoveto
static anim_move_result runmoveto(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:475
initmoveto
static long int initmoveto(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:459
runghosted
static anim_move_result runghosted(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:336
cf_strdup_local
char * cf_strdup_local(const char *str)
Definition: plugin_common.cpp:1446
convert
Definition: convert.py:1
initwizard
static long int initwizard(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:175
FOR_BELOW_PREPARE
#define FOR_BELOW_PREPARE(op_, it_)
Definition: define.h:704
object::invisible
int16_t invisible
Definition: object.h:370
closePlugin
CF_PLUGIN int closePlugin(void)
Definition: cfanim.cpp:1324
object::x
int16_t x
Definition: object.h:335
swamp
non standard information is not specified or uptime this means how long since the executable has been started A particular host may have been running a server for quite a long but due to updates or the length of time the server instance has been up may be much shorter MN US< br > link< br >< a href="http: text_comment=Latest SVN 1.x branch, Eden Prairie, MN US archbase=Standard mapbase=Standard codebase=Standard num_players=3 in_bytes=142050710 out_bytes=-1550812829 uptime=909914 version=1.11.0 sc_version=1027 cs_version=1023 last_update=1214541369 END_SERVER_DATA ---- Multigod -------- This is a brief description of the MULTIGOD hack. It is preserved here for mostly historical reasons. Introduction ~~~~~~~~~~~~ The intention of this code is to enhance the enjoy-ability and playability of clerical characters in the new skills/exp scheme. This is done by giving players gods to worship who in turn effect clerical magic and powers. Included in this patch are several new spells which (hopefully) will allow the priest characters a better chance to gain xp at higher levels. Notably, the "holy orb" and "holy word" spells have been revamped. When MULTIPLE_GODS flag is defined in include/config.h, this code is enabled. This code (described below) encompasses 3 main parts: an array of gods that players/NPCs may worship, new clerical spells which rely on the worshiped god's attrib- utes in Gods[] array and, altars/praying--the interface between a worshiper and their god. b.t. thomas@astro.psu.edu Implementation Details ~~~~~~~~~~~~~~~~~~~~~~ This code is flexible and easy to configure (just edit the god archetypes). Part of the reason for creating this code was to allow server maintainers to develop their own "mythos". From my personal point of view, I hate having the old "Christian" aligned mythos, but if that's what you like, you can replicate it with this code too (see below). Properties of the Gods ~~~~~~~~~~~~~~~~~~~~~~ Here is a fuller description of Gods archetype values. ---- name - name of the god (required) other_arch - archetype that will be used for the summon holy servant spell. title - diametrically opposed god, leave blank if none exists attacktype - favored attack of this god, used in spells of summon avatar, holy word. Recipients of "holy possession" get this too. immune - Avatars/holy servants/recipient of "holy possession" gets this. protected - all of the above AND recipient of god's blessing and the priest of this god gets this. vulnerable - Avatar/servant/recipient of gods curse/priest of this god get this. path_attuned - priest of this god and recipient of "bless" gets this path_repelled - priest and recipient of "curse" gets this path_denied - priest and recipient of "curse" gets this slaying - comma delimited list of the races of creatures that are aligned with the god. "summon cult monsters" uses. this list to find creatures. Summon avatar/call servant code assigns this value to prevent them from attacking aligned races. Value is blank if no race(s) exists. race - comma delimited list of the races of creatures "holy word", "holy possession" spells will effect. Value entry is blank if no such race(s) exists. hp,dam,ac,wc - base stats for the summoned avatar. ---- IF MORE_PRIEST_GIFTS is defined (in gods.c) then ADDITIONAL gifts/limitations will be assigned to the priest: Flags ^^^^^ Now, the following flags, in addition to being used by the god (if planted on a map) are assigned to the worshiping priest: can_use_weapon, can_use_armour, is_undead, is_blind, reflect_missile, reflect_spell, make_invisible, stealth, can_see_in_dark, xrays NOTE: if can_use_armour/can_use_weapon flags are NOT present, then the priest will be forbidden the use of these items. Stats ^^^^^ The following stats are used: ---- luck - how lucky the god (and the priest) are. last_eat - how fast priest digestion is last_hp - how fast priest healing is last_sp - how fast priest mana regeneration is last_grace - how fast priest grace regeneration is ---- Designing New Gods ~~~~~~~~~~~~~~~~~~ To examine the gods properties, use the '-m8' flag (ie 'crossfire -m8'). Note some of the big differences here in terms of spell_paths, races, etc. Most of these entries were designed with roughly polar opposite gods. For designing new gods. You should make sure that worshiping a god will be "unique" in some way. But playbalance first! You must consider the balance between the following: . spellpaths . priest gifts . priest limitations . special spells . attacktypes . summoned monster lists . properties of the avatar and holy servant. Here are some hard and fast rules for designing gods: - Decide how the cleric will get experience. The god should be either a 'summoning', 'turning' *or* a 'wounding' god. If summoning/turning, make sure the aligned_race/enemy_race list(s) has enough creatures to summon/slay at low, medium and high levels. DONT give a god attuned to wounding AND turning||summoning (in fact, at minimum, one of these 3 paths should be repelled/denied). - make sure the summoned avatar is stronger than the servant (!) - examine the avatar/servant stats. If set inproperly, you will give wimpy/super values. For example, Avatars/servants with less than 50 hp (and a high ac/no armour) will vanish quickly. Shoot for stats like: ---- type | A V E R A G E S T A T S | hp | ac | wc | arm | dam | speed ----------|----------------------------------- servant | 50 | 5 | 5 | 20 | 5 | 0.15 avatar | 350 | -5 | -1 | 50 | 50 | 0.25 ---- Its difficult to give measurements on how to trade these off. To help guide your choices try to conserve the value of speed*dam and (armour+1)*hp. * avoid giving the potent attacktypes of death, weaponmagic and paralysis. * gods have a vulnerability for every immunity. Not all attacktypes are the same. Immunity to physical, magic and common attacktypes (like fire/cold/electric) are very potent. Similarly, vuln to these is a big negative. * SPELL paths. Carefull treatment is needed here. Give a path_denied/ or a couple path_repelled for every path_attuned. BUT note: not all paths are of equal use. (ex path_abjuration has a very large list of spells). The main clerical paths are restoration, abjuration, protection, turning, wounding and summoning. For balance, make 3-4 of these repelled/denied and 1 or 2 attuned. Be sure to check out the special spells list (below). Attuned paths like DEATH, WOUNDING and (especially) PROTECTION are very potent. Allow for some balance else where if you assign (one!) of these as a path_attuned. * If using the MORE_PRIEST_GIFTS define: priest limitations of no weapons and no armour are very negative, be sure to compensate with more than an attunded path. Of course, you may break these 'rules' to create your god. When you do that, you had better make up for the bonus elsewhere! Otherwise, you will create a 'mega-god' whose worship (by the player priests) will unbalance the game. Designing a good god takes a bit of work. Special Spells ~~~~~~~~~~~~~~ Here is a possibly *incomplete* list of the special spells that a god may grant use to a worshiper. Check the file spellist.h for the 0 bookchance clerical spells to find all of these. (This list was complete on 10/96). ---- INFO perceive self PROTECTION defense; immuntity to cold, fire, electricity, poison, slow, paralysis, draining, attack, and magic RESTORE remove damnation; reincarnation; raise dead; resurrection; regeneration WOUNDING cause critical wounds; retributive strike LIGHT daylight; nightfall DEATH face of death; finger of death SUMMONING insect plague CREATE wall of thorns ---- Ideas ~~~~~ * Allow sacrifices. This is an excellent way to give a cleric xp. Need to create enemy_race creatures w/ bodyparts we can sacrifice, and designate a pointer in Gods to the appropriate array of stuff we can sacrifice for xp. Experience ---------- Obsolete file kept for historical reasons. Introduction ~~~~~~~~~~~~ This patch represents a "developer 's" version of the exp/skills system. While I have now achieved all of the objectives in sections "B" and "C" of the coding proposal (see README.PROPOSAL) and have play-tested as much of the code as possible, I am sure some big bugs must remain. (One for sure is that exp gained when using rod/horn/wand is wrong.) Below this section I outline 1) coding philosophy, 2) gross description of how the code impinges/interacts within older code. 3) designer's notes on the changes to the code. Comments on any area of this coding would be appreciated. Personally, I would like to see the Pow stat and a 2-type system of magic come into being. After all of you check out the code, I would like to discuss enhancements/bug fixes/implementation. For instance, is it too hard to figure out how to use the code! Sometime tomorrow exp2.tar.gz will be available in pub/thomas on ftp.astro.psu.edu. b.t. Code Philosophy ^^^^^^^^^^^^^^^ To move CF over to a new skills-based experience system. In this implementation several kinds of experience will exist. Players will gain experience in each kind of experience (or category) based on their actions in the game. The sum of all the various categories of experience equals the player "score", from which dam, wc, and hp are determined. All experience gaining actions will be through the use of certain skills -- so called "associated skills". Associated skills are each related to 1 kind of experience. Thus, for example, "stealing" is a skill associated with "agility" experience. There exists also "miscellaneous" skills which allow the use of a unique skill, but which are not related to any kind of experience and whose use does not generate experience points. In this implementation, skills and objects are both treated as objects in the inventory of the user. Experience "objects" each represent one kind of experience and are always invisible. Skills objects each represent one kind of skill available in the game. Skills objects may either be invisible or have an associated bitmap (in which case they are "tools"). All experience gaining actions will be through the use of certain skills -- called "associated skills". Associated skills are each related to 1 kind of experience. Thus, for example, "stealing" is a skill associated with "agility" experience. Both Players and NPC's may only use skills which are in their inventories. NPC's do not use experience objects. A breakdown of the properties of skills and exp objects objects is as follows: ---- Object Property NPC use? ------ ----------------------------------- ------- Experience Each represents a different kind of NO experience in the game. The object in the player inventory keeps track of player experience in that category. Always is invisible. Skill- Represents a skill the player may YES associated perform. May be either invisible or visible as a "tool". Successful use of this skill generates experience. Experience is allocated to appropriate experience object. Skill- Same as above, *but* this skill is not YES miscell. related to any experience category, and use of this skill generates *no* experience. ---- Linking of associated skills to experience categories is done during initialization of the code (in init()) based on the shared stats of both. How skills and experience categories are named and linked may be changed by editing the skills/experience object archetypes. Implementation Details ~~~~~~~~~~~~~~~~~~~~~~ The most important thing is that I moved most of the code into the server/skills.c and server/skill_util.c files. The skills code is loosely implemented along the lines of the spell code. This is to say that: . skills use (do_skill) is called from fire(). . there is a skills[] table similar to spells[]. . server files skills.c and skill_util.c parallel spell_effect.c and spell_util.c in respective functionallity. Particular notes about the implementation are outlined below. Defines ^^^^^^^ #define MAX_EXP_CAT be > I had to make use of several global parameters These swamp
Definition: arch-handbook.txt:553
guildoracle.list
list
Definition: guildoracle.py:87
object::speed_left
float speed_left
Definition: object.h:338
SVN_REV
#define SVN_REV
Definition: svnversion.h:2
runwizard
static anim_move_result runwizard(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:186
object::map
struct mapstruct * map
Definition: object.h:305
that
Install Bug reporting Credits so make sure you have that
Definition: README.txt:6
guildjoin.ob
ob
Definition: guildjoin.py:42
CFanimationHook::funcrun
CFAnimRunFunc funcrun
Definition: cfanim.h:91
param_moveto
Definition: cfanim.cpp:455
command
Crossfire Protocol most of the time after the actual code was already omit certain important and possibly make life miserable any new developer or curious player should be able to find most of the relevant information here If inconsistencies are found or this documentation proves to be consider the latest server side protocol code in the public source code repository as the authoritative reference Introduction If you were ever curious enough to telnet or netcat to a Crossfire chances are you were sorely disappointed While the protocol may seem to use plain text at it actually uses a mix of ASCII and binary data This handbook attempts to document various aspects of the Crossfire protocol As consult the README file to find out how to get in touch with helpful people via mailing and more History the communications plan was set to be a text based system It was up to the server and client to parse these messages and determine what to do These messages were assumed to be line per message At a reasonably early stage of Eric Anderson wrote a then the data itself you could send many data and after the other end could decode these commands This works fairly but I think the creation of numerous sub packets has some performance hit the eutl was not especially well so writing a client for a different platform became more Eric left to work on other products shortly after writing his which didn t really leave anyone with a full understanding of the socket code I have decided to remove the eutl dependency At least one advantage is that having this network related code directly in the client and server makes error handling a bit easier cleaner Packet Format the outside packet method the byte size for the size information is not included here Eutl originally used bytes for the size to bytes seems it makes a least some sense The actual data is something of the nature of the commands listed below It is a text command
Definition: protocol.txt:63
time
non standard information is not specified or uptime this means how long since the executable has been started A particular host may have been running a server for quite a long time
Definition: arch-handbook.txt:206
cf_object_apply
int cf_object_apply(object *op, object *author, int flags)
Definition: plugin_common.cpp:542
mad_mage_user.file
file
Definition: mad_mage_user.py:15
cf_object_move_to
int cf_object_move_to(object *op, int x, int y)
Definition: plugin_common.cpp:630
CFanimation::nextmovement
CFmovement * nextmovement
Definition: cfanim.h:83
cf_object_free_drop_inventory
void cf_object_free_drop_inventory(object *ob)
Definition: plugin_common.cpp:571
FLAG_WIZCAST
#define FLAG_WIZCAST
Definition: define.h:289
cf_find_string
sstring cf_find_string(const char *str)
Definition: plugin_common.cpp:1189
initnotice
static long int initnotice(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:423
you
TIPS on SURVIVING Crossfire is populated with a wealth of different monsters These monsters can have varying immunities and attack types In some of them can be quite a bit smarter than others It will be important for new players to learn the abilities of different monsters and learn just how much it will take to kill them This section discusses how monsters can interact with players Most monsters in the game are out to mindlessly kill and destroy the players These monsters will help boost a player s after he kills them When fighting a large amount of monsters in a single attempt to find a narrower hallway so that you are not being attacked from all sides Charging into a room full of Beholders for instance would not be open the door and fight them one at a time For there are several maps designed for them Find these areas and clear them out All throughout these a player can find signs and books which they can read by stepping onto them and hitting A to apply the book sign These messages will help the player to learn the system One more always keep an eye on your food If your food drops to your character will soon so BE CAREFUL ! NPCs Non Player Character are special monsters which have intelligence Players may be able to interact with these monsters to help solve puzzles and find items of interest To speak with a monster you suspect to be a simply move to an adjacent square to them and push the double ie Enter your and press< Return > You can also use say if you feel like typing a little extra Other NPCs may not speak to you
Definition: survival-guide.txt:37
CFanimation::wizard
int wizard
Definition: cfanim.h:74
town
*going from world map to inside a town
Definition: scaling.txt:1
NDI_NAVY
#define NDI_NAVY
Definition: newclient.h:233
ZipGenius
Release notes for Crossfire This is see the Changelog file included with the software Major changes since but slower than players without that skill *weather system is hopefully fixed *misc bug fixes Once you have installed the you MUST download a map set point to where you installed Crossfire install Grab map set from official SourceForge page The following sets are at ZipGenius
Definition: Release_notes.txt:40
oblinkpt
Definition: object.h:460
cf_player_move
int cf_player_move(player *pl, int dir)
Definition: plugin_common.cpp:524
runteleport
static anim_move_result runteleport(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:412
mr_finished
@ mr_finished
Definition: cfanim.h:46
is
And the skill structure used by the skills[] table is
Definition: arch-handbook.txt:577
initteleport
static long int initteleport(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:372
buf
StringBuffer * buf
Definition: readable.cpp:1552
get_boolean
static int get_boolean(const char *strg, int *bl)
Definition: cfanim.cpp:758
find_by_name
static object * find_by_name(object *origin, const char *name)
Definition: cfanim.cpp:825
CFanimation::name
char * name
Definition: cfanim.h:69
reporting
Install Bug reporting Credits but rather whatever guild name you are using *With the current map and server there are three they and GreenGoblin *Whatever name you give the folder should but it will still use GUILD_TEMPLATE *You can change what guild it uses by editing the map files Modify Map or objects if you want to use the optional Python based Guild Storage hall The first three are on the main the next two are in the guild_hq and the final one is in hallofjoining Withe the Storage three objects are found on the main floor and the last two are in the basement It s not that but you will need a map editor You find the object that has the click edit and change the line script options(which currently is "GUILD_TEMPALTE") to the guild you wish to use. And make sure you use the same one for all of them or it won 't work. Here 's a quick HOWTO for using the map editor to make these changes edit the mainfloor map you will need to update the exit path in this map as well the exit is found at the bottom of the players may not be able to enter the guild hall map or they may exit out to some other location in the game Bug reporting
Definition: README.txt:84
HUGE_BUF
#define HUGE_BUF
Definition: define.h:37
initvisible
static long int initvisible(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:156
rundropobject
static anim_move_result rundropobject(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:274
name
Plugin animator file specs[Config] name
Definition: animfiles.txt:4
FOR_BELOW_FINISH
#define FOR_BELOW_FINISH()
Definition: define.h:711
CFanimation::unique
int unique
Definition: cfanim.h:75
Note
Release notes for Crossfire This is see the Changelog file included with the software Major changes since but slower than players without that skill *weather system is hopefully fixed *misc bug fixes Once you have installed the you MUST download a map set Note
Definition: Release_notes.txt:32
object::y
int16_t y
Definition: object.h:335
Crossfire
TIPS on SURVIVING Crossfire is populated with a wealth of different monsters These monsters can have varying immunities and attack types In some of them can be quite a bit smarter than others It will be important for new players to learn the abilities of different monsters and learn just how much it will take to kill them This section discusses how monsters can interact with players Most monsters in the game are out to mindlessly kill and destroy the players These monsters will help boost a player s after he kills them When fighting a large amount of monsters in a single attempt to find a narrower hallway so that you are not being attacked from all sides Charging into a room full of Beholders for instance would not be open the door and fight them one at a time For there are several maps designed for them Find these areas and clear them out All throughout these a player can find signs and books which they can read by stepping onto them and hitting A to apply the book sign These messages will help the player to learn the system One more always keep an eye on your food If your food drops to your character will soon so BE CAREFUL ! NPCs Non Player Character are special monsters which have intelligence Players may be able to interact with these monsters to help solve puzzles and find items of interest To speak with a monster you suspect to be a simply move to an adjacent square to them and push the double ie Enter your and press< Return > You can also use say if you feel like typing a little extra Other NPCs may not speak to but display intelligence with their movement Some monsters can be and may attack the nearest of your enemies Others can be in that they follow you around and help you in your quest to kill enemies and find treasure SPECIAL ITEMS There are many special items which can be found in Crossfire
Definition: survival-guide.txt:45
autojail.who
who
Definition: autojail.py:3
runtrigger
static anim_move_result runtrigger(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:527
object::contr
struct player * contr
Definition: object.h:284
teleport
int teleport(object *teleporter, uint8_t tele_type, object *user)
Definition: move.cpp:204
CFanimation
Definition: cfanim.h:68
start_animation
static int start_animation(object *who, object *activator, object *event, const char *file, const char *message)
Definition: cfanim.cpp:868
disinfect.map
map
Definition: disinfect.py:4
oblinkpt::link
objectlink * link
Definition: object.h:461
EVENT_CLOCK
#define EVENT_CLOCK
Definition: events.h:40
cf_object_say
void cf_object_say(object *op, const char *msg)
Definition: plugin_common.cpp:1049
diamondslots.activator
activator
Definition: diamondslots.py:10
make_face_from_files.args
args
Definition: make_face_from_files.py:37
rotate-tower.result
bool result
Definition: rotate-tower.py:13
CF_PLUGIN
#define CF_PLUGIN
Definition: plugin_common.h:38
CFanimation::ghosted
int ghosted
Definition: cfanim.h:77
initfire
static long int initfire(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:94
CFmovement::parameters
void * parameters
Definition: cfanim.h:61
cf_map_insert_object_there
object * cf_map_insert_object_there(object *op, mapstruct *m, object *originator, int flag)
Definition: plugin_common.cpp:1315
CFanimationHook::funcinit
CFAnimInitFunc funcinit
Definition: cfanim.h:90
f_plug_api
void(* f_plug_api)(int *type,...)
Definition: plugin.h:79
of
a copper bar weighs and has a value of
Definition: ore.txt:3
is_animated_object
static int is_animated_object(const object *ob)
Definition: cfanim.cpp:789
SvnRevPlugin
CF_PLUGIN char SvnRevPlugin[]
Definition: cfanim.cpp:40
runpickup
static anim_move_result runpickup(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:293
FOR_OB_AND_BELOW_FINISH
#define FOR_OB_AND_BELOW_FINISH()
Definition: define.h:754
oblinkpt::value
long value
Definition: object.h:462
cf_init_plugin
int cf_init_plugin(f_plug_api getHooks)
Definition: plugin_common.cpp:146
object::below
object * below
Definition: object.h:295
first_animation
static CFanimation * first_animation
Definition: cfanim.cpp:42
PLUGIN_NAME
#define PLUGIN_NAME
Definition: cfanim.h:32
compareAnims
static int compareAnims(const void *a, const void *b)
Definition: cfanim.cpp:616
get_dir_from_name
static int get_dir_from_name(const char *name)
Definition: cfanim.cpp:51
CFanimation::invisible
int invisible
Definition: cfanim.h:73
runpickupobject
static anim_move_result runpickupobject(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:311
time_tick
@ time_tick
Definition: cfanim.h:41
initmovement
static long int initmovement(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:71
Ice.b
b
Definition: Ice.py:48
equality_split
static int equality_split(char *buffer, char **variable, char **value)
Definition: cfanim.cpp:727
Windows
How to Install a Crossfire Server on Windows
Definition: INSTALL_WIN32.txt:5
guild_questpoints_apply.mapname
mapname
Definition: guild_questpoints_apply.py:8
object::type
uint8_t type
Definition: object.h:348
cf_object_clone
object * cf_object_clone(object *op, int clonetype)
Definition: plugin_common.cpp:683
message
TIPS on SURVIVING Crossfire is populated with a wealth of different monsters These monsters can have varying immunities and attack types In some of them can be quite a bit smarter than others It will be important for new players to learn the abilities of different monsters and learn just how much it will take to kill them This section discusses how monsters can interact with players Most monsters in the game are out to mindlessly kill and destroy the players These monsters will help boost a player s after he kills them When fighting a large amount of monsters in a single attempt to find a narrower hallway so that you are not being attacked from all sides Charging into a room full of Beholders for instance would not be open the door and fight them one at a time For there are several maps designed for them Find these areas and clear them out All throughout these a player can find signs and books which they can read by stepping onto them and hitting A to apply the book sign These messages will help the player to learn the system One more always keep an eye on your food If your food drops to your character will soon so BE CAREFUL ! NPCs Non Player Character are special monsters which have intelligence Players may be able to interact with these monsters to help solve puzzles and find items of interest To speak with a monster you suspect to be a simply move to an adjacent square to them and push the double ie Enter your message
Definition: survival-guide.txt:34
script
Install Bug reporting Credits but rather whatever guild name you are using *With the current map and server there are three they and GreenGoblin *Whatever name you give the folder should but it will still use GUILD_TEMPLATE *You can change what guild it uses by editing the map files Modify Map or objects if you want to use the optional Python based Guild Storage hall The first three are on the main the next two are in the guild_hq and the final one is in hallofjoining Withe the Storage three objects are found on the main floor and the last two are in the basement It s not that but you will need a map editor You find the object that has the script
Definition: README.txt:19
Python
pluglist shows those as well as a short text describing each the list will simply appear empty The keyword for the Python plugin is Python plugout< keyword > Unloads a given identified by its _keyword_ So if you want to unload the Python you need to do plugout Python plugin< libname > Loads a given whose _filename_ is libname So in the case of Python
Definition: plugins.txt:20
CFmovement::tick
int tick
Definition: cfanim.h:63
counterspell
void counterspell(object *op, int dir)
Definition: spell_effect.cpp:2909
CFAPI_MAP_PROP_PATH
#define CFAPI_MAP_PROP_PATH
Definition: plugin.h:247
param_moveto::y
int y
Definition: cfanim.cpp:456
maps
this information may not reflect the current implementation This brief document is meant to describe the operation of the crossfire as well as the form of the data The metaserver listens on port for tcp and on port for udp packets The server sends updates to the metaserver via udp The metaserver only does basic checking on the data that server sends It trusts the server for the ip name it provides The metaserver does add the ip address and also tracks the idle time(time since last packet received). The client gets its information from the metaserver through connecting by means of tcp. The client should retrieve http the body s content type is text plain The current metaserver implementation is in Perl But the metaserver could be in any language perl is fast enough for the amount of data that is being exchanged The response includes zero or more server entries Each entry begins with the line START_SERVER_DATA and ends with the line END_SERVER_DATA Between these lines key value pairs("key=value") may be present. The entries are sent in arbitrary order. A client should apply some ordering when displaying the entries to the user. TODO b additional information outside BEGIN_SERVER_DATA END_SERVER_DATA maps
Definition: arch-handbook.txt:189
spell
with a maximum of six This is not so if you are wearing plate you receive no benefit Armour is additive with all the supplementry forms of which means that it lasts until the next semi permanent spell effect is cast upon the character spell
Definition: tome-of-magic.txt:44
CFanimationHook::name
const char * name
Definition: cfanim.h:89
inittrigger
static long int inittrigger(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:515
FLAG_WIZPASS
#define FLAG_WIZPASS
Definition: define.h:314
effects
the faster the spell may be cast there are several other common only the caster may be affected by the spell The most common spell range is that of touch This denotes that the caster much touch the recipient of the spell in order to release the spell effects(as for "self", the caster may cast the spell on himself). A "special" range for missile spells indicates that the spell will last until it impacts an object(a PC
initmessage
static long int initmessage(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:496
CFanimation::verbose
int verbose
Definition: cfanim.h:76
disinfect.count
int count
Definition: disinfect.py:7
cf_map_message
void cf_map_message(mapstruct *m, const char *msg, int color)
Definition: plugin_common.cpp:667
CFanimation::delete_end
int delete_end
Definition: cfanim.h:79
animate.anim
string anim
Definition: animate.py:20
FOR_OB_AND_BELOW_PREPARE
#define FOR_OB_AND_BELOW_PREPARE(op_)
Definition: define.h:750
runnotice
static anim_move_result runnotice(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:428
CFmovement
Definition: cfanim.h:58
cf_object_drop
void cf_object_drop(object *op, object *author)
Definition: plugin_common.cpp:1043
nlohmann::detail::void
j template void())
Definition: json.hpp:4099
CFanimation::victim
object * victim
Definition: cfanim.h:70
teleport_params
Definition: cfanim.cpp:366
getPluginProperty
CF_PLUGIN void * getPluginProperty(int *type,...)
Definition: cfanim.cpp:1218
runmovement
static anim_move_result runmovement(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:80
cf_free_string
void cf_free_string(sstring str)
Definition: plugin_common.cpp:1182
anim_move_result
anim_move_result
Definition: cfanim.h:45
CFanimation::errors_allowed
int errors_allowed
Definition: cfanim.h:78
MAX_BUF
#define MAX_BUF
Definition: define.h:35
cf_object_find_by_name
object * cf_object_find_by_name(const object *who, const char *name)
Definition: plugin_common.cpp:605
cf_object_pickup
void cf_object_pickup(object *op, object *what)
Definition: plugin_common.cpp:1434
initdropobject
static long int initdropobject(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:267
initapplyobject
static long int initapplyobject(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:236
runapplyobject
static anim_move_result runapplyobject(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:242
to
**Media tags please refer to the protocol file in doc Developers protocol Quick for your pleasure an example[/b][i] This is an old full of dirt and partially destroyed[hand] My dear as you two years i had to leave quickly Words have come to me of powerful magic scrolls discovered in an old temple by my uncle I have moved to study them I not forgot your knowledge in ancient languages I need your help for[print][b] Some parts of document are to damaged to be readable[/b][arcane] Arghis[color=Red] k h[color=dark slate blue] ark[color=#004000] fido[/color][hand] please come as fast as possible my friend[print][b] The bottom of letter seems deliberatly shredded What is but not limited to
Definition: media-tags.txt:30
FOR_MAP_PREPARE
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:723
time_second
@ time_second
Definition: cfanim.h:40
PLUGIN_VERSION
#define PLUGIN_VERSION
Definition: cfanim.h:33
cf_object_move
int cf_object_move(object *op, int dir, object *originator)
Definition: plugin_common.cpp:531
create_animation
static CFanimation * create_animation(void)
Definition: cfanim.cpp:803
cf_system_register_global_event
void cf_system_register_global_event(int event, const char *name, f_plug_event hook)
Definition: plugin_common.cpp:1102
FLAG_WIZ
#define FLAG_WIZ
Definition: define.h:231
altar_valkyrie.altar
altar
Definition: altar_valkyrie.py:27
NDI_UNIQUE
#define NDI_UNIQUE
Definition: newclient.h:251
parameters
The preferred style of formal parameters
Definition: style-guide.txt:209
object::name
sstring name
Definition: object.h:319
bigchest.check
check
Definition: bigchest.py:10
report
Definition: report.py:1
CFmovement::func
CFAnimRunFunc func
Definition: cfanim.h:60
always
Crossfire Protocol most of the time after the actual code was already omit certain important and possibly make life miserable any new developer or curious player should be able to find most of the relevant information here If inconsistencies are found or this documentation proves to be consider the latest server side protocol code in the public source code repository as the authoritative reference Introduction If you were ever curious enough to telnet or netcat to a Crossfire chances are you were sorely disappointed While the protocol may seem to use plain text at it actually uses a mix of ASCII and binary data This handbook attempts to document various aspects of the Crossfire protocol As always
Definition: protocol.txt:23
players
std::vector< archetype * > players
Definition: player.cpp:493
cf_map_trigger_connected
void cf_map_trigger_connected(objectlink *ol, object *cause, int state)
Definition: plugin_common.cpp:1028
reputation.victim
victim
Definition: reputation.py:14
CFanimationHook
Definition: cfanim.h:88
runstop
static anim_move_result runstop(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:446
mapstruct
Definition: map.h:314
cf_object_set_flag
void cf_object_set_flag(object *ob, int flag, int value)
Definition: plugin_common.cpp:1288
object::env
object * env
Definition: object.h:301
install
Install Bug reporting Credits so make sure you have version or later There are files involved in the automatic install
Definition: README.txt:7
postInitPlugin
CF_PLUGIN int postInitPlugin(void)
Definition: cfanim.cpp:1252
sstring
const typedef char * sstring
Definition: sstring.h:2
give.op
op
Definition: give.py:33
autojail.value
value
Definition: autojail.py:6
metaserver
this information may not reflect the current implementation This brief document is meant to describe the operation of the crossfire metaserver
Definition: arch-handbook.txt:130
animationcount
int animationcount
Definition: cfanim.cpp:612
initpickup
static long int initpickup(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:286
convert.dest
dest
Definition: convert.py:25
teleport_params::mapy
int mapy
Definition: cfanim.cpp:369
cfanim.h
CFanimation::tick_left
long int tick_left
Definition: cfanim.h:81
are
non standard information is not specified or uptime this means how long since the executable has been started A particular host may have been running a server for quite a long but due to updates or the length of time the server instance has been up may be much shorter MN US< br > link< br >< a href="http: text_comment=Latest SVN 1.x branch, Eden Prairie, MN US archbase=Standard mapbase=Standard codebase=Standard num_players=3 in_bytes=142050710 out_bytes=-1550812829 uptime=909914 version=1.11.0 sc_version=1027 cs_version=1023 last_update=1214541369 END_SERVER_DATA ---- Multigod -------- This is a brief description of the MULTIGOD hack. It is preserved here for mostly historical reasons. Introduction ~~~~~~~~~~~~ The intention of this code is to enhance the enjoy-ability and playability of clerical characters in the new skills/exp scheme. This is done by giving players gods to worship who in turn effect clerical magic and powers. Included in this patch are several new spells which (hopefully) will allow the priest characters a better chance to gain xp at higher levels. Notably, the "holy orb" and "holy word" spells have been revamped. When MULTIPLE_GODS flag is defined in include/config.h, this code is enabled. This code (described below) encompasses 3 main parts: an array of gods that players/NPCs may worship, new clerical spells which rely on the worshiped god's attrib- utes in Gods[] array and, altars/praying--the interface between a worshiper and their god. b.t. thomas@astro.psu.edu Implementation Details ~~~~~~~~~~~~~~~~~~~~~~ This code is flexible and easy to configure (just edit the god archetypes). Part of the reason for creating this code was to allow server maintainers to develop their own "mythos". From my personal point of view, I hate having the old "Christian" aligned mythos, but if that's what you like, you can replicate it with this code too (see below). Properties of the Gods ~~~~~~~~~~~~~~~~~~~~~~ Here is a fuller description of Gods archetype values. ---- name - name of the god (required) other_arch - archetype that will be used for the summon holy servant spell. title - diametrically opposed god, leave blank if none exists attacktype - favored attack of this god, used in spells of summon avatar, holy word. Recipients of "holy possession" get this too. immune - Avatars/holy servants/recipient of "holy possession" gets this. protected - all of the above AND recipient of god's blessing and the priest of this god gets this. vulnerable - Avatar/servant/recipient of gods curse/priest of this god get this. path_attuned - priest of this god and recipient of "bless" gets this path_repelled - priest and recipient of "curse" gets this path_denied - priest and recipient of "curse" gets this slaying - comma delimited list of the races of creatures that are aligned with the god. "summon cult monsters" uses. this list to find creatures. Summon avatar/call servant code assigns this value to prevent them from attacking aligned races. Value is blank if no race(s) exists. race - comma delimited list of the races of creatures "holy word", "holy possession" spells will effect. Value entry is blank if no such race(s) exists. hp,dam,ac,wc - base stats for the summoned avatar. ---- IF MORE_PRIEST_GIFTS is defined (in gods.c) then ADDITIONAL gifts/limitations will be assigned to the priest: Flags ^^^^^ Now, the following flags, in addition to being used by the god (if planted on a map) are assigned to the worshiping priest: can_use_weapon, can_use_armour, is_undead, is_blind, reflect_missile, reflect_spell, make_invisible, stealth, can_see_in_dark, xrays NOTE: if can_use_armour/can_use_weapon flags are NOT present, then the priest will be forbidden the use of these items. Stats ^^^^^ The following stats are used: ---- luck - how lucky the god (and the priest) are. last_eat - how fast priest digestion is last_hp - how fast priest healing is last_sp - how fast priest mana regeneration is last_grace - how fast priest grace regeneration is ---- Designing New Gods ~~~~~~~~~~~~~~~~~~ To examine the gods properties, use the '-m8' flag (ie 'crossfire -m8'). Note some of the big differences here in terms of spell_paths, races, etc. Most of these entries were designed with roughly polar opposite gods. For designing new gods. You should make sure that worshiping a god will be "unique" in some way. But playbalance first! You must consider the balance between the following: . spellpaths . priest gifts . priest limitations . special spells . attacktypes . summoned monster lists . properties of the avatar and holy servant. Here are some hard and fast rules for designing gods: - Decide how the cleric will get experience. The god should be either a 'summoning', 'turning' *or* a 'wounding' god. If summoning/turning, make sure the aligned_race/enemy_race list(s) has enough creatures to summon/slay at low, medium and high levels. DONT give a god attuned to wounding AND turning||summoning (in fact, at minimum, one of these 3 paths should be repelled/denied). - make sure the summoned avatar is stronger than the servant (!) - examine the avatar/servant stats. If set inproperly, you will give wimpy/super values. For example, Avatars/servants with less than 50 hp (and a high ac/no armour) will vanish quickly. Shoot for stats like: ---- type | A V E R A G E S T A T S | hp | ac | wc | arm | dam | speed ----------|----------------------------------- servant | 50 | 5 | 5 | 20 | 5 | 0.15 avatar | 350 | -5 | -1 | 50 | 50 | 0.25 ---- Its difficult to give measurements on how to trade these off. To help guide your choices try to conserve the value of speed*dam and (armour+1)*hp. * avoid giving the potent attacktypes of death, weaponmagic and paralysis. * gods have a vulnerability for every immunity. Not all attacktypes are the same. Immunity to physical, magic and common attacktypes (like fire/cold/electric) are very potent. Similarly, vuln to these is a big negative. * SPELL paths. Carefull treatment is needed here. Give a path_denied/ or a couple path_repelled for every path_attuned. BUT note: not all paths are of equal use. (ex path_abjuration has a very large list of spells). The main clerical paths are restoration, abjuration, protection, turning, wounding and summoning. For balance, make 3-4 of these repelled/denied and 1 or 2 attuned. Be sure to check out the special spells list (below). Attuned paths like DEATH, WOUNDING and (especially) PROTECTION are very potent. Allow for some balance else where if you assign (one!) of these as a path_attuned. * If using the MORE_PRIEST_GIFTS define: priest limitations of no weapons and no armour are very negative, be sure to compensate with more than an attunded path. Of course, you may break these 'rules' to create your god. When you do that, you had better make up for the bonus elsewhere! Otherwise, you will create a 'mega-god' whose worship (by the player priests) will unbalance the game. Designing a good god takes a bit of work. Special Spells ~~~~~~~~~~~~~~ Here is a possibly *incomplete* list of the special spells that a god may grant use to a worshiper. Check the file spellist.h for the 0 bookchance clerical spells to find all of these. (This list was complete on 10/96). ---- INFO perceive self PROTECTION defense; immuntity to cold, fire, electricity, poison, slow, paralysis, draining, attack, and magic RESTORE remove damnation; reincarnation; raise dead; resurrection; regeneration WOUNDING cause critical wounds; retributive strike LIGHT daylight; nightfall DEATH face of death; finger of death SUMMONING insect plague CREATE wall of thorns ---- Ideas ~~~~~ * Allow sacrifices. This is an excellent way to give a cleric xp. Need to create enemy_race creatures w/ bodyparts we can sacrifice, and designate a pointer in Gods to the appropriate array of stuff we can sacrifice for xp. Experience ---------- Obsolete file kept for historical reasons. Introduction ~~~~~~~~~~~~ This patch represents a "developer 's" version of the exp/skills system. While I have now achieved all of the objectives in sections "B" and "C" of the coding proposal (see README.PROPOSAL) and have play-tested as much of the code as possible, I am sure some big bugs must remain. (One for sure is that exp gained when using rod/horn/wand is wrong.) Below this section I outline 1) coding philosophy, 2) gross description of how the code impinges/interacts within older code. 3) designer's notes on the changes to the code. Comments on any area of this coding would be appreciated. Personally, I would like to see the Pow stat and a 2-type system of magic come into being. After all of you check out the code, I would like to discuss enhancements/bug fixes/implementation. For instance, is it too hard to figure out how to use the code! Sometime tomorrow exp2.tar.gz will be available in pub/thomas on ftp.astro.psu.edu. b.t. Code Philosophy ^^^^^^^^^^^^^^^ To move CF over to a new skills-based experience system. In this implementation several kinds of experience will exist. Players will gain experience in each kind of experience (or category) based on their actions in the game. The sum of all the various categories of experience equals the player "score", from which dam, wc, and hp are determined. All experience gaining actions will be through the use of certain skills -- so called "associated skills". Associated skills are each related to 1 kind of experience. Thus, for example, "stealing" is a skill associated with "agility" experience. There exists also "miscellaneous" skills which allow the use of a unique skill, but which are not related to any kind of experience and whose use does not generate experience points. In this implementation, skills and objects are both treated as objects in the inventory of the user. Experience "objects" each represent one kind of experience and are always invisible. Skills objects each represent one kind of skill available in the game. Skills objects may either be invisible or have an associated bitmap (in which case they are "tools"). All experience gaining actions will be through the use of certain skills -- called "associated skills". Associated skills are each related to 1 kind of experience. Thus, for example, "stealing" is a skill associated with "agility" experience. Both Players and NPC's may only use skills which are in their inventories. NPC's do not use experience objects. A breakdown of the properties of skills and exp objects objects is as follows: ---- Object Property NPC use? ------ ----------------------------------- ------- Experience Each represents a different kind of NO experience in the game. The object in the player inventory keeps track of player experience in that category. Always is invisible. Skill- Represents a skill the player may YES associated perform. May be either invisible or visible as a "tool". Successful use of this skill generates experience. Experience is allocated to appropriate experience object. Skill- Same as above, *but* this skill is not YES miscell. related to any experience category, and use of this skill generates *no* experience. ---- Linking of associated skills to experience categories is done during initialization of the code (in init()) based on the shared stats of both. How skills and experience categories are named and linked may be changed by editing the skills/experience object archetypes. Implementation Details ~~~~~~~~~~~~~~~~~~~~~~ The most important thing is that I moved most of the code into the server/skills.c and server/skill_util.c files. The skills code is loosely implemented along the lines of the spell code. This is to say that: . skills use (do_skill) is called from fire(). . there is a skills[] table similar to spells[]. . server files skills.c and skill_util.c parallel spell_effect.c and spell_util.c in respective functionallity. Particular notes about the implementation are outlined below. Defines ^^^^^^^ #define MAX_EXP_CAT be > I had to make use of several global parameters These are
Definition: arch-handbook.txt:525
objects
object * objects
Definition: object.cpp:294
roll-o-matic.params
params
Definition: roll-o-matic.py:193
get_command
static CFanimationHook * get_command(char *command)
Definition: cfanim.cpp:625
diamondslots.y
y
Definition: diamondslots.py:16
python_pickup.where
where
Definition: python_pickup.py:7
cf_get_maps_directory
char * cf_get_maps_directory(const char *name, char *buf, int size)
Definition: plugin_common.cpp:1069
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
Also
Crossfire Protocol most of the time after the actual code was already omit certain important and possibly make life miserable any new developer or curious player should be able to find most of the relevant information here If inconsistencies are found or this documentation proves to be consider the latest server side protocol code in the public source code repository as the authoritative reference Introduction If you were ever curious enough to telnet or netcat to a Crossfire chances are you were sorely disappointed While the protocol may seem to use plain text at it actually uses a mix of ASCII and binary data This handbook attempts to document various aspects of the Crossfire protocol As consult the README file to find out how to get in touch with helpful people via mailing and more History the communications plan was set to be a text based system It was up to the server and client to parse these messages and determine what to do These messages were assumed to be line per message At a reasonably early stage of Eric Anderson wrote a then the data itself you could send many data and after the other end could decode these commands This works fairly but I think the creation of numerous sub packets has some performance hit Also
Definition: protocol.txt:40
version
Release notes for Crossfire This is see the Changelog file included with the software Major changes since version
Definition: Release_notes.txt:20
http
Release notes for Crossfire This is see the Changelog file included with the software Major changes since but slower than players without that skill *weather system is hopefully fixed *misc bug fixes Once you have installed the you MUST download a map set point to where you installed Crossfire install Grab map set from official SourceForge page The following sets are at http
Definition: Release_notes.txt:40
runturn
static anim_move_result runturn(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:120
teleport_params::mapx
int mapx
Definition: cfanim.cpp:368
runapply
static anim_move_result runapply(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:222
nlohmann::detail::get
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:4475
cfanim_globalEventListener
CF_PLUGIN int cfanim_globalEventListener(int *type,...)
Definition: cfanim.cpp:1260
create-tower.tile
tile
Definition: create-tower.py:8
CFmovement::parent
struct CFanimation * parent
Definition: cfanim.h:59
initstop
static long int initstop(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:438
runfire
static anim_move_result runfire(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:104
CFanimation::event
object * event
Definition: cfanim.h:71
runvisible
static anim_move_result runvisible(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:167
initturn
static long int initturn(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:111
CFmovement::next
CFmovement * next
Definition: cfanim.h:64
object::container
object * container
Definition: object.h:299
skill
skill
Definition: arch-handbook.txt:585
param_moveto::x
int x
Definition: cfanim.cpp:456
first
Crossfire Protocol most of the time after the actual code was already omit certain important and possibly make life miserable any new developer or curious player should be able to find most of the relevant information here If inconsistencies are found or this documentation proves to be consider the latest server side protocol code in the public source code repository as the authoritative reference Introduction If you were ever curious enough to telnet or netcat to a Crossfire chances are you were sorely disappointed While the protocol may seem to use plain text at first
Definition: protocol.txt:20
a
Magical Runes Runes are magical inscriptions on the dungeon which cast a spell or detonate when something steps on them Flying objects don t detonate runes Beware ! Runes are invisible most of the time They are only visible occasionally ! There are several runes which are there are some special runes which may only be called with the invoke and people may apply it to read it Maybe useful for mazes ! This rune will not nor is it ordinarily invisible Partial Visibility of they ll be visible only part of the time They have a(your level/2) chance of being visible in any given round
UP_OBJ_CHANGE
#define UP_OBJ_CHANGE
Definition: object.h:523
animate.event
event
DIALOGCHECK MINARGS 1 MAXARGS 2
Definition: animate.py:17
cf_player_message
void cf_player_message(object *op, const char *txt, int flags)
Definition: plugin_common.cpp:787
initcamera
static long int initcamera(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:134
cf_map_get_map
mapstruct * cf_map_get_map(const char *name, int flags)
Definition: plugin_common.cpp:935
now
Crossfire Protocol most of the time after the actual code was already omit certain important and possibly make life miserable any new developer or curious player should be able to find most of the relevant information here If inconsistencies are found or this documentation proves to be consider the latest server side protocol code in the public source code repository as the authoritative reference Introduction If you were ever curious enough to telnet or netcat to a Crossfire chances are you were sorely disappointed While the protocol may seem to use plain text at it actually uses a mix of ASCII and binary data This handbook attempts to document various aspects of the Crossfire protocol As consult the README file to find out how to get in touch with helpful people via mailing and more History the communications plan was set to be a text based system It was up to the server and client to parse these messages and determine what to do These messages were assumed to be line per message At a reasonably early stage of Eric Anderson wrote a then the data itself you could send many data and after the other end could decode these commands This works fairly but I think the creation of numerous sub packets has some performance hit the eutl was not especially well so writing a client for a different platform became more Eric left to work on other products shortly after writing his which didn t really leave anyone with a full understanding of the socket code I have decided to remove the eutl dependency At least one advantage is that having this network related code directly in the client and server makes error handling a bit easier cleaner Packet Format the outside packet method the byte size for the size information is not included here Eutl originally used bytes for the size to bytes seems it makes a least some sense The actual data is something of the nature of the commands listed below It is a text followed by possible other data The remaining data can be binary it is up to the client and server to decode what it sent The commands as described below is just the data portion of the packet If writing a new remember that you must take into account the size of the packet There is no termination of other than knowing how long it should be For now
Definition: protocol.txt:71
animate
static void animate(void)
Definition: cfanim.cpp:1158
initpickupobject
static long int initpickupobject(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:305
connection
Definition: connection.py:1
cf_object_update
void cf_object_update(object *op, int flags)
Definition: plugin_common.cpp:1428
teleport_params::mapname
char * mapname
Definition: cfanim.cpp:367
CFmovement::id
long int id
Definition: cfanim.h:62
svnversion.h
cf_object_remove
void cf_object_remove(object *op)
Definition: plugin_common.cpp:562
CFanimation::corpse
object * corpse
Definition: cfanim.h:80
plugin
pluglist shows those as well as a short text describing each the list will simply appear empty The keyword for the Python plugin is Python plugout< keyword > Unloads a given plugin
Definition: plugins.txt:15
available
Release notes for Crossfire This is see the Changelog file included with the software Major changes since but slower than players without that skill *weather system is hopefully fixed *misc bug fixes Once you have installed the you MUST download a map set point to where you installed Crossfire install Grab map set from official SourceForge page The following sets are available
Definition: Release_notes.txt:38
replace.current
current
Definition: replace.py:64
parse_animation_block
static CFmovement * parse_animation_block(char *buffer, size_t buffer_size, FILE *fichier, CFanimation *parent)
Definition: cfanim.cpp:642
CFanimation::time_representation
enum time_enum time_representation
Definition: cfanim.h:82
if
if(!(yy_init))
Definition: loader.c:2626
have
**Media tags please refer to the protocol file in doc Developers protocol Quick for your pleasure an example[/b][i] This is an old full of dirt and partially destroyed[hand] My dear as you two years i had to leave quickly Words have come to me of powerful magic scrolls discovered in an old temple by my uncle I have moved to study them I have
Definition: media-tags.txt:19
Server
Release notes for Crossfire This is see the Changelog file included with the software Major changes since but slower than players without that skill *weather system is hopefully fixed *misc bug fixes Once you have installed the you MUST download a map set point to where you installed Crossfire Server
Definition: Release_notes.txt:32
cf_map_get_width
int cf_map_get_width(mapstruct *map)
Definition: plugin_common.cpp:1400
initPlugin
CF_PLUGIN int initPlugin(const char *iversion, f_plug_api gethooksptr)
Definition: cfanim.cpp:1208
runcamera
static anim_move_result runcamera(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:144
animationbox
CFanimationHook animationbox[]
Definition: cfanim.cpp:562
llevDebug
@ llevDebug
Definition: logger.h:13
is_valid_types_gen.type
list type
Definition: is_valid_types_gen.py:25
CFanimation::nextanimation
CFanimation * nextanimation
Definition: cfanim.h:84
CFanimation::paralyze
int paralyze
Definition: cfanim.h:72
runmessage
static anim_move_result runmessage(CFanimation *animation, long int id, void *parameters)
Definition: cfanim.cpp:505
initghosted
static long int initghosted(const char *name, char *parameters, CFmovement *move_entity)
Definition: cfanim.cpp:325
usec_elapsed
long usec_elapsed(struct timespec first, struct timespec second)
Definition: cfanim.cpp:1149
work
vs only yadda is in because all tags get reset on the next draw_ext_info In the second since it is all in one everything is bold How does it work
Definition: media-tags.txt:65
diamondslots.id
id
Definition: diamondslots.py:53