source: abuse/trunk/src/chars.cpp @ 40

Last change on this file since 40 was 39, checked in by Sam Hocevar, 15 years ago
  • Fix almost 2,000 warnings by using proper "const" keywords where needed.
File size: 13.8 KB
Line 
1#include "chars.hpp"
2#include "game.hpp"
3#include "intsect.hpp"
4#include "lisp.hpp"
5#include "jwindow.hpp"
6#include "input.hpp"
7#include "id.hpp"
8#include "clisp.hpp"
9#include "dprint.hpp"
10#include "lisp_gc.hpp"
11
12#define FADING_FRAMES 26
13#define FADING_MAX 32
14
15character_type **figures;
16
17
18
19int total_weapons=0;
20int *weapon_types=NULL;    // maps 0..total_weapons into 'real' weapon type
21
22char const *state_names[MAX_STATE] =
23{
24    "dead",
25    "dieing",
26    "stopped",
27    "start_run_jump", "run_jump", "run_jump_fall", "end_run_jump",
28    "flinch_up", "flinch_down",
29    "morph_pose",
30    "running"
31};
32
33/*                             "start_still_jump","still_jump","still_jump_fall","end_still_jump",
34
35                               "morph_pose",
36                               
37                               "walking",
38                               
39
40                               "weapon_draw",
41                               "weapon_put_away",
42                               "weapon_fire",
43                               "weapon_end_fire",
44                               "weapon_fire_up",
45                               "weapon_end_fire_up",
46
47                               "blocking",
48                               "block_recoil",
49
50                               "turn_around",
51                               "flinch_up","flinch_down","flinch_back",
52                               "flinch_air","flinch_ground","flinch_getup","woze",
53                               "stance"
54                             } ; */
55
56
57char const *cflag_names[TOTAL_CFLAGS] =
58{
59    "hurt_all", "is_weapon", "stoppable", "can_block",
60    "hurtable", "pushable", "unlistable",
61    "add_front", "cached_in", "need_cache_in", "unactive_shield"
62};
63
64char const *ofun_names[TOTAL_OFUNS] =
65{
66    "ai_fun", "move_fun", "draw_fun", "map_draw_fun", "damage_fun",
67    "next_state_fun", "user_fun",
68    "constructor", "reload_fun", "get_cache_list_fun",
69    "type_change_fun"
70};
71
72int character_type::add_state(void *symbol)             // returns index into seq to use
73{
74  if (item_type(symbol)!=L_SYMBOL)
75  {
76    lprint(symbol);
77    lbreak("is not a symbol (in def_char)");
78    exit(0);
79  }
80
81  void *val=symbol_value(symbol);
82
83  int num;
84  if (DEFINEDP(val))
85  {
86    if (item_type(val)!=L_NUMBER)
87    {
88      lprint(symbol);
89      dprintf("expecting symbol value to be a number, instead got : ");
90      lprint(val);
91      lbreak("");
92      exit(0);
93    }
94    num=lnumber_value(val);
95  } else
96  {
97    num=ts;
98    if (num<MAX_STATE) num=MAX_STATE;
99    int sp=current_space;
100    current_space=PERM_SPACE;
101    set_symbol_number(symbol,num);
102    current_space=sp;
103  }
104
105  if (num<ts && seq[num])
106  {
107    lprint(symbol);
108    lbreak("symbol has been assigned value %d, but value already in use by state %s\n"
109           "use a different symbol for this state\n",
110           lstring_value(symbol_name(seq_syms[num])));
111    exit(0);
112  } else if (num>=ts)
113  {
114    seq=(sequence **)jrealloc(seq,sizeof(sequence *)*(num+1),"state list");   
115    seq_syms=(void **)jrealloc(seq_syms,sizeof(void *)*(num+1),"state sym list");   
116
117    memset(&seq[ts],0,sizeof(sequence *)*((num+1)-ts));
118    memset(&seq_syms[ts],0,sizeof(void *)*((num+1)-ts));
119
120    ts=num+1;
121  }
122
123  seq_syms[num]=symbol;
124  return num;
125}
126
127int flinch_state(character_state state)
128{
129  if (state==flinch_up || state==flinch_down)
130    return 1;
131  else return 0;
132}
133
134int character_type::cache_in()    // returns false if out of cache memory
135{
136  int i;
137  if (get_cflag(CFLAG_CACHED_IN))
138    return 1;
139  cflags|=1<<CFLAG_CACHED_IN;
140
141  for (i=0;i<ts;i++)
142  {
143    if (seq[i])
144      seq[i]->cache_in();
145  }
146  return 1;
147}
148
149void character_type::add_sequence(character_state which, sequence *new_seq)
150{
151  if (seq[which])
152    delete seq[which];
153  seq[which]=new_seq; 
154
155
156void *l_obj_get(long number) // exten lisp function switches on number
157{
158  character_type *t=figures[current_object->otype];
159  if (t->tiv<=number || !t->vars[number])
160  {
161    lbreak("access : variable does not exsist for this class\n");
162    return 0;
163  }
164  return new_lisp_number(current_object->lvars[t->var_index[number]]); 
165}
166
167void l_obj_set(long number, void *arg)  // exten lisp function switches on number
168{
169  character_type *t=figures[current_object->otype];
170  if (t->tiv<=number || !t->vars[number])
171  {
172    lbreak("set : variable does not exsist for this class\n");
173    return;
174  }
175  current_object->lvars[t->var_index[number]]=lnumber_value(arg);
176}
177
178void l_obj_print(long number)  // exten lisp function switches on number
179{
180  character_type *t=figures[current_object->otype];
181  if (t->tiv<=number || !t->vars[number])
182  {
183    lbreak("access : variable does not exsist for this class\n");
184    return;
185  }
186  dprintf("%d",current_object->lvars[t->var_index[number]]); 
187}
188
189void character_type::add_var(void *symbol, void *name)
190{
191  /* First see if the variable has been defined for another object
192     if so report a conflict if any occur */
193  lisp_symbol *s=(lisp_symbol *)symbol;
194  if (DEFINEDP(s->value) && (item_type(s->value)!=L_OBJECT_VAR))
195  {
196    lprint(symbol);
197    lbreak("symbol already has a value, cannot instantiate an object varible");
198    exit(0);
199  } else if (DEFINEDP(s->value))
200  {
201    int index=((lisp_object_var *)s->value)->number;
202    if (index<tiv)
203    {
204      if (vars[index])
205      {       
206        lbreak("While defining object %s :\n"
207               "  var '%s' was previously defined by another\n"
208               "  with index %d, but %s has a var listed '%s' with same index\n"
209               "  try moving definition of %s before previously declared object",
210               lstring_value(symbol_name(name)),
211               lstring_value(symbol_name(symbol)),
212               index,
213               lstring_value(symbol_name(name)),
214               lstring_value(symbol_name(vars[index])),
215               lstring_value(symbol_name(name))
216               );
217        exit(0);
218      } else
219      {
220        var_index[index]=tv;
221        vars[index]=symbol;
222        tv++;
223      }
224    } else
225    {
226      int new_total=index+1;
227      vars=(void **)jrealloc(vars,sizeof(void *)*new_total,"variable name list");
228      var_index=(short *)jrealloc(var_index,sizeof(short)*new_total,"variable index");
229      memset(&vars[tiv],0,(new_total-tiv)*sizeof(void *));
230      memset(&var_index[tiv],0,(new_total-tiv)*sizeof(short));
231      tiv=new_total;
232
233      var_index[index]=tv;
234      vars[index]=symbol;
235      tv++;
236    }   
237  } else  /** Nope, looks like we have to add the variable ourself and define the assesor funs */
238  {
239    /* locate a free index in the index list */
240    int free_index=tiv;
241    for (int i=0;i<tiv;i++)
242      if (!vars[i] && i<tiv) free_index=i;
243    if (free_index==tiv)
244    {
245      int new_total=free_index+1;
246      vars=(void **)jrealloc(vars,sizeof(void *)*new_total,"variable name list");
247      var_index=(short *)jrealloc(var_index,sizeof(short)*new_total,"variable index");
248      memset(&vars[tiv],0,(new_total-tiv)*sizeof(void *));
249      memset(&var_index[tiv],0,(new_total-tiv)*sizeof(short));
250      tiv=new_total;
251    }
252
253    /* create the var and add to var list */
254    int sp=current_space;
255    current_space=PERM_SPACE;
256
257    add_c_object(symbol,free_index);
258   
259    vars[free_index]=symbol;
260    var_index[free_index]=tv;
261    tv++;
262    current_space=sp;
263  }
264}
265
266
267long character_type::isa_var_name(char *name)
268{
269  int i=0;
270  for (;i<TOTAL_OBJECT_VARS;i++)
271  {
272    if (!strcmp(object_descriptions[i].name,name))
273      return 1;
274  }
275  for (i=0;i<tiv;i++)
276    if (!strcmp(lstring_value(symbol_name(vars[i])),name))
277      return 1;
278  return 0;
279}
280
281character_type::character_type(void *args, void *name)
282{
283  p_ref r2(args);
284  int i;
285  ts=tv=0;
286  seq=NULL;
287  seq_syms=NULL;
288  vars=NULL;
289  var_index=NULL;
290  tiv=0;
291
292  void *l_abil=  make_find_symbol("abilities");
293  void *l_funs=  make_find_symbol("funs");
294  void *l_states=make_find_symbol("states");
295  void *l_flags= make_find_symbol("flags");
296  void *l_range= make_find_symbol("range");
297  void *l_draw_range= make_find_symbol("draw_range");
298  void *l_fields=make_find_symbol("fields");
299  void *l_logo=  make_find_symbol("logo");
300  void *l_vars=  make_find_symbol("vars");
301
302  memset(fun_table,0,sizeof(fun_table));     // destory all hopes of fun
303  fields=NULL;
304  cflags=0;
305  morph_mask=-1;
306  morph_power=0;
307  total_fields=0;
308  logo=-1;
309  rangex=rangey=0;
310  draw_rangex=draw_rangey=0;
311
312  for (i=0;i<TOTAL_ABILITIES;i++)
313    abil[i]=get_ability_default((ability)i);         
314  void *field=args;
315  p_ref r7(field);
316  for (;field;field=CDR(field))
317  {
318    void *f=CAR(CAR(field));
319    p_ref r1(f);
320   
321    if (f==l_abil)
322    {
323      void *l=CDR(CAR(field));
324      p_ref r4(l);
325      for (i=0;i<TOTAL_ABILITIES;i++)
326      {
327        Cell *ab=assoc(make_find_symbol(ability_names[i]),l);
328        p_ref r5(ab);
329        if (!NILP(ab))
330          abil[i]=lnumber_value(eval(lcar(lcdr(ab))));
331      }
332    } else if (f==l_funs)
333    {
334      void *l=CDR(CAR(field));
335      p_ref r4(l);
336      for (i=0;i<TOTAL_OFUNS;i++)
337      {
338        Cell *ab=assoc(make_find_symbol(ofun_names[i]),l);
339        p_ref r5(ab);
340        if (!NILP(ab) && lcar(lcdr(ab)))
341        fun_table[i]=lcar(lcdr(ab));
342      }
343    } else if (f==l_flags)
344    {
345      void *l=CDR(CAR(field));
346      p_ref r4(l);
347      for (i=0;i<TOTAL_CFLAGS;i++)
348      {
349        Cell *ab=assoc(make_find_symbol(cflag_names[i]),l);
350        p_ref r5(ab);
351        if (!NILP(ab) && eval(lcar(lcdr(ab))))
352        cflags|=(1<<i);
353      }
354     
355      if (get_cflag(CFLAG_IS_WEAPON))  // if this is a weapon add to weapon array
356      {
357        total_weapons++;
358        weapon_types=(int *)jrealloc(weapon_types,sizeof(int)*total_weapons,"weapon map");
359        weapon_types[total_weapons-1]=total_objects;
360      }
361    } else if (f==l_range)
362    {
363      rangex=lnumber_value(eval(lcar(lcdr(lcar(field)))));
364      rangey=lnumber_value(eval(lcar(lcdr(lcdr(lcar(field))))));
365    } else if (f==l_draw_range)
366    {
367      draw_rangex=lnumber_value(eval(lcar(lcdr(lcar(field)))));
368      draw_rangey=lnumber_value(eval(lcar(lcdr(lcdr(lcar(field))))));
369    } else if (f==l_states)
370    {
371      void *l=CDR(CAR(field));
372      p_ref r4(l);
373      char fn[100];
374      strcpy(fn,lstring_value(eval(CAR(l)))); l=CDR(l);
375      while (l)
376      {
377          int index;
378          void *e;
379          sequence *mem;
380          index = add_state(CAR((CAR(l))));
381          e = eval(CAR(CDR(CAR(l))));
382          mem = new sequence(fn,e,NULL);
383        seq[index]=mem;
384        l=CDR(l);
385      }
386    } else if (f==l_fields)
387    {
388      void *mf=CDR(CAR(field));
389      p_ref r4(mf);
390      while (!NILP(mf))
391      {
392        char *real=lstring_value(eval(lcar(lcar(mf))));
393        char *fake=lstring_value(eval(lcar(lcdr(lcar(mf)))));
394        if (!isa_var_name(real))
395        {
396          lprint(field);
397          lbreak("fields : no such var name \"%s\"\n",name);
398          exit(0);
399        }
400        total_fields++;
401
402        fields=(named_field **)jrealloc(fields,sizeof(named_field *)*total_fields,"named_fields");
403        fields[total_fields-1]=new named_field(real,fake);
404        mf=lcdr(mf);
405      }
406    } else if (f==l_logo)
407    {
408      char *fn=lstring_value(eval(CAR(CDR(CAR(field)))));
409      char *o=lstring_value(eval(CAR(CDR(CDR(CAR(field))))));
410      logo=cash.reg(fn,o,SPEC_IMAGE,1);
411    } else if (f==l_vars)
412    {
413      void *l=CDR(CAR(field));
414      p_ref r8(l);
415      while (l)
416      {
417        add_var(CAR(l),name);
418        l=CDR(l);
419      }       
420    }
421    else
422    {
423      lprint(lcar(field));
424      lbreak("Unknown field for character definition");
425      exit(0);
426    }   
427  }
428
429  if (!seq[stopped])
430    lbreak("object (%s) has no stopped state, please define one!\n",
431           lstring_value(symbol_name(name)));
432
433/*  char *fn=lstring_value(lcar(desc));
434  if (!fn)
435  {
436    printf("No filename given for def-character (%s)\n",name);
437    exit(0);
438  }
439  desc=lcdr(desc);  //  skip filename
440
441
442  Cell *mrph=assoc(l_morph,desc);     // check for morph info
443  morph_power=0;
444  if (!NILP(mrph))
445  {
446    mrph=lcdr(mrph);
447    morph_mask=cash.reg_object(fn,lcar(mrph),SPEC_IMAGE,1);
448    morph_power=lnumber_value(lcar(lcdr(mrph)));
449  } else morph_mask=-1;
450
451  Cell *sa=assoc(l_state_art,desc);
452  if (NILP(sa))
453  {
454    printf("missing state state art in def-character (%s)\n",name);
455    exit(0);
456  }
457 
458  sa=lcdr(sa);   // list of state sequences
459  while (!NILP(sa))
460  {
461    int num=lnumber_value(lcar(lcar(sa)));
462    if (seq[num])   
463      printf("Warning : state '%s' defined multiply for object %s\n"
464             "          using first definition\n",state_names[num],name);
465    else   
466      seq[lnumber_value(lcar(lcar(sa)))]=new sequence(fn,lcar(lcdr(lcar(sa))),lcar(lcdr(lcdr(lcar(sa)))));
467    sa=lcdr(sa);   
468  }
469
470  Cell *range=assoc(l_range,desc);
471  if (!NILP(range))
472  {
473    rangex=lnumber_value(lcar(lcdr(range)));
474    rangey=lnumber_value(lcar(lcdr(lcdr(range))));
475  } else
476  {
477    rangex=100;
478    rangey=50;
479  }
480
481
482
483
484  Cell *mf=assoc(l_fields,desc);
485  if (!NILP(mf))
486  {
487    mf=lcdr(mf);
488    total_fields=0;
489    while (!NILP(mf))
490    {
491      char *name=lstring_value(lcar(lcar(mf)));
492      int t=default_simple.total_vars(),find=-1;
493      for (int i=0;find<0 && i<t;i++)
494        if (!strcmp(default_simple.var_name(i),name))
495          find=i;
496      if (find<0)
497      {
498        lprint(assoc(l_fields,desc));
499        printf("fields : no such var name \"%s\"\n",name);
500        printf("current possiblities are : \n");
501        for (int i=0;i<t;i++) printf("\"%s\" ",default_simple.var_name(i));
502        printf("\n");
503        exit(0);
504      }
505      char *new_name=lstring_value(lcar(lcdr(lcar(mf))));
506      total_fields++;
507
508      fields=(named_field **)jrealloc(fields,sizeof(named_field *)*total_fields,"named_fields");
509      fields[total_fields-1]=new named_field(find,new_name);
510      mf=lcdr(mf);
511    }
512  } else total_fields=0;
513
514
515  Cell *lg=assoc(l_logo,desc);
516  if (NILP(lg))
517  {
518    if (get_cflag(CFLAG_IS_WEAPON))
519    {
520      lprint(desc);
521      lbreak("object must have a logo defined if it is a weapon\n"
522             "example '(logo . (""art/misc.spe"" . ""big waepon""))\n");
523    }
524    logo=-1;
525  }
526  else
527    logo=cash.reg_object(fn,lcdr(lg),SPEC_IMAGE,1); 
528    */
529}
530
531
532sequence *character_type::get_sequence(character_state s)
533{
534  if (seq[s])
535    return seq[s];
536  else return seq[stopped];
537}
538
539
540character_type::~character_type()
541{
542  for (int i=0;i<ts;i++) 
543    if (seq[i])
544      delete seq[i];
545  if (ts) jfree(seq);
546
547  if (total_fields)
548  {
549    for (int i=0;i<total_fields;i++)
550      delete fields[i];
551    jfree(fields);
552  }
553
554  if (ts)
555    jfree(seq_syms);
556 
557  if (tiv)
558  {
559    jfree(vars);
560    jfree(var_index);
561  }
562
563
564}
565
566extern long small_ptr_size(void *ptr);
567
568
569void chk_sizes()
570{
571  for (int i=0;i<total_objects;i++)
572  {
573    figures[i]->check_sizes();
574  }
575}
576
577
578void character_type::check_sizes()
579{
580  for (int i=0;i<ts;i++)
581    if (seq[i] && small_ptr_size(seq[i])!=8)
582      printf("bad size for state %d\n",i);
583}
584
585
586
587
Note: See TracBrowser for help on using the repository browser.