ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/plugins/cfanim/cfanim.c
Revision: 1.1
Committed: Fri Feb 3 07:14:18 2006 UTC (18 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
Branch point for: UPSTREAM
Log Message:
Initial revision

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