ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/plugins/cfanim/cfanim.c
Revision: 1.4
Committed: Wed Mar 15 15:35:51 2006 UTC (18 years, 3 months ago) by elmex
Content type: text/plain
Branch: MAIN
Changes since 1.3: +2 -1 lines
Log Message:
UPSTREAM merge from 15.03.2006

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 elmex 1.4 /* */
28     /*****************************************************************************/
29 root 1.1
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 root 1.2 cf_object_move(op,dir,op);
74 root 1.1 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 elmex 1.3 static CFanimationHook *get_command(char *command)
443 root 1.1 {
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 elmex 1.3 static CFmovement *parse_animation_block(char *buffer, size_t buffer_size, FILE *fichier, CFanimation *parent)
454 root 1.1 {
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 elmex 1.3 static CFanimation *create_animation(void)
596 root 1.1 {
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 elmex 1.3 static void animate_one(CFanimation *animation, long int milliseconds)
837 root 1.1 {
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     }
1091     va_end(args);
1092     context->returnvalue = 0;
1093    
1094     pushContext(context);
1095     /* Put your plugin action(s) here */
1096    
1097     context = popContext();
1098     rv = context->returnvalue;
1099     free(context);
1100    
1101     return &rv;
1102     }
1103    
1104     CF_PLUGIN void* eventListener(int* type, ...)
1105     {
1106     static int rv=0;
1107     va_list args;
1108     char* buf;
1109     CFPContext* context;
1110    
1111     context = malloc(sizeof(CFPContext));
1112    
1113     context->message[0]=0;
1114    
1115     va_start(args,type);
1116    
1117     context->who = va_arg(args, object*);
1118     context->event_code = va_arg(args,int);
1119     context->activator = va_arg(args, object*);
1120     context->third = va_arg(args, object*);
1121     buf = va_arg(args, char*);
1122     if (buf !=0)
1123     strcpy(context->message,buf);
1124     context->fix = va_arg(args, int);
1125     strcpy(context->script,cf_get_maps_directory(va_arg(args, char*)));
1126     strcpy(context->options,va_arg(args, char*));
1127     context->returnvalue = 0;
1128     va_end(args);
1129    
1130     pushContext(context);
1131     /* Put your plugin action(s) here */
1132     printf("CFAnim: %s called animator script %s, options are %s\n",
1133     context->activator->name,
1134     context->script,
1135     context->options);
1136    
1137     context->returnvalue = start_animation(context->who, context->activator,
1138     context->script, context->options);
1139    
1140     context = popContext();
1141     rv = context->returnvalue;
1142     free(context);
1143     printf("Execution complete");
1144     return &rv;
1145     }
1146    
1147     CF_PLUGIN int closePlugin()
1148     {
1149     printf("CFAnim 2.0a closing\n");
1150     return 0;
1151     }
1152