ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/plugins/cfanim/cfanim.c
Revision: 1.1.1.1 (vendor branch)
Committed: Fri Feb 3 07:14:18 2006 UTC (18 years, 5 months ago) by root
Content type: text/plain
Branch: UPSTREAM
CVS Tags: UPSTREAM_2006_02_03
Changes since 1.1: +0 -0 lines
Log Message:
initial import

File Contents

# User Rev Content
1 root 1.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