1 /*
2  *  Abuse - dark 2D side-scrolling platform game
3  *  Copyright (c) 1995 Crack dot Com
4  *  Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
5  *
6  *  This software was released into the Public Domain. As with most public
7  *  domain software, no warranty is made or implied by Crack dot Com, by
8  *  Jonathan Clark, or by Sam Hocevar.
9  */
10 
11 
12 #ifndef __LEVEL_HPP_
13 #define __LEVEL_HPP_
14 
15 #include "specs.h"
16 #include "objects.h"
17 #include "view.h"
18 #include "id.h"
19 
20 #include <stdlib.h>
21 #define ASPECT 4             // foreground scrolls 4 times faster than background
22 
23 
24 // the following defines the area of activity for objects
25 // when they are out of this are no processing occurs on them
26 // region is specified from upper left corner of screen
27 #define ACTIVE_LEFT 500
28 #define ACTIVE_RIGHT (280+500)
29 #define ACTIVE_TOP 200
30 #define ACTIVE_BOTTOM (180+200)
31 #define fgvalue(y) ((y) & 0x3fff)
32 #define above_tile(y) ((y) & 0x4000)
33 #define bgvalue(y) (y)
34 
35 class area_controller
36 {
37   public :
38   int32_t x,y,w,h,active;
39   int32_t ambient,view_xoff,view_yoff;
40   int32_t ambient_speed, view_xoff_speed,view_yoff_speed;
41   area_controller *next;
42   area_controller(int32_t X, int32_t Y, int32_t W, int32_t H, area_controller *Next);
43 } ;
44 
45 extern int32_t last_tile_hit_x,last_tile_hit_y;
46 extern int dev;
47 class level        // contain map info and objects
48 {
49   uint16_t *map_fg,        // just big 2d arrays
50            *map_bg,
51        bg_width,bg_height,
52        fg_width,fg_height;
53   char *Name,*first_name;
54   int32_t total_objs;
55   game_object *first,*first_active,*last;
56 
57   game_object **attack_list;                // list of characters for tick which can attack someone
58   int attack_list_size,attack_total;
59   void add_attacker(game_object *who);
60 
61   game_object **target_list;                // list of characters for tick which can be attacked
62   int target_list_size,target_total;
63   void add_target(game_object *who);
64 
65   game_object **block_list;                // list of characters who can block a character
66   int block_list_size,block_total;
67   void add_block(game_object *who);
68 
69   void remove_block(game_object *who);
70   void remove_all_block(game_object *who);
71 
72   game_object **all_block_list;            // list of characters who can block a character or can be hurt
73   int all_block_list_size,all_block_total;
74   void add_all_block(game_object *who);
75   uint32_t ctick;
76 
77 public :
original_name()78   char *original_name() { if (first_name) return first_name; else return Name; }
tick_counter()79   uint32_t tick_counter() { return ctick; }
80   void set_tick_counter(uint32_t x);
81   area_controller *area_list;
82 
clear_active_list()83   void clear_active_list() { first_active=NULL; }
name()84   char *name() { return Name; }
85   game_object *attacker(game_object *who);
86   int is_attacker(game_object *who);
87   game_object *main_character();
88 
first_object()89   game_object *first_object() { return first; }
first_active_object()90   game_object *first_active_object() { return first_active; }
foreground_width()91   uint16_t foreground_width() { return fg_width; }
foreground_height()92   uint16_t foreground_height() { return fg_height; }
background_width()93   uint16_t background_width() { return bg_width; }
background_height()94   uint16_t background_height() { return bg_height; }
load_failed()95   int load_failed() { return map_fg==NULL; }
96   level(spec_directory *sd, bFILE *fp, char const *lev_name);
97   void load_fail();
98   level(int width, int height, char const *name);
99   int save(char const *filename, int save_all);  // save_all includes player and view information (1 = success)
set_name(char const * name)100   void set_name(char const *name) { Name=strcpy((char *)realloc(Name,strlen(name)+1),name); }
101   void set_size(int w, int h);
102   void remove_light(light_source *which);
103   void try_pushback(game_object *subject,game_object *target);
104   ~level();
105 
fg_raised(int x,int y)106   int fg_raised(int x, int y) { CHECK(x>=0 && y>=0 && x<fg_width && y<fg_height);
107                  return (*(map_fg+x+y*fg_width))&0x4000; }
fg_set_raised(int x,int y,int r)108   void fg_set_raised(int x, int y, int r) { CHECK(x>=0 && y>=0 && x<fg_width && y<fg_height);
109                         uint16_t v=(*(map_fg+x+y*fg_width))&(0xffff-0x4000);
110                         if (r) (*(map_fg+x+y*fg_width))=v|0x4000;
111                         else (*(map_fg+x+y*fg_width))=v;
112                       }
mark_seen(int x,int y)113   void mark_seen(int x, int y) { CHECK(x>=0 && y>=0 && x<fg_width && y<fg_height);
114                       (*(map_fg+x+y*fg_width))|=0x8000; }
clear_fg(int32_t x,int32_t y)115   void clear_fg(int32_t x, int32_t y) { *(map_fg+x+y*fg_width)&=0x7fff; }
116 
get_fgline(int y)117   uint16_t *get_fgline(int y) { CHECK(y>=0 && y<fg_height); return map_fg+y*fg_width; }
get_bgline(int y)118   uint16_t *get_bgline(int y) { CHECK(y>=0 && y<bg_height); return map_bg+y*bg_width; }
get_fg(int x,int y)119   uint16_t get_fg(int x, int y) { if (x>=0 && y>=0 && x<fg_width && y<fg_height)
120                               return fgvalue(*(map_fg+x+y*fg_width));
121                                     else return 0;
122                       }
get_bg(int x,int y)123   uint16_t get_bg(int x, int y) { if (x>=0 && y>=0 && x<bg_width && y<bg_height)
124                       return *(map_bg+x+y*bg_width);
125                                      else return 0;
126                     }
put_fg(int x,int y,uint16_t tile)127   void put_fg(int x, int y, uint16_t tile) { *(map_fg+x+y*fg_width)=tile; }
put_bg(int x,int y,uint16_t tile)128   void put_bg(int x, int y, uint16_t tile) { *(map_bg+x+y*bg_width)=tile; }
129   void draw_objects(view *v);
130   void interpolate_draw_objects(view *v);
131   void draw_areas(view *v);
132   int tick();                                // returns false if character is dead
133   void check_collisions();
134   void wall_push();
135   void add_object(game_object *new_guy);
136   void add_object_after(game_object *new_guy, game_object *who);
137   void delete_object(game_object *who);
138   void remove_object(game_object *who);      // unlinks the object from level, but doesn't delete it
139   void load_objects(spec_directory *sd, bFILE *fp);
140   void load_cache_info(spec_directory *sd, bFILE *fp);
141   void old_load_objects(spec_directory *sd, bFILE *fp);
142   void load_options(spec_directory *sd, bFILE *fp);
143   void write_objects(bFILE *fp, object_node *save_list);
144   void write_options(bFILE *fp);
145   void write_thumb_nail(bFILE *fp, image *im);
146   void write_cache_prof_info();
147   void restart();
148 
149 
150   void unactivate_all();
151   // forms all the objects in processing range into a linked list
152   int add_actives(int32_t x1, int32_t y1, int32_t x2, int32_t y2);  //returns total added
153   void pull_actives(game_object *o, game_object *&last_active, int &t);
154   int add_drawables(int32_t x1, int32_t y1, int32_t x2, int32_t y2);  //returns total added
155 
156   game_object *find_object(int32_t x, int32_t y);
157 
158   game_object *damage_intersect(int32_t x1, int32_t y1, int32_t &x2, int32_t &y2, game_object *exclude);
159   game_object *boundary_setback(game_object *subject, int32_t x1, int32_t y1, int32_t &x2, int32_t &y2);
160   game_object *all_boundary_setback(game_object *subject, int32_t x1, int32_t y1, int32_t &x2, int32_t &y2);
161   int crush(game_object *by_who, int xamount, int yamount);
162   int push_characters(game_object *by_who, int xamount, int yamount);  // return 0 if fail on any.
163   int platform_push(game_object *by_who, int xamount, int yamount);
164   void foreground_intersect(int32_t x1, int32_t y1, int32_t &x2, int32_t &y2);
165   void vforeground_intersect(int32_t x1, int32_t y1, int32_t &y2);
166 
167   void hurt_radius(int32_t x, int32_t y,int32_t r, int32_t m, game_object *from, game_object *exclude,
168            int max_push);
169   void send_signal(int32_t signal);
170   void next_focus();
171   void to_front(game_object *o);
172   void to_back(game_object *o);
173   game_object *find_closest(int x, int y, int type, game_object *who);
174   game_object *find_xclosest(int x, int y, int type, game_object *who);
175   game_object *find_xrange(int x, int y, int type, int xd);
176   game_object *find_self(game_object *me);
177 
178 
179   void write_links(bFILE *fp, object_node *save_list, object_node *exclude_list);
180   void load_links(bFILE *fp, spec_directory *sd, object_node *save_list, object_node *exclude_list);
181 
182 
183   game_object *find_type(int type, int skip);
184   void insert_players();   // inserts the players into the level
185 
186 
187   game_object *get_random_start(int min_player_dist, view *exclude);
188 //  game_object *find_enemy(game_object *exclude1, game_object *exclude2);
189 
190   bFILE *create_dir(char *filename, int save_all,
191             object_node *save_list, object_node *exclude_list);
192   view *make_view_list(int nplayers);
193   int32_t total_light_links(object_node *list);
194   int32_t total_object_links(object_node *save_list);
195   game_object *find_object_in_area(int32_t x, int32_t y, int32_t x1, int32_t y1,
196                    int32_t x2, int32_t y2, Cell *list, game_object *exclude);
197   game_object *find_object_in_angle(int32_t x, int32_t y, int32_t start_angle, int32_t end_angle,
198                     void *list, game_object *exclude);
199   object_node *make_not_list(object_node *list);
200   int load_player_info(bFILE *fp, spec_directory *sd, object_node *save_list);
201   void write_player_info(bFILE *fp, object_node *save_list);
202   void write_object_info(char *filename);
203   void level_loaded_notify();
204 } ;
205 
206 extern level *current_level;
207 void pull_actives(game_object *o, game_object *&last_active, int &t);
208 
209 
210 
211 #endif
212 
213 
214 
215 
216 
217 
218 
219 
220 
221 
222 
223 
224 
225 
226 
227 
228 
229