source: abuse/trunk/src/cop.cpp @ 43

Last change on this file since 43 was 39, checked in by Sam Hocevar, 14 years ago
  • Fix almost 2,000 warnings by using proper "const" keywords where needed.
File size: 26.6 KB
Line 
1#include "lisp.hpp"
2#include "lisp_gc.hpp"
3#include "compiled.hpp"
4#include "objects.hpp"
5#include "level.hpp"
6#include "game.hpp"
7#include "jrand.hpp"
8#include "clisp.hpp"
9#include "ant.hpp"
10#include "dev.hpp"
11
12enum { point_angle, fire_delay1 };
13
14#define SHOTGUN  10
15#define GRENADE  2
16#define ROCKET   3
17#define PLASMA   4
18#define FIREBOMB 5
19#define DFRIS    6
20#define LSABER   7
21
22extern int registered;
23
24signed char small_fire_off[24*2]=  // x & y offset from character to end of gun.
25  { 17,20,     // 1
26    17,23,     // 2
27    17,28,     
28    15,33,     
29    11,39,     // 5
30    7,43,
31    -3,44,     // 7
32    -10,42,   
33    -16,39,
34    -20,34,
35    -20,28,
36    -20,25,
37    -19,20,
38    -19,16,
39    -16,14,
40    -14,11,
41    -11,9,
42    -7,8,
43    -3,8,
44    2,8,
45    6,9,
46    10,10,
47    14,13,
48    16,15 };
49
50signed char large_fire_off[24*2]=
51  { 18,25,
52    17,30,
53    15,34,
54    14,36,
55    10,39,
56    7,41,
57    4,42,
58    -3,41,
59    -8,39,
60    -11,37,
61    -14,33,
62    -16,30,
63    -18,25,
64    -17,21,
65    -14,17,
66    -11,15,
67    -7,13,
68    -4,12,
69    3,12,
70    9,12,
71    12,15,
72    14,16,
73    15,18,
74    16,21 };
75 
76
77enum { in_climbing_area,
78        disable_top_draw,
79        just_hit,
80        ship_pan_x,
81        special_power,
82        used_special_power,
83        last1_x, last1_y,
84        last2_x, last2_y,
85        has_saved_this_level,
86        r_ramp, g_ramp, b_ramp,
87        is_teleporting,
88       just_fired};
89
90
91enum { sgb_speed,
92       sgb_angle,
93       sgb_lastx,
94       sgb_lasty,
95       sgb_bright_color,
96       sgb_medium_color,
97       sgb_lifetime };
98
99enum { NO_POWER,
100       FAST_POWER,
101       FLY_POWER,
102       SNEAKY_POWER,
103       HEALTH_POWER } ;
104
105enum { top_point_angle,
106       top_fire_delay1,
107       top_just_fired };
108
109inline int angle_diff(int a1, int a2)
110{
111  if (a1<a2)
112  { if ((a2-a1)<180)
113      return a2-a1;
114    else return 360-a2+a1;
115  } else
116  {
117    if ((a1-a2)<180)
118      return a1-a2;
119    else return 360-a1+a2;
120  }
121  return 0;
122}
123
124void *top_ai()
125{
126  game_object *o=current_object;
127  if (o->total_objects())            // make sure we are linked to the main character
128  { 
129    game_object *q=o->get_object(0);
130
131    view *v=q->controller();
132    if (v)
133    {
134      if (!v->freeze_time)
135      {
136        o->direction=1;                 // always face right
137
138        if (q->direction<0)
139          q->x+=4;
140        int i;
141        signed char *fire_off=o->otype==S_DFRIS_TOP ? large_fire_off :
142                                        (o->otype==S_ROCKET_TOP ? large_fire_off :
143                                         (o->otype==S_BFG_TOP ? large_fire_off : small_fire_off));
144        signed char *f=fire_off,*fb=NULL;
145        int best_diff=200,best_num=0;
146        int iy=f[1],ix=f[6*2];
147       
148        int best_angle=lisp_atan2(q->y-iy-v->pointer_y,v->pointer_x-q->x-ix);
149        for (i=0;i<24;i++,f+=2)             // check all the angles to see which would best fit animation wise
150        {
151          int this_angle=lisp_atan2(f[1]-iy,f[0]-ix);
152          int this_diff=angle_diff(this_angle,best_angle);
153          if (this_diff<best_diff)
154          {
155            best_diff=this_diff;
156            best_num=i;
157            fb=f;
158          }
159        }
160
161
162        // if the pointer is too close to the player go with the angle shown, not the angle through the pointer
163        if (abs(q->y-fb[1]-v->pointer_y)<45 & abs(v->pointer_x-q->x+fb[0])<40)
164          o->lvars[point_angle]=lisp_atan2(fb[1]-iy,fb[0]-ix);
165        else
166          o->lvars[point_angle]=lisp_atan2(q->y-fb[1]-v->pointer_y,v->pointer_x-(q->x+fb[0]));
167       
168
169        if (q->direction<0)
170          q->x-=4;
171
172        o->x=q->x;
173        o->y=q->y+29-q->picture()->height();
174
175        rand_on+=o->lvars[point_angle];
176        o->current_frame=best_num;
177
178
179        if (o->lvars[fire_delay1])
180          o->lvars[fire_delay1]--;
181
182        o->otype=weapon_types[v->current_weapon];  // switch to correct top part   
183      }
184    }
185  }
186  return true_symbol;
187}
188
189
190int player_fire_weapon(game_object *o, int type, game_object *target, int angle, signed char *fire_off)
191{
192
193  if (!o->total_objects()) return 0;
194  game_object *other=o->get_object(0);
195  int ox=other->x,oy=other->y;
196  if (other->direction<0) other->x+=4;
197
198  int firex=other->x+fire_off[o->current_frame*2];
199  int firey=other->y-fire_off[o->current_frame*2+1];
200 
201
202 
203  // fire try to move up to gun level
204
205  int32_t x2=o->x,y2=firey;
206//  current_level->foreground_intersect(other->x,other->y,x2,y2);      // find first location we can actuall "see"
207//  current_level->all_boundary_setback(o,other->x,other->y,x2,y2);       // to make we don't fire through walls
208  other->y=y2;
209
210  if (other->y==firey)             // now try to move out to end of gun if we were not blocked above
211  {
212    x2=firex;
213    current_level->foreground_intersect(other->x,other->y,x2,y2);      // find first location we can actuall "see"
214    current_level->all_boundary_setback(other,other->x,other->y,x2,y2);       // to make we don't fire through walls
215    o->x=x2;
216  }
217
218  void *list=NULL;
219  p_ref r1(list);
220  push_onto_list(new_lisp_pointer(target),list);
221  push_onto_list(new_lisp_number(angle),list);
222  push_onto_list(new_lisp_number(y2),list);
223  push_onto_list(new_lisp_number(x2),list);
224  push_onto_list(new_lisp_number(type),list);
225  push_onto_list(new_lisp_pointer(o->get_object(0)),list);
226  eval_function((lisp_symbol *)l_fire_object,list);
227  o->lvars[top_just_fired]=1;
228  other->lvars[just_fired]=1;
229  other->x=ox;
230  other->y=oy;
231
232  return 1;
233}
234
235
236
237void *laser_ufun(void *args)
238{
239  game_object *o=current_object;
240  p_ref r1(args);
241  void *signal=CAR(args);  args=CDR(args);
242  void *ret=NULL;
243
244  if (signal==l_FIRE)
245  {
246    if (!o->lvars[fire_delay1])                   // make sur we are not waiting of previous fire
247    {
248      int32_t value=lnumber_value(eval(CAR(args)));
249      if (value)                                   // do we have ammo ?
250      {
251        o->lvars[fire_delay1]=3;
252        if (player_fire_weapon(o,SHOTGUN,NULL,o->lvars[point_angle],small_fire_off))
253          ret=new_lisp_number(-1);
254        else ret=new_lisp_number(0);
255      } else
256      {
257        o->lvars[fire_delay1]=5;                  // no ammo, set large fire delay for next shot
258        player_fire_weapon(o,SHOTGUN,NULL,o->lvars[point_angle],small_fire_off);
259        ret=new_lisp_number(0);
260      }
261    } else ret=new_lisp_number(0);                // can't fire yet, return 0 ammo subtract
262  }
263  return ret;
264}
265
266
267static int ammo_type(int otype)
268{
269  if (otype==S_GRENADE_TOP)
270    return GRENADE;
271  else if (otype==S_FIREBOMB_TOP)
272    return FIREBOMB;
273  else if (otype==S_DFRIS_TOP)
274    return DFRIS;
275  else return SHOTGUN;
276}
277
278
279void *top_ufun(void *args)                       // generic top character ai GRENADE && FIREBOMB
280{
281  game_object *o=current_object;
282  p_ref r1(args);
283  void *signal=CAR(args);  args=CDR(args);
284  void *ret=NULL;
285
286  if (signal==l_FIRE)
287  {
288    if (!o->lvars[fire_delay1])                   // make sur we are not waiting of previous fire
289    {
290      int32_t value=lnumber_value(eval(CAR(args)));
291      if (value)                                   // do we have ammo ?
292      {
293        o->lvars[fire_delay1]=6;
294        if (player_fire_weapon(o,ammo_type(o->otype),NULL,o->lvars[point_angle],
295                               o->otype==DFRIS ? large_fire_off : small_fire_off ))       
296          ret=new_lisp_number(-1);
297        else ret=new_lisp_number(0);
298      } else ret=new_lisp_number(0);
299    } else ret=new_lisp_number(0);                // can't fire yet, return 0 ammo subtract
300  }
301  return ret;
302}
303
304static int climb_handler(game_object *, int xm, int ym, int but);
305
306void *plaser_ufun(void *args)
307{
308  game_object *o=current_object;
309  p_ref r1(args);
310  void *signal=CAR(args);  args=CDR(args);
311  void *ret=NULL;
312
313  if (signal==l_FIRE)
314  {
315    if (!o->lvars[fire_delay1])                   // make sur we are not waiting of previous fire
316    {
317      int32_t value=lnumber_value(eval(CAR(args)));
318      if (value)                                   // do we have ammo ?
319      {
320        o->lvars[fire_delay1]=2;
321        if (player_fire_weapon(o,PLASMA,NULL,o->lvars[point_angle],small_fire_off))       
322          ret=new_lisp_number(-1);
323        else ret=new_lisp_number(0);
324      } else ret=new_lisp_number(0);
325    } else ret=new_lisp_number(0);                // can't fire yet, return 0 ammo subtract
326  }
327  return ret;
328}
329
330void *lsaber_ufun(void *args)
331{
332  game_object *o=current_object;
333  p_ref r1(args);
334  void *signal=CAR(args);  args=CDR(args);
335  void *ret=NULL;
336
337  if (signal==l_FIRE)
338  {
339    if (!o->lvars[fire_delay1])                   // make sur we are not waiting of previous fire
340    {
341      int32_t value=lnumber_value(eval(CAR(args)));
342      if (value)                                   // do we have ammo ?
343      {
344        o->lvars[fire_delay1]=1;
345        if (player_fire_weapon(o,LSABER,NULL,o->lvars[point_angle]+(current_level->tick_counter()&7)-8,
346                               small_fire_off))
347          ret=new_lisp_number(-1);
348        else ret=new_lisp_number(0);
349      } else ret=new_lisp_number(0);
350    } else ret=new_lisp_number(0);                // can't fire yet, return 0 ammo subtract
351  }
352  return ret;
353}
354
355
356
357void *player_rocket_ufun(void *args)
358{
359  game_object *o=current_object;
360  p_ref r1(args);
361  void *signal=CAR(args);  args=CDR(args);
362  void *ret=NULL;
363  int xd,yd,cl=0xfffffff,d;
364  if (signal==l_FIRE)
365  {
366    if (!o->lvars[fire_delay1])                   // make sur we are not waiting of previous fire
367    {
368      int32_t value=lnumber_value(eval(CAR(args)));
369      if (value)                                   // do we have ammo ?
370      {
371        o->lvars[fire_delay1]=6;
372        game_object *target=NULL,*p,*bot=o->total_objects() ? o->get_object(0) : 0;
373        if (bad_guy_array)
374        {
375          game_object *other=current_object->total_objects() ? current_object->get_object(0) : 0;
376          for (p=current_level->first_active_object();p;p=p->next_active)
377          {
378            xd=abs(p->x-o->x);
379            yd=abs(p->y-o->y);
380            if (xd<160 && yd<130 && bad_guy_array[p->otype] && p!=other)
381            {
382              if (p->targetable() &&             
383                  !(p->otype==S_ROCKET && p->total_objects() && p->get_object(0)==bot))  // don't track onto own missles
384              {
385                d=xd*xd+yd*yd;
386                if (d<cl)
387                {
388                  cl=d;
389                  target=p;
390                }
391              }
392            }
393          }
394        }
395        if (player_fire_weapon(o,ROCKET,target,o->lvars[point_angle],large_fire_off))     
396          ret=new_lisp_number(-1);
397        else ret=new_lisp_number(0);
398
399      } else ret=new_lisp_number(0);
400    } else ret=new_lisp_number(0);                // can't fire yet, return 0 ammo subtract
401  }
402  return ret;
403}
404
405static int player_move(game_object *o, int xm, int ym, int but)
406{
407  if (!o->lvars[in_climbing_area])
408  {
409    if (o->state==S_climbing)
410    {
411      o->set_gravity(1);
412      o->set_state(run_jump_fall);
413    }
414    o->next_picture();
415    return o->mover(xm,ym,but);
416  } else return climb_handler(o,xm,ym,but);
417     
418}
419
420
421static void undo_special_power(game_object *o)
422{
423  switch (o->lvars[special_power])
424  {
425    case SNEAKY_POWER :
426    {
427      if (o->lvars[used_special_power]>0)
428        o->lvars[used_special_power]--;
429    } break;
430    case FAST_POWER :
431    {
432      o->lvars[used_special_power]=0;
433    } break;
434  }
435}
436
437static void do_special_power(game_object *o, int xm, int ym, int but, game_object *top)
438{
439  switch (o->lvars[special_power])
440  {
441    case FLY_POWER :
442    {
443      if (registered)
444      {
445        game_object *cloud=create(S_CLOUD,o->x+o->direction*-10,o->y+jrand()%5);
446        if (current_level)
447        current_level->add_object(cloud);
448        o->set_state(run_jump);
449        o->set_gravity(1);
450        o->set_yacel(0);
451        if (o->yvel()>0) o->set_yvel(o->yvel()/2);
452        if (ym<0)
453        o->set_yvel(o->yvel()-3);
454        else
455        o->set_yvel(o->yvel()-2);
456        the_game->play_sound(S_FLY_SND,32,o->x,o->y);
457      }
458    } break;
459    case FAST_POWER :
460    {
461      if ((current_level->tick_counter()%16)==0)
462      the_game->play_sound(S_SPEED_SND,100,o->x,o->y);
463
464      o->lvars[used_special_power]=1;
465      o->lvars[last1_x]=o->x;
466      o->lvars[last1_y]=o->y;
467      int32_t oyvel=o->yvel();
468      int in=o->lvars[in_climbing_area];
469
470      player_move(o,xm,ym,but);
471      if (ym<0 && !oyvel && o->yvel()<0)             // if they just jumped, make them go higher
472      o->set_yvel(o->yvel()+o->yvel()/3);
473      o->lvars[in_climbing_area]=in;
474
475      o->lvars[last2_x]=o->x;
476      o->lvars[last2_x]=o->y;
477    } break;
478    case SNEAKY_POWER :
479    {
480      if (registered)
481      {
482        if (o->lvars[used_special_power]<15)
483          o->lvars[used_special_power]++;
484      }
485    } break;
486  }
487}
488
489static int climb_off_handler(game_object *o)
490{
491  if (o->next_picture())
492    o->controller()->pan_y-=4;
493  else
494  {
495    o->y-=28;
496    o->controller()->pan_y+=28;
497    o->controller()->last_y-=28;
498    o->set_state(stopped);
499  }
500  return 0;
501}
502
503
504static int climb_on_handler(game_object *o)
505{
506  if (o->next_picture())
507    o->controller()->pan_y+=4;
508  else
509    o->set_state((character_state)S_climbing);
510  return 0;
511}
512
513static int climb_handler(game_object *o, int xm, int ym, int but)
514{
515  int yd=o->lvars[in_climbing_area];  // see how from the top we are
516  o->lvars[in_climbing_area]=0;          // set 0, ladders will set back to proper if still in area
517  if (o->state==S_climb_off)
518    climb_off_handler(o);
519  else if (o->state==S_climb_on)
520    climb_on_handler(o); 
521  else
522  {
523    if (o->state==S_climbing)
524    {
525      if (ym>0)                       // going down
526      {
527
528        if (o->current_frame==0) o->current_frame=9;
529          o->current_frame--;   
530
531/*      if (o->lvars[special_power]==FAST_POWER)
532        {
533          int32_t xv=0,yv=4;
534          o->try_move(o->x,o->y,xv,yv,1);
535          if (yv==4)
536            o->y+=3;
537          else
538          {
539            o->set_gravity(1);
540            o->set_state(run_jump_fall);
541          }
542        }
543        else */ o->y+=3;
544       
545
546      } else if (ym<0)
547      {
548        if (yd<32)
549          o->set_state((character_state)S_climb_off);
550        else
551        {
552          if (!o->next_picture()) o->set_state((character_state)S_climbing);
553          o->y-=3;
554        }
555      }
556      if (xm)                     // trying to get off the ladder, check to see if that's ok
557      {
558        int32_t x2=0,y2=-20;
559        o->try_move(o->x,o->y,x2,y2,3);
560        if (y2==-20)
561        {
562          o->set_gravity(1);
563          if (ym>=0)
564            o->set_state(run_jump_fall);
565          else
566          { o->set_state(run_jump);
567            o->set_yvel(get_ability(o->otype,jump_yvel));         
568          }
569        }
570      }
571    }  else if (ym>0 && yd<10)
572    {
573      o->y+=28;
574      o->controller()->pan_y-=28;
575      o->controller()->last_y+=28;
576      o->set_state((character_state)S_climb_on);
577    }
578    else if (o->yvel()>=0 && (ym>0 || (ym<0 && yd>8)))
579    {
580      o->set_state((character_state)S_climbing);
581      o->set_gravity(0);
582      o->set_xvel(0);
583      o->set_yvel(0);
584      o->set_xacel(0);
585      o->set_yacel(0);
586      return 0;
587    } else
588    {
589      o->next_picture();
590      return o->mover(xm,ym,but);
591    }
592  }
593  return 0;
594}
595
596
597void *cop_mover(int xm, int ym, int but)
598{
599
600  int ret=0;
601  game_object *o=current_object,*top;
602  if (o->controller() && o->controller()->freeze_time) 
603  {
604    o->controller()->freeze_time--;
605    if (but || o->controller()->key_down(JK_SPACE) || o->controller()->key_down(JK_ENTER))
606      o->controller()->freeze_time=0;
607  }
608  else
609  {
610    if (!o->total_objects())                  // if no top create one
611    {
612      top=create(S_MGUN_TOP,o->x,o->y,0,0);
613      current_level->add_object_after(top,o);   
614      o->add_object(top);
615      top->add_object(o);
616    } else top=o->get_object(0);
617
618    if (o->yvel()>10)
619    {
620      o->set_yacel(0);
621      o->set_yvel(o->yvel()-1);            // terminal velocity
622    }
623
624    if (o->aistate()==0)  // just started, wait for button
625    {
626      o->set_aistate(1);   
627    } else if (o->aistate()==1)         // normal play
628    {
629      if (o->hp()==0)
630      {
631        o->set_aistate(2);                // go to deing state
632        o->set_state(dead);     
633      }
634      else
635      {
636        if (o->hp()<40 && (current_level->tick_counter()%16)==0) // if low on health play heart beat   
637          the_game->play_sound(S_LOW_HEALTH_SND,127,o->x,o->y);
638        else if (o->hp()<15 && (current_level->tick_counter()%8)==0) // if low on health play heart beat
639          the_game->play_sound(S_LOW_HEALTH_SND,127,o->x,o->y);
640        else if (o->hp()<7 && (current_level->tick_counter()%4)==0) // if low on health play heart beat
641          the_game->play_sound(S_LOW_HEALTH_SND,127,o->x,o->y);
642
643        if (but&1)
644        do_special_power(o,xm,ym,but,top);
645        else
646        undo_special_power(o);
647        ret=player_move(o,xm,ym,but);
648        top->x=o->x;
649        top->y=o->y+29-top->picture()->height();
650       
651        if ((but&2) && !o->lvars[is_teleporting] && o->state!=S_climbing && o->state!=S_climb_off)
652        {
653          void *args=NULL;
654          p_ref r1(args);
655          view *v=o->controller();
656
657          push_onto_list(new_lisp_number(v->weapon_total(v->current_weapon)),args);
658          push_onto_list(l_FIRE,args);
659
660          current_object=top;
661          void *ret=eval_function((lisp_symbol *)figures[top->otype]->get_fun(OFUN_USER_FUN),args);       
662          current_object=o;
663          v->add_ammo(v->current_weapon,lnumber_value(ret));   
664        }
665      }
666    } else if (o->aistate()==3)
667    {
668      if (!o->controller() || o->controller()->key_down(JK_SPACE))
669      {
670        eval_function((lisp_symbol *)l_restart_player,NULL);  // call teh user function to reset the player
671        o->controller()->reset_player();
672        o->set_aistate(0);     
673      } else if (o->controller() && o->controller()->local_player())
674        the_game->show_help(symbol_str("space_cont"));
675
676    } else o->set_aistate(o->aistate()+1);
677  }
678
679  return new_lisp_number(ret);
680}
681
682
683
684void *ladder_ai()
685{
686  view *f=player_list;
687  game_object *o=current_object;
688  if (o->total_objects())
689  {
690    game_object *other=o->get_object(0);
691    for (;f;f=f->next)
692    {
693      int mex=f->focus->x;
694      int mey=f->focus->y;
695     
696      if (o->x<=mex && o->y<=mey && other->x>=mex && other->y>=mey)
697      {
698        if (f->focus->state==S_climbing)
699          f->focus->x=(o->x+other->x)/2;
700        f->focus->lvars[in_climbing_area]=mey-o->y;     
701      }
702    }
703  }
704  return true_symbol;
705}
706
707
708
709void *player_draw(int just_fired_var, int num)
710{
711  game_object *o=current_object;
712  if (num==0)
713  {
714    if (o->lvars[just_fired_var])
715    {
716      o->draw_tint(S_bright_tint);
717      o->lvars[just_fired_var]=0;
718    } else
719      o->drawer();
720  }
721  else
722  {
723    if (o->lvars[just_fired_var])
724    {
725      o->draw_double_tint(lnumber_value(lget_array_element(symbol_value(l_player_tints),num)),S_bright_tint);
726      o->lvars[just_fired_var]=0;
727    } else
728      o->draw_tint(lnumber_value(lget_array_element(symbol_value(l_player_tints),num)));
729  }
730  return NULL;
731}
732
733
734void *top_draw()
735{
736  game_object *o=current_object;
737  if (o->total_objects())
738  {
739    game_object *bot=o->get_object(0);
740    if (bot->state==stopped  || bot->state==running ||
741        bot->state==run_jump || bot->state==run_jump_fall ||
742        bot->state==end_run_jump)
743    {
744      int oldy=o->y;
745      o->x=bot->x;
746      if (bot->direction<0)
747        o->x+=4;
748      o->y=bot->y+29-bot->picture()->height();
749
750      void *ret=NULL;
751      p_ref r1(ret);
752
753      push_onto_list(new_lisp_number(bot->controller()->player_number),ret);
754
755      if (bot->lvars[special_power]==SNEAKY_POWER)
756      {
757        if (bot->lvars[used_special_power]==0)
758          player_draw(top_just_fired,bot->controller()->player_number);
759        else if (bot->lvars[used_special_power]<15)
760          o->draw_trans(bot->lvars[used_special_power],16);
761        else
762          o->draw_predator();
763      } else
764        eval_function((lisp_symbol *)l_player_draw,ret);
765     
766      o->y=oldy;
767      if (bot->direction<0)
768        o->x-=4;
769    }
770  }
771  return NULL;
772}
773
774
775
776void *bottom_draw()
777{
778  game_object *o=current_object;
779
780  if (o->lvars[r_ramp] || o->lvars[g_ramp] || o->lvars[b_ramp])
781  {
782    int r=o->lvars[r_ramp];
783    if (r>7) r-=7;
784    else r=0;
785    o->lvars[r_ramp]=r;
786
787    int g=o->lvars[g_ramp];
788    if (g>7) g-=7;
789    else g=0;
790    o->lvars[g_ramp]=g;
791
792    int b=o->lvars[b_ramp];
793    if (b>7) b-=7;
794    else b=0;
795    o->lvars[b_ramp]=b;
796
797    palette *p=pal->copy();
798    uint8_t *addr=(uint8_t *)p->addr();
799    int ra,ga,ba;
800   
801    for (int i=0;i<256;i++)
802    {
803      ra=(int)*addr+r; if (ra>255) ra=255; else if (ra<0) r=0; *addr=(uint8_t)ra; addr++;
804      ga=(int)*addr+g; if (ga>255) ga=255; else if (ga<0) g=0; *addr=(uint8_t)ga; addr++;
805      ba=(int)*addr+b; if (ba>255) ba=255; else if (ba<0) b=0; *addr=(uint8_t)ba; addr++;
806    }
807    p->load();
808    delete p;
809  }
810
811  if (o->aistate()>0)
812  {
813    switch (o->lvars[special_power])
814    {
815      case NO_POWER :
816      { player_draw(just_fired,o->controller()->player_number); } break;
817
818      case HEALTH_POWER :
819      {
820        player_draw(just_fired,o->controller()->player_number);
821        if (o->controller() && o->controller()->local_player())
822          cash.img(S_health_image)->put_image(screen,o->controller()->cx2-20,
823                                            o->controller()->cy1+5,1);
824      } break;
825      case FAST_POWER :
826      {
827        eval_function((lisp_symbol *)l_draw_fast,NULL);
828        int old_state=o->state;
829        switch (o->state)
830        {
831          case stopped : o->state=(character_state)S_fast_stopped; break;
832          case running : o->state=(character_state)S_fast_running; break;
833          case start_run_jump : o->state=(character_state)S_fast_start_run_jump; break;
834          case run_jump : o->state=(character_state)S_fast_run_jump; break;
835          case run_jump_fall : o->state=(character_state)S_fast_run_jump_fall; break;
836          case end_run_jump : o->state=(character_state)S_fast_end_run_jump; break;
837          default: break;
838        }
839
840        player_draw(just_fired,o->controller()->player_number);
841        o->state=(character_state)old_state;
842        if (o->controller() && o->controller()->local_player())
843          cash.img(S_fast_image)->put_image(screen,o->controller()->cx2-20,
844                                            o->controller()->cy1+5,1);
845      } break;
846      case FLY_POWER :
847      {
848        int old_state=o->state;
849        switch (o->state)
850        {
851          case stopped : o->state=(character_state)S_fly_stopped; break;
852          case running : o->state=(character_state)S_fly_running; break;
853          case start_run_jump : o->state=(character_state)S_fly_start_run_jump; break;
854          case run_jump : o->state=(character_state)S_fly_run_jump; break;
855          case run_jump_fall : o->state=(character_state)S_fly_run_jump_fall; break;
856          case end_run_jump : o->state=(character_state)S_fly_end_run_jump; break;
857          default: break;
858        }
859
860        player_draw(just_fired,o->controller()->player_number);
861        o->state=(character_state)old_state;
862
863        if (o->controller() && o->controller()->local_player())
864          cash.img(S_fly_image)->put_image(screen,o->controller()->cx2-20,
865                                            o->controller()->cy1+5,1);
866      } break;
867      case SNEAKY_POWER :
868      {
869        if (o->lvars[used_special_power]==0)
870          player_draw(just_fired,o->controller()->player_number);
871        else if (o->lvars[used_special_power]<15)
872          o->draw_trans(o->lvars[used_special_power],16);
873        else
874          o->draw_predator();
875         
876        if (o->controller() && o->controller()->local_player())
877          cash.img(S_sneaky_image)->put_image(screen,o->controller()->cx2-20,
878                                            o->controller()->cy1+5,1);
879      } break;
880    }   
881  }
882  return NULL;
883}
884
885
886
887void *sgun_ai()
888{
889  game_object *o=current_object;
890
891  if (o->lvars[sgb_lifetime]==0)
892    return NULL;
893  o->lvars[sgb_lifetime]--;
894
895  o->lvars[sgb_lastx]=o->x;
896  o->lvars[sgb_lasty]=o->y;
897  o->lvars[sgb_speed]=o->lvars[sgb_speed]*6/5;
898 
899  int32_t ang=o->lvars[sgb_angle];
900  int32_t mag=o->lvars[sgb_speed];
901
902  int32_t xvel=(lisp_cos(ang))*(mag);
903  current_object->set_xvel(xvel>>16);
904  current_object->set_fxvel((xvel&0xffff)>>8);
905  int32_t yvel=-(lisp_sin(ang))*(mag);
906  current_object->set_yvel(yvel>>16);
907  current_object->set_fyvel((yvel&0xffff)>>8);     
908
909
910  int whit=0;
911  game_object *who=o->bmove(whit, o->total_objects() ? o->get_object(0) : 0);
912
913  if (whit || (who && figures[who->otype]->get_cflag(CFLAG_UNACTIVE_SHIELD) && who->total_objects() &&
914               who->get_object(0)->aistate()==0))
915  {
916    o->lvars[sgb_lifetime]=0;
917    game_object *n=create(S_EXPLODE5,o->x+jrand()%4,o->y+jrand()%4);
918    current_level->add_object(n);   
919  } else if (who && figures[who->otype]->get_cflag(CFLAG_HURTABLE))
920  {
921    o->lvars[sgb_lifetime]=0;
922    game_object *n=create(S_EXPLODE3,o->x+jrand()%4,o->y+jrand()%4);
923    current_level->add_object(n);       
924     who->do_damage(5,o,o->x,o->y,(lisp_cos(ang)*10)>>16,(lisp_sin(ang)*10)>>16);
925  }
926  return true_symbol;
927}
928
929
930
931void *mover_ai()
932{
933  game_object *o=current_object;
934  if (o->total_objects()==2)
935  {
936    if (o->aistate()<2)
937    {
938      game_object *obj=o->get_object(1);
939      o->remove_object(obj);
940      game_object *d=o->get_object(0);
941      d->add_object(obj);
942      d->set_aistate(d->aitype());
943    } else
944    {
945      o->set_aistate(o->aistate()-1);
946      game_object *d=o->get_object(0);
947      game_object *obj=o->get_object(1);     
948
949      obj->x=d->x-(d->x-o->x)*o->aistate()/o->aitype();
950      obj->y=d->y-(d->y-o->y)*o->aistate()/o->aitype();
951    }
952  }
953  return true_symbol;
954}       
955
956
957void *respawn_ai()
958{
959 game_object *o=current_object;
960 int x=o->total_objects();
961 if (x)
962 {
963   game_object *last=o->get_object(x-1);
964   if (last->x==o->x && last->y==o->y)
965   {
966     if (last->fade_count())
967       last->set_fade_count(last->fade_count()-1);
968     o->set_aistate_time(0);
969   } else if (o->aistate_time()>o->xvel())
970   {
971     int type=o->get_object(jrandom(x))->otype;
972     game_object *n=create(type,o->x,o->y);
973     current_level->add_object(n);
974     o->add_object(n);
975     n->set_fade_count(15);
976     o->set_aistate_time(0);
977   }
978 }
979 return true_symbol;
980}
981
982static int compare_players(const void *a, const void *b)
983{
984  if  ( ((view **)a)[0]->kills > ((view **)b)[0]->kills)
985    return -1;
986  else if  ( ((view **)a)[0]->kills < ((view **)b)[0]->kills)
987    return 1;
988  else if (((view **)a)[0]->player_number > ((view **)b)[0]->player_number)
989    return -1;
990  else if (((view **)a)[0]->player_number < ((view **)b)[0]->player_number)
991    return 1;
992  else return 0; 
993}
994
995void *score_draw()
996{
997  view *sorted_players[16],*local=NULL;
998  int tp=0;
999  view *f=player_list;
1000  for (;f;f=f->next)
1001  {
1002    sorted_players[tp]=f;
1003    tp++;
1004    if (f->local_player()) local=f;
1005  }
1006
1007  JCFont *fnt=eh->font();
1008  if (local)
1009  {
1010    qsort(sorted_players,tp,sizeof(view *),compare_players);
1011
1012    int x=local->cx1;
1013    int y=local->cy1;
1014    char msg[100];
1015
1016    int i;
1017    for (i=0;i<tp;i++)
1018    {
1019      int color=lnumber_value(lget_array_element(symbol_value(l_player_text_color),sorted_players[i]->player_number)); 
1020      sprintf(msg,"%3ld %s",(long)sorted_players[i]->kills,sorted_players[i]->name);
1021      if (sorted_players[i]==local)
1022        strcat(msg," <<");
1023
1024      fnt->put_string(screen,x,y,msg,color);
1025      y+=fnt->height();
1026    }
1027  }
1028  return NULL;
1029}
1030
1031
1032extern void fade_in(image *im, int steps);
1033extern void fade_out(int steps);
1034
1035void *show_kills()
1036{
1037  fade_out(8);
1038  eh->set_mouse_position(0,0);
1039  screen->clear();
1040  image *im=cash.img(cash.reg("art/frame.spe","end_level_screen",SPEC_IMAGE,1));
1041  im->put_image(screen,0,0);
1042  int x1=im->width()+1,y1=0,y2=screen->height();
1043  JCFont *fnt=eh->font();
1044 
1045  view *v=player_list; int tp=0,i;
1046  for (v=player_list;v;v=v->next) tp++;
1047
1048  int y=(y1+y2)/2-(tp+2)*fnt->height()/2,x=x1+10;
1049  char const *header_str = symbol_str("score_header");
1050  fnt->put_string(screen,x,y,header_str,eh->bright_color());
1051  y+=fnt->height();
1052
1053  screen->wiget_bar(x,y+2,x+strlen(header_str)*fnt->width(),y+fnt->height()-3,
1054                     eh->bright_color(),eh->medium_color(),eh->dark_color());
1055  y+=fnt->height();
1056  v=player_list;
1057  for (i=0;i<tp;i++)
1058  {
1059    enum { NAME_LEN=18 } ;
1060    int color=lnumber_value(lget_array_element(symbol_value(l_player_text_color),v->player_number)); 
1061    char max_name[NAME_LEN];
1062    strncpy(max_name,v->name,NAME_LEN-1);
1063    max_name[NAME_LEN-1]=0;
1064    char msg[100];
1065
1066
1067    sprintf(msg,"%-17s %3ld  %3ld",max_name,(long)v->kills,(long)(v->tkills+v->kills));
1068    fnt->put_string(screen,x,y,msg,color);
1069
1070    y+=fnt->height();
1071    v=v->next;
1072  }
1073 
1074  eh->flush_screen();
1075  milli_wait(4000);   // wait 4 seconds
1076
1077  return NULL;
1078}
1079
1080
Note: See TracBrowser for help on using the repository browser.