ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/plugins/cfanim/cfanim.c
Revision: 1.6
Committed: Sun Aug 13 17:16:02 2006 UTC (17 years, 9 months ago) by elmex
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +0 -0 lines
State: FILE REMOVED
Log Message:
Made server compile with C++.
Removed cfanim plugin and crossedit.
C++ here we come.

File Contents

# Content
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 <cfanim.h>
33 #include <stdarg.h>
34
35 f_plug_api gethook;
36 f_plug_api registerGlobalEvent;
37 f_plug_api unregisterGlobalEvent;
38 f_plug_api systemDirectory;
39 f_plug_api reCmp;
40
41 CFPContext* context_stack;
42 CFPContext* current_context;
43 CFanimation *first_animation=NULL;
44
45 int get_dir_from_name (char*name)
46 {
47 if (!strcmp(name,"north")) return 1;
48 if (!strcmp(name,"north_east")) return 2;
49 if (!strcmp(name,"east")) return 3;
50 if (!strcmp(name,"south_east")) return 4;
51 if (!strcmp(name,"south")) return 5;
52 if (!strcmp(name,"south_west")) return 6;
53 if (!strcmp(name,"west")) return 7;
54 if (!strcmp(name,"north_west")) return 8;
55 return -1;
56 }
57
58 long int initmovement(char* name,char* parameters, struct CFmovement_struct* move_entity)
59 {
60 int dir;
61 dir=get_dir_from_name (name);
62 move_entity->parameters=NULL;
63 return dir;
64 }
65 int runmovement(struct CFanimation_struct* animation, long int id, void* parameters)
66 {
67 object* op=animation->victim;
68 int dir=id;
69 printf ("CFAnim: Moving in direction %ld\n",id);
70 if (op->type==PLAYER)
71 cf_player_move(op->contr,dir);
72 else
73 cf_object_move(op,dir,op);
74 return 1;
75 }
76
77 long int initfire(char* name,char* parameters,struct CFmovement_struct* move_entity)
78 {
79 int dir;
80 dir=get_dir_from_name(&(name[5]));
81 move_entity->parameters=NULL;
82 return dir;
83 }
84
85 int runfire(struct CFanimation_struct* animation, long int id, void* parameters)
86 {
87 printf ("CFAnim: Firing in direction %ld\n",id);
88 return 1;
89 }
90
91 long int initturn(char* name,char* parameters,struct CFmovement_struct* move_entity)
92 {
93 int dir;
94 dir=get_dir_from_name (&(name[5]));
95 move_entity->parameters=NULL;
96 return dir;
97 }
98
99 int runturn(struct CFanimation_struct* animation, long int id, void* parameters)
100 {
101 object* op=animation->victim;
102 int dir=id;
103 int face;
104 printf ("CFAnim: Turning in direction %ld\n",id);
105 op->facing=dir;
106 cf_object_set_int_property(op,CFAPI_OBJECT_ANIMATION,face);
107 return 1;
108 }
109
110 long int initcamera(char* name,char* parameters,struct CFmovement_struct* move_entity)
111 {
112 int dir;
113 dir=get_dir_from_name (&(name[7]));
114 move_entity->parameters=NULL;
115 return dir;
116 }
117 int runcamera(struct CFanimation_struct* animation, long int id, void* parameters)
118 {
119 printf ("CFAnim: Moving the camera in direction %ld\n",id);
120 return 1;
121 /*if (animation->victim->type==PLAYER)
122 hook_scroll_map(animation->victim,id);
123 else printf ("CFAnim: Not a player\n");
124 return 1;*/
125 }
126
127 long int initvisible (char* name, char* parameters, struct CFmovement_struct* move_entity)
128 {
129 int result;
130 if (get_boolean (parameters,&result))
131 return result;
132 printf ("CFAnim: Error in animation - possible values for 'invisible' are 'yes' and 'no'\n");
133 return -1;
134 }
135 int runvisible(struct CFanimation_struct* animation, long int id, void* parameters)
136 {
137 if (id==-1)
138 return 1;
139 animation->invisible=id;
140 return 1;
141 }
142
143 long int initwizard (char* name, char* parameters, struct CFmovement_struct* move_entity)
144 {
145 int result;
146 if (get_boolean (parameters,&result))
147 return result;
148 printf ("CFAnim: Error in animation - possible values for 'wizard' are 'yes' and 'no'\n");
149 return -1;
150 }
151 int runwizard(struct CFanimation_struct* animation, long int id, void* parameters)
152 {
153 if (id==-1)
154 return 1;
155 animation->wizard=id;
156 return 1;
157 }
158 long int initsay (char* name, char* parameters, struct CFmovement_struct* move_entity)
159 {
160 if (parameters)
161 move_entity->parameters=cf_strdup_local (parameters);
162 else
163 move_entity->parameters=NULL;
164 printf ("CFAnim: init say: parameters: %p\n",parameters);
165 return 1;
166 }
167 int runsay(struct CFanimation_struct* animation, long int id, void* parameters)
168 {
169 if (parameters)
170 {
171 cf_object_speak(animation->victim, parameters);
172 free (parameters);
173 }
174 else
175 printf ("CFAnim: Error in animation: nothing to say with say function\n");
176 return 1;
177 }
178 long int initapply (char* name, char* parameters, struct CFmovement_struct* move_entity)
179 {
180 return 1;
181 }
182 int runapply(struct CFanimation_struct* animation, long int id, void* parameters)
183 {
184 object* current_container;
185 if (animation->victim->type!=PLAYER)
186 return 0;
187 current_container=animation->victim->container;
188 animation->victim->container=NULL;
189 cf_object_apply_below(animation->victim);
190 animation->victim->container=current_container;
191 return 1;
192 }
193 long int initapplyobject (char* name, char* parameters, struct CFmovement_struct* move_entity)
194 {
195 move_entity->parameters=parameters?cf_add_string(parameters):NULL;
196 return 1;
197 }
198 int runapplyobject(struct CFanimation_struct* animation, long int id, void* parameters)
199 {
200 object* current;
201 int aflag;
202
203 if (!parameters)
204 return 0;
205 for (current=animation->victim->below;current;current=current->below)
206 if(current->name==parameters) break;
207 if (!current)
208 for (current=animation->victim->inv;current;current=current->below)
209 if(current->name==parameters) break;
210 if (!current)
211 {
212 cf_free_string (parameters);
213 return 0;
214 }
215 aflag=AP_APPLY;
216 cf_object_apply(animation->victim, current, aflag);
217 cf_free_string(parameters);
218 return 1;
219 }
220
221 long int initdropobject (char* name, char* parameters, struct CFmovement_struct* move_entity)
222 {
223 move_entity->parameters=parameters?cf_strdup_local(parameters):NULL;
224 return 1;
225 }
226 int rundropobject(struct CFanimation_struct* animation, long int id, void* parameters)
227 {
228 if (!parameters)
229 return 0;
230 cf_object_drop(animation->victim, parameters);
231 cf_free_string(parameters);
232 return 1;
233 }
234
235 long int initpickup (char* name, char* parameters, struct CFmovement_struct* move_entity)
236 {
237 return 1;
238 }
239 int runpickup(struct CFanimation_struct* animation, long int id, void* parameters)
240 {
241 object* current;
242 current=animation->victim->below;
243 if (!current)
244 return 0;
245 cf_object_pickup(animation->victim, current);
246 return 1;
247 }
248
249 long int initpickupobject (char* name, char* parameters, struct CFmovement_struct* move_entity)
250 {
251 move_entity->parameters=parameters?cf_add_string(parameters):NULL;
252 return 1;
253 }
254 int runpickupobject(struct CFanimation_struct* animation, long int id, void* parameters)
255 {
256 object* current;
257 if (!parameters) return 0;
258 for (current=animation->victim->below;current;current=current->below)
259 if(current->name==parameters)
260 break;
261 if (current)
262 cf_object_pickup(animation->victim, current);
263 cf_free_string(parameters);
264 return 1;
265 }
266 long int initghosted (char* name, char* parameters, struct CFmovement_struct* move_entity)
267 {
268 int result;
269 if (get_boolean(parameters,&result))
270 return result;
271 printf ("CFAnim: Error in animation: possible values for 'ghosted' are 'yes' and 'no'\n");
272 return -1;
273 }
274 int runghosted(struct CFanimation_struct* animation, long int id, void* parameters)
275 {
276 object* corpse;
277
278 if ( (id && animation->ghosted) ||
279 (!id && !animation->ghosted) )
280 runghosted(animation, !id, parameters);
281 if (id) /*Create a ghost/corpse pair*/
282 {
283 corpse = cf_object_clone(animation->victim,1);
284 corpse->x=animation->victim->x;
285 corpse->y=animation->victim->y;
286 corpse->type=0;
287 corpse->contr=NULL;
288 cf_map_insert_object_there(animation->victim->map, corpse, NULL, 0);
289 animation->wizard=1;
290 animation->invisible=1;
291 animation->corpse=corpse;
292 }
293 else /*Remove a corpse, make current player visible*/
294 {
295 animation->wizard=0;
296 animation->invisible=0;
297 cf_object_remove(animation->corpse);
298 cf_object_free(animation->corpse);
299 animation->corpse=NULL;
300 animation->victim->invisible=0;
301 }
302 animation->ghosted=id;
303 return 1;
304 }
305
306 typedef struct
307 {
308 char* mapname;
309 int mapx;
310 int mapy;
311 }teleport_params;
312
313 long int initteleport (char* name, char* parameters, struct CFmovement_struct* move_entity)
314 {
315 char* mapname;
316 int mapx;
317 int mapy;
318 teleport_params* teleport;
319 move_entity->parameters=NULL;
320 printf (".(%s)\n",parameters);
321 if (!parameters)
322 {
323 printf ("CFAnim: Error - no parameters for teleport\n");
324 return 0;
325 }
326 mapname=strstr (parameters," ");
327 printf (".(%s)\n",parameters);
328 if (!mapname)
329 return 0;
330 *mapname='\0';
331 mapx=atoi(parameters);
332 mapname++;
333 parameters=mapname;
334 if (!parameters)
335 {
336 printf ("CFAnim: Error - not enough parameters for teleport\n");
337 return 0;
338 }
339 printf (".(%s)\n",parameters);
340 mapname=strstr (parameters," ");
341 printf (".\n");
342 if (!mapname)
343 return 0;
344 *mapname='\0';
345 mapy=atoi(parameters);
346 mapname++;
347 if (mapname[0]=='\0')
348 return 0;
349 teleport=(teleport_params*)malloc (sizeof(teleport_params));
350 teleport->mapname=cf_strdup_local (mapname);
351 teleport->mapx=mapx;
352 teleport->mapy=mapy;
353 move_entity->parameters=teleport;
354 return 1;
355 }
356 int runteleport(struct CFanimation_struct* animation, long int id, void* parameters)
357 {
358 teleport_params* teleport=(teleport_params*)parameters;
359 if (!parameters)
360 return 0;
361 cf_object_teleport(animation->victim, cf_map_get_map(teleport->mapname),
362 teleport->mapx, teleport->mapy);
363 free(parameters);
364 return 1;
365 }
366
367 long int initnotice (char* name, char* parameters, struct CFmovement_struct* move_entity)
368 {
369 move_entity->parameters=parameters?cf_strdup_local(parameters):NULL;
370 return 1;
371 }
372 int runnotice(struct CFanimation_struct* animation, long int id, void* parameters)
373 {
374 int val;
375
376 val = NDI_NAVY|NDI_UNIQUE;
377
378 cf_player_message(animation->victim, parameters, val);
379 return 1;
380 }
381
382
383 CFanimationHook animationbox[]=
384 {
385 {"north",initmovement,runmovement},
386 {"north_east",initmovement,runmovement},
387 {"east",initmovement,runmovement},
388 {"south_east",initmovement,runmovement},
389 {"south",initmovement,runmovement},
390 {"south_west",initmovement,runmovement},
391 {"west",initmovement,runmovement},
392 {"north_west",initmovement,runmovement},
393 {"fire_north",initfire,runfire},
394 {"fire_north_east",initfire,runfire},
395 {"fire_east",initfire,runfire},
396 {"fire_south_east",initfire,runfire},
397 {"fire_south",initfire,runfire},
398 {"fire_south_west",initfire,runfire},
399 {"fire_west",initfire,runfire},
400 {"fire_north_west",initfire,runfire},
401 {"turn_north",initturn,runturn},
402 {"turn_north_east",initturn,runturn},
403 {"turn_east",initturn,runturn},
404 {"turn_south_east",initturn,runturn},
405 {"turn_south",initturn,runturn},
406 {"turn_south_west",initturn,runturn},
407 {"turn_west",initturn,runturn},
408 {"turn_north_west",initturn,runturn},
409 {"camera_north",initcamera,runcamera},
410 {"camera_north_east",initcamera,runcamera},
411 {"camera_east",initcamera,runcamera},
412 {"camera_south_east",initcamera,runcamera},
413 {"camera_south",initcamera,runcamera},
414 {"camera_south_west",initcamera,runcamera},
415 {"camera_west",initcamera,runcamera},
416 {"camera_north_west",initcamera,runcamera},
417 {"invisible",initvisible,runvisible},
418 {"wizard",initwizard,runwizard},
419 {"say",initsay,runsay},
420 {"apply",initapply,runapply},
421 {"apply_object",initapplyobject,runapplyobject},
422 {"drop_object",initdropobject,rundropobject},
423 {"pickup",initpickup,runpickup},
424 {"pickup_object",initpickupobject,runpickupobject},
425 {"ghosted",initghosted,runghosted},
426 {"teleport",initteleport,runteleport},
427 {"notice",initnotice,runnotice}
428 };
429 int animationcount=sizeof (animationbox) / sizeof (CFanimationHook);
430 int ordered_commands=0;
431 static int compareAnims (const void *a, const void *b)
432 {
433 return strcmp ( ((CFanimationHook*)a)->name,((CFanimationHook*)b)->name);
434 }
435
436 void prepare_commands (void)
437 {
438 qsort (animationbox,animationcount,sizeof (CFanimationHook),compareAnims);
439 ordered_commands=1;
440 }
441
442 static CFanimationHook *get_command(char *command)
443 {
444 CFanimationHook dummy;
445 dummy.name=command;
446 if (!ordered_commands)
447 prepare_commands();
448 return (CFanimationHook*)
449 bsearch (&dummy,animationbox,animationcount,
450 sizeof(CFanimationHook), compareAnims);
451 }
452
453 static CFmovement *parse_animation_block(char *buffer, size_t buffer_size, FILE *fichier, CFanimation *parent)
454 {
455 CFmovement* first=NULL;
456 CFmovement* current=NULL;
457 CFmovement* next;
458 char* time;
459 char* name;
460 char* parameters;
461 int tick;
462 CFanimationHook* animationhook;
463 if (parent->verbose)
464 printf ("CFAnim: In parse block for %s\n",buffer);
465 while (fgets(buffer,buffer_size,fichier))
466 {
467 if (buffer[0]=='[') break;
468 if (buffer[0]=='#') continue;
469 buffer[strlen(buffer)-strlen("\n")]='\0';
470 while (buffer[strlen(buffer)-1]==' ')
471 buffer[strlen(buffer)-1]='\0';
472 if (strlen (buffer)<=0)
473 continue;
474 time=buffer;
475
476 name= strstr (buffer," ");
477 if (!name) continue;
478 *name='\0';
479 name++;
480 while (*name==' ') name++;
481
482 tick=atoi(time);
483 if (tick<0) continue;
484
485 parameters=strstr (name," ");
486 if (parameters) /*Parameters may be nul*/
487 {
488 *parameters ='\0';
489 parameters++;
490 while (*parameters==' ') parameters++;
491 if (*parameters=='\0') parameters=NULL;
492 }
493 animationhook= get_command (name);
494 printf ("\n");
495 if (parent->verbose)
496 {
497 if (!animationhook)
498 printf ("CFAnim: %s - Unknown animation command\n",name);
499 else
500 printf ("CFAnim: Parsed %s -> %p\n",name,animationhook);
501 }
502 if (!animationhook)
503 {
504 if (parent->errors_allowed)
505 continue;
506 else
507 break;
508 }
509 next= (CFmovement*) malloc (sizeof (CFmovement));
510 if (!next) continue;
511 next->parent=parent;
512 next->tick=tick;
513 next->next=NULL;
514 if (animationhook->funcinit)
515 next->id=animationhook->funcinit (name,parameters,next);
516 next->func=animationhook->funcrun;
517 if (current) current->next=next;
518 else first=next;
519 current=next;
520 }
521 printf ("\n");
522 return first;
523 }
524
525 /*
526 * This function take buffer with a value like "blabla= things"
527 * Its arguments are:
528 * buffer: where equality is written
529 * variable: the address of a char pointer. It will
530 * be positionned to where in buffer the
531 * variable name starts. leading spaces
532 * will be converted to \0
533 * value: the same as above but for the value part
534 * Note that variable and value become pointers to internals of
535 * buffer. If buffer chages, they will whange too!
536 */
537 int equality_split (char* buffer, char**variable, char**value)
538 {
539 if (!strcmp (&buffer[strlen(buffer)-strlen("\n")],"\n"))
540 buffer[strlen(buffer)-strlen("\n")]='\0';
541 *value=strstr (buffer,"=");
542 if (!*value) return 0;
543 **value='\0';
544 *variable=buffer;
545 (*value)++;
546 while ((strlen(*variable)>0) && ((*variable)[strlen(*variable)-1]==' '))
547 (*variable)[strlen(*variable)-1]='\0';
548 while ((strlen(*value)>0) && ((*value)[strlen(*value)-1]==' '))
549 (*value)[strlen(*value)-1]='\0';
550 while (**value==' ') (*value)++;
551 if ((**variable=='\0') || (**value=='\0')) return 0;
552 return 1;
553 }
554 /*
555 * This function gets a string containing
556 * [Y/y](es)/[N/n](o), 1/0
557 * and set bool according to what's read
558 * if return value is true, bool was set successfully
559 * else, an error occured and bool was not touched
560 */
561 int get_boolean (char* string,int* bool)
562 {
563 if (!strncmp (string,"y",1))
564 *bool=1;
565 else if (!strncmp (string,"n",1))
566 *bool=0;
567 else if (!strncmp (string,"Y",1))
568 *bool=1;
569 else if (!strncmp (string,"N",1))
570 *bool=0;
571 else if (!strncmp (string,"1",1))
572 *bool=1;
573 else if (!strncmp (string,"0",1))
574 *bool=0;
575 else return 0;
576 return 1;
577 }
578
579 int is_animated_player (object* pl)
580 {
581 CFanimation* current;
582 for (current=first_animation;current;current++)
583 if ((current->victim==pl) && (current->paralyze))
584 {
585 if (current->verbose)
586 printf("CFAnim: Getting a command for a paralyzed player %s.\n",pl->name);
587 return 1;
588 }
589 return 0;
590 }
591
592 /*
593 * return a new animation pointer inserted in the list of animations
594 */
595 static CFanimation *create_animation(void)
596 {
597 CFanimation* new;
598 CFanimation* current;
599 new=(CFanimation*) malloc (sizeof (CFanimation));
600 if (!new) return NULL;
601 new->name=NULL;
602 new->victim=NULL;
603 new->nextmovement=NULL;
604 new->nextanimation=NULL;
605 for (current=first_animation;(current && current->nextanimation);
606 current=current->nextanimation);
607 if (!current)
608 first_animation=new;
609 else
610 current->nextanimation=new;
611 return new;
612 }
613
614 void free_events(object* who)
615 {
616 /*if (who->event_hook[current_event])
617 {
618 hook_free_string (who->event_hook[current_event]);
619 who->event_hook[current_event]=NULL;
620 }
621 if (who->event_plugin[current_event])
622 {
623 hook_free_string (who->event_plugin[current_event]);
624 who->event_plugin[current_event]=NULL;
625 }
626 if (who->event_hook[current_event])
627 {
628 hook_free_string (who->event_options[current_event]);
629 who->event_options[current_event]=NULL;
630 }*/
631
632 }
633
634 /*
635 * Create a new animation object according to file, option and activator (who)
636 */
637 int start_animation (object* who,object* activator,char* file, char* options)
638 {
639 FILE* fichier;
640 char* name=NULL;
641 int victimtype=0;
642 object* victim=NULL;
643 int unique=0;
644 int always_delete=0;
645 int parallel=0;
646 int paralyzed=1;
647 int invisible=0;
648 int wizard=0;
649 enum time_enum timetype;
650 int errors_allowed=0;
651 int verbose=0;
652 char* animationitem;
653 char buffer[HUGE_BUF];
654 char* variable;
655 char* value;
656 int errors_found=0;
657 CFanimation* current_anim;
658
659 fichier = fopen(cf_get_maps_directory(file),"r");
660 if (fichier == NULL)
661 {
662 printf("CFAnim: Unable to open %s\n", cf_get_maps_directory(file));
663 return 0;
664 }
665 while (fgets(buffer,HUGE_BUF,fichier))
666 {
667 if (buffer[0]=='[') break;
668 if (buffer[0]=='#') continue;
669 if (!strcmp(buffer,"\n")) continue;
670 errors_found=1;
671 printf ("CFAnim: '%s' has an invalid syntax.\n",buffer);
672 }
673 if (feof(fichier))
674 return 0;
675 if (strncmp (buffer,"[Config]",8))
676 {
677 printf ("CFAnim: Fatal error in %s: [Config] must be the first group defined.\n",file);
678 return 0;
679 }
680 while (fgets(buffer,HUGE_BUF,fichier))
681 {
682 if (buffer[0]=='[') break;
683 if (buffer[0]=='#') continue;
684 if (!strcmp(buffer,"\n")) continue;
685 if (!equality_split(buffer,&variable,&value))
686 errors_found=1;
687 else
688 {
689 if (!strcmp (variable,"name"))
690 {
691 if (*value=='"') value++;
692 if (value[strlen(value)-1] == '"') value[strlen(value)-1]='\0';
693 name=cf_strdup_local (value);
694 }
695 else if (!strcmp (variable,"victimtype"))
696 {
697 if (!strcmp (value,"player")) victimtype=0;
698 else if (!strcmp (value,"object")) victimtype=1;
699 else if (!strcmp (value,"any")) victimtype=2;
700 else errors_found=1;
701 }
702 else if (!strcmp (variable,"victim"))
703 {
704 printf ("Setting victim to %s\n",value);
705 if (!strcmp (value,"who"))
706 victim=who;
707 else if (!strcmp (value,"activator"))
708 victim=activator;
709 else if (!strcmp (value,"who_owner"))
710 if (!who)
711 {
712 errors_found=1;
713 printf("Warning: object \"who\" doesn't exist and you victimized it's owner\n");
714 }
715 else
716 victim=who->env;
717 else if (!strcmp (value,"activator_owner"))
718 if (!activator)
719 {
720 errors_found=1;
721 printf ("Warning: object \"activator\" doesn't exist and you victimized it's owner\n");
722 }
723 else
724 victim=activator->env;
725 else
726 errors_found=1;
727 }
728 else if (!strcmp(variable,"unique"))
729 {
730 if (!get_boolean(value,&unique))
731 errors_found=1;
732 }
733 else if (!strcmp(variable,"always_delete"))
734 {
735 if (!get_boolean(value,&always_delete))
736 errors_found=1;
737 }
738 else if (!strcmp(variable,"parallel"))
739 {
740 if (!get_boolean(value,&parallel))
741 errors_found=1;
742 }
743 else if (!strcmp(variable,"paralyzed"))
744 {
745 if (!get_boolean(value,&paralyzed))
746 errors_found=1;
747 }
748 else if (!strcmp(variable,"invisible"))
749 {
750 if (!get_boolean(value,&invisible))
751 errors_found=1;
752 }
753 else if (!strcmp(variable,"wizard"))
754 {
755 if (!get_boolean(value,&wizard))
756 errors_found=1;
757 }
758 else if (!strcmp(variable,"errors_allowed"))
759 {
760 if (!get_boolean(value,&errors_allowed))
761 errors_found=1;
762 }
763 else if (!strcmp(variable,"verbose"))
764 {
765 if (!get_boolean(value,&verbose))
766 errors_found=1;
767 }
768 else if (!strcmp(variable,"time_representation"))
769 {
770 if (!strcmp (value,"second")) timetype=time_second;
771 else if (!strcmp (value,"tick")) timetype=time_tick;
772 else errors_found=1;
773 }
774 else if (!strcmp(variable,"animation"))
775 {
776 animationitem=cf_strdup_local(value);
777 }
778 else errors_found=1;
779 }
780 }
781 if (buffer[0]=='\0')
782 {
783 printf ("CFAnim: Errors occurred during the parsing of %s\n", cf_get_maps_directory(file));
784 return 0;
785 }
786 if (!(current_anim=create_animation()))
787 {
788 printf ("CFAnim: Fatal error - Not enough memory.\n");
789 return 0;
790 }
791 if (always_delete)
792 {
793 /*if (verbose) printf("CFAnim: Freeing event nr. %d for %s.\n",current_event,who->name);*/
794 free_events(who);
795 }
796 if (!victim)
797 {
798 printf ("CFAnim: Fatal error - victim is NULL");
799 return 0;
800 }
801 if ( ( (victim->type==PLAYER) && (victimtype==1)) ||
802 ( (victim->type!=PLAYER) && (victimtype==0)) ||
803 ( errors_found && !errors_allowed) )
804 {
805 if (verbose) printf ("CFAnim: No correct victim found or errors found, aborting.\n");
806 return 0;
807 }
808 if (unique && !always_delete)
809 {
810 /*if (verbose) printf ("CFAnim: Freeing event nr. %d for %s.\n",current_event,who->name);*/
811 free_events(who);
812 }
813 current_anim->name = name;
814 current_anim->victim = victim;
815 current_anim->paralyze = paralyzed;
816 current_anim->invisible = invisible;
817 current_anim->wizard = wizard;
818 current_anim->unique = unique;
819 current_anim->ghosted = 0;
820 current_anim->corpse = NULL;
821 current_anim->time_representation=timetype;
822 current_anim->verbose = verbose;
823 current_anim->tick_left = 0;
824 current_anim->errors_allowed=errors_allowed;
825 while (buffer[0]=='[')
826 {
827 if (strncmp (&buffer[1],animationitem,strlen(animationitem)))
828 while (fgets(buffer,HUGE_BUF,fichier))
829 if (buffer[0]=='[') break;
830 current_anim->nextmovement=parse_animation_block(buffer,HUGE_BUF,fichier,current_anim);
831 if (current_anim->nextmovement) break;
832 }
833 fclose (fichier);
834 return 1;
835 }
836 static void animate_one(CFanimation *animation, long int milliseconds)
837 {
838 CFmovement* current;
839
840 if (animation->time_representation==time_second)
841 animation->tick_left+=milliseconds;
842 else animation->tick_left++;
843 if (animation->verbose)
844 printf("CFAnim: Ticking %s for %s. Tickleft is %ld\n",
845 animation->name,animation->victim->name,animation->tick_left);
846 if (animation->invisible)
847 animation->victim->invisible=10;
848 if (animation->wizard)
849 {
850 if (animation->verbose)
851 printf ("CFAnim: Setting wizard flags\n");
852 cf_object_set_flag(animation->victim, FLAG_WIZPASS,1);
853 cf_object_set_flag(animation->victim, FLAG_WIZCAST,1);
854 cf_object_set_flag(animation->victim, FLAG_WIZ,1);
855
856 }
857 cf_object_update(animation->victim,UP_OBJ_CHANGE);
858
859 if (animation->nextmovement)
860 while ( animation->tick_left> animation->nextmovement->tick)
861 {
862 animation->tick_left-=animation->nextmovement->tick;
863 animation->nextmovement->func (animation,
864 animation->nextmovement->id,
865 animation->nextmovement->parameters);
866 current=animation->nextmovement;
867 animation->nextmovement=animation->nextmovement->next;
868 free (current);
869 if (!animation->nextmovement) break;
870 }
871 cf_object_set_flag(animation->victim, FLAG_WIZPASS,0);
872 cf_object_set_flag(animation->victim, FLAG_WIZCAST,0);
873 cf_object_set_flag(animation->victim, FLAG_WIZ,0);
874 }
875
876 void animate(void)
877 {
878 CFanimation* current;
879 CFanimation* next;
880 struct timeval now;
881 static struct timeval yesterday;
882 static int already_passed=0;
883 long int delta_milli;
884 (void) GETTIMEOFDAY(&now);
885 if (!already_passed)
886 {
887 already_passed=1;
888 memcpy (&yesterday,&now,sizeof (struct timeval));
889 return;
890 }
891 delta_milli=(now.tv_sec-yesterday.tv_sec)*1000+(now.tv_usec/1000-yesterday.tv_usec/1000);
892 /*printf ("Working for %ld milli seconds\n",delta_milli);*/
893 memcpy (&yesterday,&now,sizeof (struct timeval));
894 for (current=first_animation;current;current=current->nextanimation)
895 animate_one(current,delta_milli);
896 current=first_animation;
897 while (current)
898 {
899 if (!current->nextmovement)
900 {
901 next=current->nextanimation;
902 if (first_animation==current)
903 first_animation=next;
904 if (current->name)
905 free (current->name);
906 free (current);
907 current=next;
908 }
909 else
910 current=current->nextanimation;
911 }
912 }
913
914
915
916
917
918
919
920
921 void initContextStack(void)
922 {
923 current_context = NULL;
924 context_stack = NULL;
925 }
926
927 void pushContext(CFPContext* context)
928 {
929 if (current_context == NULL)
930 {
931 context_stack = context;
932 context->down = NULL;
933 }
934 else
935 {
936 context->down = current_context;
937 }
938 current_context = context;
939 }
940
941 CFPContext* popContext()
942 {
943 CFPContext* oldcontext;
944 if (current_context != NULL)
945 {
946 oldcontext = current_context;
947 current_context = current_context->down;
948 return oldcontext;
949 }
950 else
951 return NULL;
952 }
953
954 CF_PLUGIN int initPlugin(const char* iversion, f_plug_api gethooksptr)
955 {
956 gethook = gethooksptr;
957
958 printf("CFAnim 2.0a init\n");
959
960 /* Place your initialization code here */
961 return 0;
962 }
963
964 CF_PLUGIN void* getPluginProperty(int* type, ...)
965 {
966 va_list args;
967 char* propname;
968
969 va_start(args, type);
970 propname = va_arg(args, char *);
971
972 if (!strcmp(propname, "Identification"))
973 {
974 va_end(args);
975 return PLUGIN_NAME;
976 }
977 else if (!strcmp(propname, "FullName"))
978 {
979 va_end(args);
980 return PLUGIN_VERSION;
981 }
982 return NULL;
983 }
984
985 CF_PLUGIN int runPluginCommand(object* op, char* params)
986 {
987 return -1;
988 }
989
990 CF_PLUGIN int postInitPlugin(void)
991 {
992 int hooktype = 1;
993 int rtype = 0;
994
995 printf("CFAnim 2.0a post init\n");
996 registerGlobalEvent = gethook(&rtype,hooktype,"cfapi_system_register_global_event");
997 unregisterGlobalEvent = gethook(&rtype,hooktype,"cfapi_system_unregister_global_event");
998 systemDirectory = gethook(&rtype,hooktype,"cfapi_system_directory");
999 reCmp = gethook(&rtype,hooktype,"cfapi_system_re_cmp");
1000 cf_init_plugin( gethook );
1001 initContextStack();
1002 /* Pick the global events you want to monitor from this plugin */
1003 registerGlobalEvent(NULL,EVENT_CLOCK,PLUGIN_NAME,globalEventListener);
1004 return 0;
1005 }
1006
1007 CF_PLUGIN void* globalEventListener(int* type, ...)
1008 {
1009 va_list args;
1010 static int rv=0;
1011 CFPContext* context;
1012 char* buf;
1013 player* pl;
1014 context = malloc(sizeof(CFPContext));
1015
1016 va_start(args, type);
1017 context->event_code = va_arg(args, int);
1018
1019 context->message[0]=0;
1020
1021 context->who = NULL;
1022 context->activator = NULL;
1023 context->third = NULL;
1024 rv = context->returnvalue = 0;
1025 switch(context->event_code)
1026 {
1027 case EVENT_CRASH:
1028 printf( "Unimplemented for now\n");
1029 break;
1030 case EVENT_BORN:
1031 context->activator = va_arg(args, object*);
1032 break;
1033 case EVENT_PLAYER_DEATH:
1034 context->who = va_arg(args, object*);
1035 break;
1036 case EVENT_GKILL:
1037 context->who = va_arg(args, object*);
1038 context->activator = va_arg(args, object*);
1039 break;
1040 case EVENT_LOGIN:
1041 pl = va_arg(args, player*);
1042 context->activator = pl->ob;
1043 buf = va_arg(args, char*);
1044 if (buf !=0)
1045 strcpy(context->message,buf);
1046 break;
1047 case EVENT_LOGOUT:
1048 pl = va_arg(args, player*);
1049 context->activator = pl->ob;
1050 buf = va_arg(args, char*);
1051 if (buf !=0)
1052 strcpy(context->message,buf);
1053 break;
1054 case EVENT_REMOVE:
1055 context->activator = va_arg(args, object*);
1056 break;
1057 case EVENT_SHOUT:
1058 context->activator = va_arg(args, object*);
1059 buf = va_arg(args, char*);
1060 if (buf !=0)
1061 strcpy(context->message,buf);
1062 break;
1063 case EVENT_MUZZLE:
1064 context->activator = va_arg(args, object*);
1065 buf = va_arg(args, char*);
1066 if (buf !=0)
1067 strcpy(context->message,buf);
1068 break;
1069 case EVENT_KICK:
1070 context->activator = va_arg(args, object*);
1071 buf = va_arg(args, char*);
1072 if (buf !=0)
1073 strcpy(context->message,buf);
1074 break;
1075 case EVENT_MAPENTER:
1076 context->activator = va_arg(args, object*);
1077 break;
1078 case EVENT_MAPLEAVE:
1079 context->activator = va_arg(args, object*);
1080 break;
1081 case EVENT_CLOCK:
1082 break;
1083 case EVENT_MAPRESET:
1084 buf = va_arg(args, char*);
1085 if (buf !=0)
1086 strcpy(context->message,buf);
1087 break;
1088 case EVENT_TELL:
1089 break;
1090 case EVENT_FIND_UNARMED_SKILL:
1091 context->who = va_arg(args, object*);
1092 break;
1093 case EVENT_PLAYER_USE_SKILL:
1094 case EVENT_MONSTER_USE_SKILL:
1095 context->activator = va_arg(args, object*);
1096 context->who = va_arg(args, object*);
1097 context->third = va_arg(args, object*);
1098 context->fix = va_arg(args, int);
1099
1100 buf = va_arg(args, char*);
1101 if (buf !=0)
1102 strncpy(context->message, buf, sizeof (context->message));
1103 break;
1104 }
1105 va_end(args);
1106 context->returnvalue = 0;
1107
1108 pushContext(context);
1109 /* Put your plugin action(s) here */
1110
1111 context = popContext();
1112 rv = context->returnvalue;
1113 free(context);
1114
1115 return &rv;
1116 }
1117
1118 CF_PLUGIN void* eventListener(int* type, ...)
1119 {
1120 static int rv=0;
1121 va_list args;
1122 char* buf;
1123 CFPContext* context;
1124
1125 context = malloc(sizeof(CFPContext));
1126
1127 context->message[0]=0;
1128
1129 va_start(args,type);
1130
1131 context->who = va_arg(args, object*);
1132 context->event_code = va_arg(args,int);
1133 context->activator = va_arg(args, object*);
1134 context->third = va_arg(args, object*);
1135 buf = va_arg(args, char*);
1136 if (buf !=0)
1137 strcpy(context->message,buf);
1138 context->fix = va_arg(args, int);
1139 strcpy(context->script,cf_get_maps_directory(va_arg(args, char*)));
1140 strcpy(context->options,va_arg(args, char*));
1141 context->returnvalue = 0;
1142 va_end(args);
1143
1144 pushContext(context);
1145 /* Put your plugin action(s) here */
1146 printf("CFAnim: %s called animator script %s, options are %s\n",
1147 context->activator->name,
1148 context->script,
1149 context->options);
1150
1151 context->returnvalue = start_animation(context->who, context->activator,
1152 context->script, context->options);
1153
1154 context = popContext();
1155 rv = context->returnvalue;
1156 free(context);
1157 printf("Execution complete");
1158 return &rv;
1159 }
1160
1161 CF_PLUGIN int closePlugin()
1162 {
1163 printf("CFAnim 2.0a closing\n");
1164 return 0;
1165 }
1166