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