source: abuse/trunk/src/go.cpp @ 555

Last change on this file since 555 was 555, checked in by Sam Hocevar, 11 years ago

ps3: make everything compile on the PS3. Of course, nothing links yet
because so much support is missing.

File size: 8.0 KB
RevLine 
[56]1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
[494]4 *  Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
[56]5 *
6 *  This software was released into the Public Domain. As with most public
[555]7 *  domain software, no warranty is made or implied by Crack dot Com, by
8 *  Jonathan Clark, or by Sam Hocevar.
[56]9 */
10
[555]11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
[56]14
[481]15#include "go.h"
16#include "level.h"
17#include "game.h"
18#include "id.h"
19#include "signals.h"
[2]20
21#define EL_WAIT_MOVEMENT 1           // wait for the user to press up or down
22#define EL_SKIP_SIGNAL   2
23#define EL_WAIT_SIGNAL   3
24#define EL_WAIT_SKIP     4
25
26
27void elcontrol::draw()
28{
29  if (dev & EDIT_MODE)
30    game_object::draw();
31
32}
33
[124]34ifield *elevator::make_fields(int ystart, ifield *Next)
[2]35{
[124]36  int H=10;
[2]37  return new text_field(5,ystart+H*0,ELEVATOR_SPEED,"speed",              "#####",speed,
38         new text_field(5,ystart+H*1,ELEVATOR_DIR,"heading dir",          "#####",dir,
[494]39         new text_field(5,ystart+H*2,ELEVATOR_DIRECTION,"facing dir",     "#####",direction,
[124]40            NULL)));
41}
[2]42
[124]43void elevator::gather_input(InputManager *inm)
44{
45  dir=atoi(inm->get(ELEVATOR_DIR)->read());
46  speed=atoi(inm->get(ELEVATOR_SPEED)->read());
47  direction=atoi(inm->get(ELEVATOR_DIRECTION)->read());
48  if (direction==0) direction=1;
[2]49}
50
51
52
53ifield *elcontrol::make_fields(int ystart,ifield *Next)
54{
55  int H=10;
[124]56  return new text_field(5,ystart+H*0,ELCONTROL_ALLOW_DIR,"stop dir","#####",allow_dir,NULL);
[2]57}
58
[120]59void elcontrol::gather_input(InputManager *inm)
[2]60{
[124]61  allow_dir=atoi(inm->get(ELCONTROL_ALLOW_DIR)->read());
[2]62}
63
64
65elcontrol::elcontrol(long X, long Y)
66{
67  defaults();
68  x=X;
69  y=Y;
[124]70  allow_dir=0;
[2]71}
72
73elcontrol::elcontrol(FILE *fp, unsigned char *state_remap)
74{
75  load(fp,state_remap);
[17]76  allow_dir=read_uint16(fp);
[2]77}
78
79
80
81
82
83int elevator::can_block(game_object *who)
[124]84{
[2]85  if (who!=this)
[124]86    return 1;
[2]87  else return 0;
[124]88
[2]89}
90
91
92void elevator::draw()  // draw cables above the elevator
93{
94  game_object::draw();
95  long x1,y1,x2,y2,sy1,sy2,sx,i;
[124]96  picture_space(x1,y1,x2,y2);
[2]97
98  sx=the_game->screenx(x1);
99
[124]100  sy2=the_game->screeny(y1);
[2]101  if (sy2>=the_game->viewy1)
102  {
103    long draw_to=y1-(sy2-the_game->viewy1),tmp=x;
[124]104    current_level->foreground_intersect(x,y1,tmp,draw_to);
[2]105    sy1=the_game->screeny(draw_to);
106    sy1=max(the_game->viewy1,sy1);
107    sy2=min(the_game->viewy2,sy2);
[541]108    TransImage *p=picture();
[124]109
[494]110    for (i=sy1; i<=sy2; i++)
[532]111      p->PutScanLine(screen,sx,i,0);
[124]112  }
[2]113}
114
115
116elevator::elevator(long X, long Y)
117{
118  defaults();
119  x=X;
[124]120  y=Y;
[2]121  dir=0;
[124]122  speed=3;
[2]123}
124
125int elevator::size()
[124]126{
127  return game_object::size()+4;
[2]128}
129
130
131elevator::elevator(FILE *fp, unsigned char *state_remap)
132{
[124]133  load(fp,state_remap);
134  dir=read_uint16(fp);
135  speed=read_uint16(fp);
[2]136}
137
[124]138void elevator::save(FILE *fp)
139{
140  game_object::save(fp);
141  write_uint16(fp,dir);
142  write_uint16(fp,speed);
[2]143}
144
145
146elcontrol *elevator::find_stop()
147{
148  long x1,y1,x2,y2;
[124]149  picture_space(x1,y1,x2,y2);
[2]150  int i;
[124]151  game_object **o=current_level->obj;
[494]152  for (i=current_level->first_object(); i>=0; i=o[i]->next_active)
[124]153  {
[2]154    if (o[i]->type()==O_elcontrol)
155    {
156      int yd=o[i]->y-y;
157      if (abs(yd)<=speed && o[i]->x>x1 && o[i]->x<x2)
[124]158        return (elcontrol *)(o[i]);
[2]159    }
[124]160
[2]161  }
[124]162  return NULL;
[2]163}
164
165
166
167int elevator::decide()
168{
169  if (abs(dir)<=1)                                  // the elevator is stopped
170  {
171    switch (state)
172    {
[494]173      case stopped :
[2]174      {
175        long x1,y1,x2,y2;
[124]176    picture_space(x1,y1,x2,y2);
[2]177
178
[124]179    game_object *a=current_level->attacker(this);
[2]180                  // are we in the elevator?, if not wait for someone to get in
[124]181    if (a->x>x1+3 && a->x<x2-3 && a->y<y2 && a->y>y1+8)
182    {
183      int but,xm,ym;                          // wait for the user to press up or down
184      the_game->get_movement(but,xm,ym);      // see which way he wants to go
185      if (ym)
186      {
187        elcontrol *sp=find_stop();
188        if (ym<0 && (!sp || sp->allow_dir>=0))
189          dir=-1;
190        else if (ym>0 && (!sp || sp->allow_dir<=0))
191          dir=1;
192        if (dir)
193        {
194          if (has_sequence(start_still_jump))
195            set_state(start_still_jump);         // close the door
196          else
197            dir=dir+dir;                     // elevator doesn't have a door, start moving
198        }
[2]199      }
[124]200    }
201    break;
202      }
[2]203      case start_still_jump :
[124]204    next_picture();
205    if (end_of_sequence())                // door closed yet?
206    {
207      set_state(still_jump);              // we can start moving now
208      dir=dir+dir;
[494]209    }
[124]210    break;
[2]211      case still_jump :                       // just stopped, open the doors
[124]212    set_state(end_still_jump);
213    break;
[2]214      case end_still_jump :
[124]215    next_picture();
216    if (end_of_sequence())                // wait for doors to finish opening
217      set_state(stopped);
218    break;
[2]219      default :
[124]220    CHECK(0);
221    }
222  }
[2]223
224  if (abs(dir)>1)                     // are we moving?
225  {
226    next_picture();
227    int adder;
228    if (dir<0)                         // how much do we move this tick?
229      adder=-speed;
230    else adder=speed;
231
232    if (abs(dir)==8)                   // are we checking for stops yet?
233    {
234      elcontrol *s=find_stop();
235      if (s)                           // found one, stop or slow down
[124]236      {
237    adder=s->y-y;
238    if (!adder)
239          dir=0;
240      }
[2]241    } else dir=dir+dir;
[124]242
[2]243    if (dir)                                   // make sure move, wasn't canceled by a stop
244    {
245      if (!current_level->crush(this,0,adder)) // see if we can crush anyone (I hope so! :) )
[124]246      {
247    y+=adder;
248    current_level->push_characters(this,0,adder);
[2]249      } else dir=0;                           // we crushed, stop the elevator and wait on user
250    }
251  }
252
253  return 1;                                   // return not dead, can't kill elevators
254}
255
256
257char *sensor::aname()
258{
259  if (activate==-1)
260    return "FOCUS";
[124]261  else return object_names[activate];
[2]262}
263
264void sensor::get_activate(char *name)
265{
[124]266  int i;
267  activate=-1;  // if we can't fnd the name then go focus
[494]268  for (i=0; i<TOTAL_OBJECTS; i++)
[2]269    if (!strcmp(name,object_names[i]))
[124]270      activate=i;
[2]271}
272
273
274
275
[124]276int sensor::size()
277{
278  return game_object::size()+2*3+(strlen(aname())+2);
[2]279}
280
281
[124]282void sensor::save(FILE *fp)
283{ game_object::save(fp);
[17]284  write_uint16(fp,xrange);
285  write_uint16(fp,yrange);
[124]286  write_uint16(fp,signal);
[2]287
[17]288  write_uint8(fp,strlen(aname())+1);
[124]289  fwrite(aname(),strlen(aname())+1,1,fp);
[2]290}
291
292sensor::sensor(FILE *fp, unsigned char *state_remap)
293{
294  load(fp,state_remap);
[17]295  xrange=read_uint16(fp);
296  yrange=read_uint16(fp);
[124]297  signal=read_uint16(fp);
[2]298
299  char name[200];
[17]300  fread(name,read_uint8(fp),1,fp);
[2]301  get_activate(name);
302}
303
304int sensor::decide()
[124]305{
[2]306  int i;
307  game_object **o=current_level->obj;
308  long x1,y1,x2,y2;
309  if (activate==-1)
310  {
[124]311    current_level->attacker(this)->picture_space(x1,y1,x2,y2);
[2]312    if (x+xrange>=x1 && x-xrange<=x2 && y+yrange>=y1 && y-yrange<=y2)
[124]313      current_level->send_signal(signal);
[2]314  }
315  else
[124]316  {
[494]317    for (i=current_level->first_object(); i>=0; i=o[i]->next_active)
[2]318    {
[124]319      long x1,y1,x2,y2;
[2]320      if (o[i]->type()==activate)
[494]321      {
[124]322    o[i]->picture_space(x1,y1,x2,y2);
323    if (x+xrange>=x1 && x-xrange<=x2 && y+yrange>=y1 && y-yrange<=y2)
[494]324    {
[124]325          current_level->send_signal(signal);
326      return 1;          // only send one signal!
[494]327    }
[2]328      }
[124]329    }
[2]330  }
331  return 1;
332}
333
334
335
336
337void sensor::draw()
338{
339  if (dev & EDIT_MODE)
[124]340  {
[2]341    game_object::draw();
[124]342    int sx=the_game->screenx(x),sy=the_game->screeny(y);
343    screen->rectangle(sx-xrange,sy-yrange,sx+xrange,sy+yrange,wm->bright_color());
344  }
[2]345}
346
347
[124]348ifield *sensor::make_fields(int ystart, ifield *Next)
349{
[2]350  int H=10;
351  return new text_field(5,ystart+H*0,SENSOR_XRANGE,   "xrange",    "#####",xrange,
[124]352     new text_field(5,ystart+H*1,SENSOR_YRANGE,   "yrange",    "#####",yrange,
353     new text_field(5,ystart+H*2,SENSOR_SIGNAL,   "signal",    "#####",signal,
354     new text_field(5,ystart+H*3,SENSOR_ACTIVATE, "activator", "####################",aname(),
355            NULL))));
[2]356}
357
358
[120]359void sensor::gather_input(InputManager *inm)
[2]360{
361  xrange=atoi(inm->get(SENSOR_XRANGE)->read());
362  yrange=atoi(inm->get(SENSOR_XRANGE)->read());
363  signal=atoi(inm->get(SENSOR_SIGNAL)->read());
364  get_activate(inm->get(SENSOR_ACTIVATE)->read());
[494]365}
[2]366
Note: See TracBrowser for help on using the repository browser.