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

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