Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
| #include "map.h" | |
| #include "omdata.h" | |
| #include "mapitems.h" | |
| #include "output.h" | |
| #include "game.h" | |
| #include "rng.h" | |
| #include "line.h" | |
| #include "debug.h" | |
| #ifndef sgn | |
| #define sgn(x) (((x) < 0) ? -1 : 1) | |
| #endif | |
| #define dbg(x) dout((DebugLevel)(x),D_MAP_GEN) << __FILE__ << ":" << __LINE__ << ": " | |
| ter_id grass_or_dirt() | |
| { | |
| if (one_in(4)) | |
| { | |
| return t_grass; | |
| } | |
| return t_dirt; | |
| } | |
| ter_id dirt_or_pile() | |
| { | |
| if (one_in(4)) | |
| { | |
| return t_dirtmound; | |
| } | |
| return t_dirt; | |
| } | |
| enum room_type | |
| { | |
| room_null, | |
| room_closet, | |
| room_lobby, | |
| room_chemistry, | |
| room_teleport, | |
| room_goo, | |
| room_cloning, | |
| room_vivisect, | |
| room_bionics, | |
| room_dorm, | |
| room_living, | |
| room_bathroom, | |
| room_kitchen, | |
| room_bedroom, | |
| room_mine_shaft, | |
| room_mine_office, | |
| room_mine_storage, | |
| room_mine_fuel, | |
| room_mine_housing, | |
| room_bunker_bots, | |
| room_bunker_launcher, | |
| room_bunker_rifles, | |
| room_bunker_grenades, | |
| room_bunker_armor, | |
| room_mansion_courtyard, | |
| room_mansion_entry, | |
| room_mansion_bedroom, | |
| room_mansion_library, | |
| room_mansion_kitchen, | |
| room_mansion_dining, | |
| room_mansion_game, | |
| room_mansion_pool, | |
| room_mansion_bathroom, | |
| room_mansion_gallery, | |
| room_split | |
| }; | |
| bool connects_to(oter_id there, int dir_from_here); | |
| void house_room(map* m, room_type type, int x1, int y1, int x2, int y2); | |
| void science_room(map* m, int x1, int y1, int x2, int y2, int rotate); | |
| void set_science_room(map* m, int x1, int y1, bool faces_right, int turn); | |
| void silo_rooms(map* m); | |
| void build_mine_room(map* m, room_type type, int x1, int y1, int x2, int y2); | |
| map_extra random_map_extra(map_extras); | |
| room_type pick_mansion_room(int x1, int y1, int x2, int y2); | |
| void build_mansion_room(map* m, room_type type, int x1, int y1, int x2, int y2); | |
| void mansion_room(map* m, int x1, int y1, int x2, int y2); // pick & build | |
| void line(map* m, ter_id type, int x1, int y1, int x2, int y2); | |
| void square(map* m, ter_id type, int x1, int y1, int x2, int y2); | |
| void rough_circle(map* m, ter_id type, int x, int y, int rad); | |
| void add_corpse(game* g, map* m, int x, int y); | |
| void map::generate(game* g, overmap* om, int x, int y, int turn) | |
| { | |
| dbg(D_INFO) << "map::generate( g[" << g << "], om[" << (void*)om << "], x[" << x << "], " | |
| << "y[" << y << "], turn[" << turn << "] )"; | |
| // First we have to create new submaps and initialize them to 0 all over | |
| // We create all the submaps, even if we're not a tinymap, so that map | |
| // generation which overflows won't cause a crash. At the bottom of this | |
| // function, we save the upper-left 4 submaps, and delete the rest. | |
| for (int i = 0; i < my_MAPSIZE * my_MAPSIZE; i++) | |
| { | |
| grid[i] = new submap; | |
| grid[i]->active_item_count = 0; | |
| grid[i]->field_count = 0; | |
| grid[i]->turn_last_touched = turn; | |
| grid[i]->comp = computer(); | |
| for (int x = 0; x < SEEX; x++) | |
| { | |
| for (int y = 0; y < SEEY; y++) | |
| { | |
| grid[i]->ter[x][y] = t_null; | |
| grid[i]->trp[x][y] = tr_null; | |
| grid[i]->fld[x][y] = field(); | |
| grid[i]->rad[x][y] = 0; | |
| grid[i]->graf[x][y] = graffiti(); | |
| } | |
| } | |
| } | |
| oter_id terrain_type, t_north, t_east, t_south, t_west, t_above; | |
| unsigned zones = 0; | |
| int overx = x / 2; | |
| int overy = y / 2; | |
| if (x >= OMAPX * 2 || x < 0 || y >= OMAPY * 2 || y < 0) | |
| { | |
| dbg(D_INFO) << "map::generate: In section 1"; | |
| // This happens when we're at the very edge of the overmap, and are generating | |
| // terrain for the adjacent overmap. | |
| int sx = 0, sy = 0; | |
| overx = (x % (OMAPX * 2)) / 2; | |
| if (x >= OMAPX * 2) | |
| { | |
| sx = 1; | |
| } | |
| if (x < 0) | |
| { | |
| sx = -1; | |
| overx = (OMAPX * 2 + x) / 2; | |
| } | |
| overy = (y % (OMAPY * 2)) / 2; | |
| if (y >= OMAPY * 2) | |
| { | |
| sy = 1; | |
| } | |
| if (y < 0) | |
| { | |
| overy = (OMAPY * 2 + y) / 2; | |
| sy = -1; | |
| } | |
| overmap tmp(g, om->posx + sx, om->posy + sy, om->posz); | |
| terrain_type = tmp.ter(overx, overy); | |
| //zones = tmp.zones(overx, overy); | |
| if (om->posz < 0 || om->posz == 9) // 9 is for tutorial overmap | |
| { | |
| overmap tmp2 = overmap(g, om->posx, om->posy, om->posz + 1); | |
| t_above = tmp2.ter(overx, overy); | |
| } | |
| else | |
| { | |
| t_above = ot_null; | |
| } | |
| if (overy - 1 >= 0) | |
| { | |
| t_north = tmp.ter(overx, overy - 1); | |
| } | |
| else | |
| { | |
| t_north = om->ter(overx, OMAPY - 1); | |
| } | |
| if (overx + 1 < OMAPX) | |
| { | |
| t_east = tmp.ter(overx + 1, overy - 1); | |
| } | |
| else | |
| { | |
| t_east = om->ter(0, overy); | |
| } | |
| if (overy + 1 < OMAPY) | |
| { | |
| t_south = tmp.ter(overx, overy + 1); | |
| } | |
| else | |
| { | |
| t_south = om->ter(overx, 0); | |
| } | |
| if (overx - 1 >= 0) | |
| { | |
| t_west = tmp.ter(overx - 1, overy); | |
| } | |
| else | |
| { | |
| t_west = om->ter(OMAPX - 1, overy); | |
| } | |
| } | |
| else | |
| { | |
| dbg(D_INFO) << "map::generate: In section 2"; | |
| if (om->posz < 0 || om->posz == 9) // 9 is for tutorials | |
| { | |
| overmap tmp = overmap(g, om->posx, om->posy, om->posz + 1); | |
| t_above = tmp.ter(overx, overy); | |
| } | |
| else | |
| { | |
| t_above = ot_null; | |
| } | |
| terrain_type = om->ter(overx, overy); | |
| if (overy - 1 >= 0) | |
| { | |
| t_north = om->ter(overx, overy - 1); | |
| } | |
| else | |
| { | |
| overmap tmp(g, om->posx, om->posy - 1, 0); | |
| t_north = tmp.ter(overx, OMAPY - 1); | |
| } | |
| if (overx + 1 < OMAPX) | |
| { | |
| t_east = om->ter(overx + 1, overy); | |
| } | |
| else | |
| { | |
| overmap tmp(g, om->posx + 1, om->posy, 0); | |
| t_east = tmp.ter(0, overy); | |
| } | |
| if (overy + 1 < OMAPY) | |
| { | |
| t_south = om->ter(overx, overy + 1); | |
| } | |
| else | |
| { | |
| overmap tmp(g, om->posx, om->posy + 1, 0); | |
| t_south = tmp.ter(overx, 0); | |
| } | |
| if (overx - 1 >= 0) | |
| { | |
| t_west = om->ter(overx - 1, overy); | |
| } | |
| else | |
| { | |
| overmap tmp(g, om->posx - 1, om->posy, 0); | |
| t_west = tmp.ter(OMAPX - 1, overy); | |
| } | |
| } | |
| draw_map(terrain_type, t_north, t_east, t_south, t_west, t_above, turn, g); | |
| if (one_in(oterlist[terrain_type].embellishments.chance)) | |
| { | |
| add_extra(random_map_extra(oterlist[terrain_type].embellishments), g); | |
| } | |
| post_process(g, zones); | |
| // Okay, we know who are neighbors are. Let's draw! | |
| // And finally save used submaps and delete the rest. | |
| for (int i = 0; i < my_MAPSIZE; i++) | |
| { | |
| for (int j = 0; j < my_MAPSIZE; j++) | |
| { | |
| dbg(D_INFO) << "map::generate: submap (" << i << "," << j << ")"; | |
| dbg(D_INFO) << grid[i + j]; | |
| if (i <= 1 && j <= 1) | |
| { | |
| saven(om, turn, x, y, i, j); | |
| } | |
| else | |
| { | |
| delete grid[i + j * my_MAPSIZE]; | |
| } | |
| } | |
| } | |
| } | |
| void map::draw_map(oter_id terrain_type, oter_id t_north, oter_id t_east, | |
| oter_id t_south, oter_id t_west, oter_id t_above, int turn, | |
| game* g) | |
| { | |
| // Big old switch statement with a case for each overmap terrain type. | |
| // Many of these can be copied from another type, then rotated; for instance, | |
| // ot_house_east is identical to ot_house_north, just rotated 90 degrees to | |
| // the right. The rotate(int) function is at the bottom of this file. | |
| // The place_items() function takes a mapitems type (see mapitems.h and | |
| // mapitemsdef.cpp), an "odds" int giving the chance for a single item to be | |
| // placed, four ints (x1, y1, x2, y2) corresponding to the upper left corner | |
| // and lower right corner of a square where the items are placed, a boolean | |
| // that indicates whether items may spawn on grass & dirt, and finally an | |
| // integer that indicates on which turn the items were created. This final | |
| // integer should be 0, unless the items are "fresh-grown" like wild fruit. | |
| int rn, lw, rw, mw, tw, bw, cw, x, y; | |
| int n_fac = 0, e_fac = 0, s_fac = 0, w_fac = 0; | |
| computer* tmpcomp = NULL; | |
| int SEEX_oth = SEEX; | |
| int SEEY_oth = SEEY - 5; | |
| switch (terrain_type) | |
| { | |
| case ot_null: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_null; | |
| radiation(i, j) = 0; | |
| } | |
| } | |
| break; | |
| case ot_crater: | |
| if (t_north != ot_crater) | |
| { | |
| n_fac = 6; | |
| } | |
| if (t_east != ot_crater) | |
| { | |
| e_fac = 6; | |
| } | |
| if (t_south != ot_crater) | |
| { | |
| s_fac = 6; | |
| } | |
| if (t_west != ot_crater) | |
| { | |
| w_fac = 6; | |
| } | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (rng(0, w_fac) <= i && rng(0, e_fac) <= SEEX * 2 - 1 - i && | |
| rng(0, n_fac) <= j && rng(0, s_fac) <= SEEX * 2 - 1 - j) | |
| { | |
| ter(i, j) = t_rubble; | |
| radiation(i, j) = rng(0, 4) * rng(0, 2); | |
| } | |
| else | |
| { | |
| ter(i, j) = t_dirt; | |
| radiation(i, j) = rng(0, 2) * rng(0, 2) * rng(0, 2); | |
| } | |
| } | |
| } | |
| place_items(mi_wreckage, 83, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| break; | |
| case ot_field: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| //------Jovan's----- | |
| if (one_in(120)) | |
| { | |
| if (one_in(30)) | |
| { | |
| ter(i, j) = t_shrub_blueberry; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_shrub; | |
| } | |
| } | |
| else if (one_in(1000)) | |
| { | |
| ter(i, j) = t_mutpoppy; | |
| } | |
| //------------------ | |
| } | |
| } | |
| place_items(mi_field, 60, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, turn); | |
| break; | |
| case ot_dirtlot: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_dirt; | |
| if (one_in(120)) | |
| { | |
| ter(i, j) = t_pit_shallow; | |
| } | |
| else if (one_in(50)) | |
| { | |
| ter(i, j) = t_grass; | |
| } | |
| } | |
| } | |
| if (one_in(4)) | |
| { | |
| add_vehicle(g, veh_truck, 12, 12, 90); | |
| } | |
| break; | |
| case ot_forest: | |
| case ot_forest_thick: | |
| case ot_forest_water: | |
| switch (terrain_type) | |
| { | |
| case ot_forest_thick: | |
| n_fac = 8; | |
| e_fac = 8; | |
| s_fac = 8; | |
| w_fac = 8; | |
| break; | |
| case ot_forest_water: | |
| n_fac = 4; | |
| e_fac = 4; | |
| s_fac = 4; | |
| w_fac = 4; | |
| break; | |
| case ot_forest: | |
| n_fac = 0; | |
| e_fac = 0; | |
| s_fac = 0; | |
| w_fac = 0; | |
| } | |
| if (t_north == ot_forest || t_north == ot_forest_water) | |
| { | |
| n_fac += 14; | |
| } | |
| else if (t_north == ot_forest_thick) | |
| { | |
| n_fac += 18; | |
| } | |
| if (t_east == ot_forest || t_east == ot_forest_water) | |
| { | |
| e_fac += 14; | |
| } | |
| else if (t_east == ot_forest_thick) | |
| { | |
| e_fac += 18; | |
| } | |
| if (t_south == ot_forest || t_south == ot_forest_water) | |
| { | |
| s_fac += 14; | |
| } | |
| else if (t_south == ot_forest_thick) | |
| { | |
| s_fac += 18; | |
| } | |
| if (t_west == ot_forest || t_west == ot_forest_water) | |
| { | |
| w_fac += 14; | |
| } | |
| else if (t_west == ot_forest_thick) | |
| { | |
| w_fac += 18; | |
| } | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| int forest_chance = 0, num = 0; | |
| if (j < n_fac) | |
| { | |
| forest_chance += n_fac - j; | |
| num++; | |
| } | |
| if (SEEX * 2 - 1 - i < e_fac) | |
| { | |
| forest_chance += e_fac - (SEEX * 2 - 1 - i); | |
| num++; | |
| } | |
| if (SEEY * 2 - 1 - j < s_fac) | |
| { | |
| forest_chance += s_fac - (SEEX * 2 - 1 - j); | |
| num++; | |
| } | |
| if (i < w_fac) | |
| { | |
| forest_chance += w_fac - i; | |
| num++; | |
| } | |
| if (num > 0) | |
| { | |
| forest_chance /= num; | |
| } | |
| rn = rng(0, forest_chance); | |
| if ((forest_chance > 0 && rn > 13) || one_in(100 - forest_chance)) | |
| { | |
| if (one_in(250)) | |
| { | |
| ter(i, j) = t_tree_apple; | |
| add_item(i, j, (*itypes)[itm_apple], turn); | |
| } | |
| else | |
| { | |
| ter(i, j) = t_tree; | |
| } | |
| } | |
| else if ((forest_chance > 0 && rn > 10) || one_in(100 - forest_chance)) | |
| { | |
| ter(i, j) = t_tree_young; | |
| } | |
| else if ((forest_chance > 0 && rn > 9) || one_in(100 - forest_chance)) | |
| { | |
| if (one_in(250)) | |
| { | |
| ter(i, j) = t_shrub_blueberry; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_underbrush; | |
| } | |
| } | |
| else | |
| { | |
| ter(i, j) = t_dirt; | |
| } | |
| } | |
| } | |
| place_items(mi_forest, 60, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, turn); | |
| if (terrain_type == ot_forest_water) | |
| { | |
| // Reset *_fac to handle where to place water | |
| if (t_north == ot_forest_water) | |
| { | |
| n_fac = 2; | |
| } | |
| else if (t_north >= ot_river_center && t_north <= ot_river_nw) | |
| { | |
| n_fac = 3; | |
| } | |
| else if (t_north == ot_forest || t_north == ot_forest_thick) | |
| { | |
| n_fac = 1; | |
| } | |
| else | |
| { | |
| n_fac = 0; | |
| } | |
| if (t_east == ot_forest_water) | |
| { | |
| e_fac = 2; | |
| } | |
| else if (t_east >= ot_river_center && t_east <= ot_river_nw) | |
| { | |
| e_fac = 3; | |
| } | |
| else if (t_east == ot_forest || t_east == ot_forest_thick) | |
| { | |
| e_fac = 1; | |
| } | |
| else | |
| { | |
| e_fac = 0; | |
| } | |
| if (t_south == ot_forest_water) | |
| { | |
| s_fac = 2; | |
| } | |
| else if (t_south >= ot_river_center && t_south <= ot_river_nw) | |
| { | |
| s_fac = 3; | |
| } | |
| else if (t_south == ot_forest || t_south == ot_forest_thick) | |
| { | |
| s_fac = 1; | |
| } | |
| else | |
| { | |
| s_fac = 0; | |
| } | |
| if (t_west == ot_forest_water) | |
| { | |
| w_fac = 2; | |
| } | |
| else if (t_west >= ot_river_center && t_west <= ot_river_nw) | |
| { | |
| w_fac = 3; | |
| } | |
| else if (t_west == ot_forest || t_west == ot_forest_thick) | |
| { | |
| w_fac = 1; | |
| } | |
| else | |
| { | |
| w_fac = 0; | |
| } | |
| x = SEEX / 2 + rng(0, SEEX), y = SEEY / 2 + rng(0, SEEY); | |
| for (int i = 0; i < 20; i++) | |
| { | |
| if (x >= 0 && x < SEEX * 2 && y >= 0 && y < SEEY * 2) | |
| { | |
| if (ter(x, y) == t_water_sh) | |
| { | |
| ter(x, y) = t_water_dp; | |
| } | |
| else if (ter(x, y) == t_dirt || ter(x, y) == t_underbrush) | |
| { | |
| ter(x, y) = t_water_sh; | |
| } | |
| } | |
| else | |
| { | |
| i = 20; | |
| } | |
| x += rng(-2, 2); | |
| y += rng(-2, 2); | |
| if (x < 0 || x >= SEEX * 2) | |
| { | |
| x = SEEX / 2 + rng(0, SEEX); | |
| } | |
| if (y < 0 || y >= SEEY * 2) | |
| { | |
| y = SEEY / 2 + rng(0, SEEY); | |
| } | |
| for (int j = 0; j < n_fac; j++) | |
| { | |
| int wx = rng(0, SEEX * 2 - 1), wy = rng(0, SEEY - 1); | |
| if (ter(wx, wy) == t_dirt || ter(wx, wy) == t_underbrush) | |
| { | |
| ter(wx, wy) = t_water_sh; | |
| } | |
| } | |
| for (int j = 0; j < e_fac; j++) | |
| { | |
| int wx = rng(SEEX, SEEX * 2 - 1), wy = rng(0, SEEY * 2 - 1); | |
| if (ter(wx, wy) == t_dirt || ter(wx, wy) == t_underbrush) | |
| { | |
| ter(wx, wy) = t_water_sh; | |
| } | |
| } | |
| for (int j = 0; j < s_fac; j++) | |
| { | |
| int wx = rng(0, SEEX * 2 - 1), wy = rng(SEEY, SEEY * 2 - 1); | |
| if (ter(wx, wy) == t_dirt || ter(wx, wy) == t_underbrush) | |
| { | |
| ter(wx, wy) = t_water_sh; | |
| } | |
| } | |
| for (int j = 0; j < w_fac; j++) | |
| { | |
| int wx = rng(0, SEEX - 1), wy = rng(0, SEEY * 2 - 1); | |
| if (ter(wx, wy) == t_dirt || ter(wx, wy) == t_underbrush) | |
| { | |
| ter(wx, wy) = t_water_sh; | |
| } | |
| } | |
| } | |
| rn = rng(0, 2) * rng(0, 1) * (rng(0, 1) + rng(0, 1));// Good chance of 0 | |
| for (int i = 0; i < rn; i++) | |
| { | |
| x = rng(0, SEEX * 2 - 1); | |
| y = rng(0, SEEY * 2 - 1); | |
| add_trap(x, y, tr_sinkhole); | |
| if (ter(x, y) != t_water_sh) | |
| { | |
| ter(x, y) = t_dirt; | |
| } | |
| } | |
| } | |
| if (one_in(100)) // One in 100 forests has a spider living in it :o | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEX * 2; j++) | |
| { | |
| if ((ter(i, j) == t_dirt || ter(i, j) == t_underbrush) && !one_in(3)) | |
| { | |
| add_field(NULL, i, j, fd_web, rng(1, 3)); | |
| } | |
| } | |
| } | |
| add_spawn(mon_spider_web, rng(1, 2), SEEX, SEEY); | |
| } | |
| break; | |
| case ot_hive: | |
| // Start with a basic forest pattern | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| rn = rng(0, 14); | |
| if (rn > 13) | |
| { | |
| ter(i, j) = t_tree; | |
| } | |
| else if (rn > 11) | |
| { | |
| ter(i, j) = t_tree_young; | |
| } | |
| else if (rn > 10) | |
| { | |
| ter(i, j) = t_underbrush; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_dirt; | |
| } | |
| } | |
| } | |
| // j and i loop through appropriate hive-cell center squares | |
| for (int j = 5; j < SEEY * 2 - 5; j += 6) | |
| { | |
| for (int i = (j == 5 || j == 17 ? 3 : 6); i < SEEX * 2 - 5; i += 6) | |
| { | |
| if (!one_in(8)) | |
| { | |
| // Caps are always there | |
| ter(i , j - 5) = t_wax; | |
| ter(i , j + 5) = t_wax; | |
| for (int k = -2; k <= 2; k++) | |
| { | |
| for (int l = -1; l <= 1; l++) | |
| { | |
| ter(i + k, j + l) = t_floor_wax; | |
| } | |
| } | |
| add_spawn(mon_bee, 2, i, j); | |
| add_spawn(mon_beekeeper, 1, i, j); | |
| ter(i , j - 3) = t_floor_wax; | |
| ter(i , j + 3) = t_floor_wax; | |
| ter(i - 1, j - 2) = t_floor_wax; | |
| ter(i , j - 2) = t_floor_wax; | |
| ter(i + 1, j - 2) = t_floor_wax; | |
| ter(i - 1, j + 2) = t_floor_wax; | |
| ter(i , j + 2) = t_floor_wax; | |
| ter(i + 1, j + 2) = t_floor_wax; | |
| // Up to two of these get skipped; an entrance to the cell | |
| int skip1 = rng(0, 23); | |
| int skip2 = rng(0, 23); | |
| ter(i - 1, j - 4) = t_wax; | |
| ter(i , j - 4) = t_wax; | |
| ter(i + 1, j - 4) = t_wax; | |
| ter(i - 2, j - 3) = t_wax; | |
| ter(i - 1, j - 3) = t_wax; | |
| ter(i + 1, j - 3) = t_wax; | |
| ter(i + 2, j - 3) = t_wax; | |
| ter(i - 3, j - 2) = t_wax; | |
| ter(i - 2, j - 2) = t_wax; | |
| ter(i + 2, j - 2) = t_wax; | |
| ter(i + 3, j - 2) = t_wax; | |
| ter(i - 3, j - 1) = t_wax; | |
| ter(i - 3, j) = t_wax; | |
| ter(i - 3, j - 1) = t_wax; | |
| ter(i - 3, j + 1) = t_wax; | |
| ter(i - 3, j) = t_wax; | |
| ter(i - 3, j + 1) = t_wax; | |
| ter(i - 2, j + 3) = t_wax; | |
| ter(i - 1, j + 3) = t_wax; | |
| ter(i + 1, j + 3) = t_wax; | |
| ter(i + 2, j + 3) = t_wax; | |
| ter(i - 1, j + 4) = t_wax; | |
| ter(i , j + 4) = t_wax; | |
| ter(i + 1, j + 4) = t_wax; | |
| if (skip1 == 0 || skip2 == 0) | |
| { | |
| ter(i - 1, j - 4) = t_floor_wax; | |
| } | |
| if (skip1 == 1 || skip2 == 1) | |
| { | |
| ter(i , j - 4) = t_floor_wax; | |
| } | |
| if (skip1 == 2 || skip2 == 2) | |
| { | |
| ter(i + 1, j - 4) = t_floor_wax; | |
| } | |
| if (skip1 == 3 || skip2 == 3) | |
| { | |
| ter(i - 2, j - 3) = t_floor_wax; | |
| } | |
| if (skip1 == 4 || skip2 == 4) | |
| { | |
| ter(i - 1, j - 3) = t_floor_wax; | |
| } | |
| if (skip1 == 5 || skip2 == 5) | |
| { | |
| ter(i + 1, j - 3) = t_floor_wax; | |
| } | |
| if (skip1 == 6 || skip2 == 6) | |
| { | |
| ter(i + 2, j - 3) = t_floor_wax; | |
| } | |
| if (skip1 == 7 || skip2 == 7) | |
| { | |
| ter(i - 3, j - 2) = t_floor_wax; | |
| } | |
| if (skip1 == 8 || skip2 == 8) | |
| { | |
| ter(i - 2, j - 2) = t_floor_wax; | |
| } | |
| if (skip1 == 9 || skip2 == 9) | |
| { | |
| ter(i + 2, j - 2) = t_floor_wax; | |
| } | |
| if (skip1 == 10 || skip2 == 10) | |
| { | |
| ter(i + 3, j - 2) = t_floor_wax; | |
| } | |
| if (skip1 == 11 || skip2 == 11) | |
| { | |
| ter(i - 3, j - 1) = t_floor_wax; | |
| } | |
| if (skip1 == 12 || skip2 == 12) | |
| { | |
| ter(i - 3, j) = t_floor_wax; | |
| } | |
| if (skip1 == 13 || skip2 == 13) | |
| { | |
| ter(i - 3, j - 1) = t_floor_wax; | |
| } | |
| if (skip1 == 14 || skip2 == 14) | |
| { | |
| ter(i - 3, j + 1) = t_floor_wax; | |
| } | |
| if (skip1 == 15 || skip2 == 15) | |
| { | |
| ter(i - 3, j) = t_floor_wax; | |
| } | |
| if (skip1 == 16 || skip2 == 16) | |
| { | |
| ter(i - 3, j + 1) = t_floor_wax; | |
| } | |
| if (skip1 == 17 || skip2 == 17) | |
| { | |
| ter(i - 2, j + 3) = t_floor_wax; | |
| } | |
| if (skip1 == 18 || skip2 == 18) | |
| { | |
| ter(i - 1, j + 3) = t_floor_wax; | |
| } | |
| if (skip1 == 19 || skip2 == 19) | |
| { | |
| ter(i + 1, j + 3) = t_floor_wax; | |
| } | |
| if (skip1 == 20 || skip2 == 20) | |
| { | |
| ter(i + 2, j + 3) = t_floor_wax; | |
| } | |
| if (skip1 == 21 || skip2 == 21) | |
| { | |
| ter(i - 1, j + 4) = t_floor_wax; | |
| } | |
| if (skip1 == 22 || skip2 == 22) | |
| { | |
| ter(i , j + 4) = t_floor_wax; | |
| } | |
| if (skip1 == 23 || skip2 == 23) | |
| { | |
| ter(i + 1, j + 4) = t_floor_wax; | |
| } | |
| if (t_north == ot_hive && t_east == ot_hive && t_south == ot_hive && | |
| t_west == ot_hive) | |
| { | |
| place_items(mi_hive_center, 90, i - 2, j - 2, i + 2, j + 2, false, turn); | |
| } | |
| else | |
| { | |
| place_items(mi_hive, 80, i - 2, j - 2, i + 2, j + 2, false, turn); | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| case ot_spider_pit: | |
| // First generate a forest | |
| n_fac = 0; | |
| e_fac = 0; | |
| s_fac = 0; | |
| w_fac = 0; | |
| if (t_north == ot_forest || t_north == ot_forest_water) | |
| { | |
| n_fac += 14; | |
| } | |
| else if (t_north == ot_forest_thick) | |
| { | |
| n_fac += 18; | |
| } | |
| if (t_east == ot_forest || t_east == ot_forest_water) | |
| { | |
| e_fac += 14; | |
| } | |
| else if (t_east == ot_forest_thick) | |
| { | |
| e_fac += 18; | |
| } | |
| if (t_south == ot_forest || t_south == ot_forest_water) | |
| { | |
| s_fac += 14; | |
| } | |
| else if (t_south == ot_forest_thick) | |
| { | |
| s_fac += 18; | |
| } | |
| if (t_west == ot_forest || t_west == ot_forest_water) | |
| { | |
| w_fac += 14; | |
| } | |
| else if (t_west == ot_forest_thick) | |
| { | |
| w_fac += 18; | |
| } | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| int forest_chance = 0, num = 0; | |
| if (j < n_fac) | |
| { | |
| forest_chance += n_fac - j; | |
| num++; | |
| } | |
| if (SEEX * 2 - 1 - i < e_fac) | |
| { | |
| forest_chance += e_fac - (SEEX * 2 - 1 - i); | |
| num++; | |
| } | |
| if (SEEY * 2 - 1 - j < s_fac) | |
| { | |
| forest_chance += s_fac - (SEEX * 2 - 1 - j); | |
| num++; | |
| } | |
| if (i < w_fac) | |
| { | |
| forest_chance += w_fac - i; | |
| num++; | |
| } | |
| if (num > 0) | |
| { | |
| forest_chance /= num; | |
| } | |
| rn = rng(0, forest_chance); | |
| if ((forest_chance > 0 && rn > 13) || one_in(100 - forest_chance)) | |
| { | |
| ter(i, j) = t_tree; | |
| } | |
| else if ((forest_chance > 0 && rn > 10) || one_in(100 - forest_chance)) | |
| { | |
| ter(i, j) = t_tree_young; | |
| } | |
| else if ((forest_chance > 0 && rn > 9) || one_in(100 - forest_chance)) | |
| { | |
| ter(i, j) = t_underbrush; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_dirt; | |
| } | |
| } | |
| } | |
| place_items(mi_forest, 60, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, turn); | |
| // Next, place webs and sinkholes | |
| for (int i = 0; i < 4; i++) | |
| { | |
| int x = rng(3, SEEX * 2 - 4), y = rng(3, SEEY * 2 - 4); | |
| if (i == 0) | |
| { | |
| ter(x, y) = t_slope_down; | |
| } | |
| else | |
| { | |
| ter(x, y) = t_dirt; | |
| add_trap(x, y, tr_sinkhole); | |
| } | |
| for (int x1 = x - 3; x1 <= x + 3; x1++) | |
| { | |
| for (int y1 = y - 3; y1 <= y + 3; y1++) | |
| { | |
| add_field(NULL, x1, y1, fd_web, rng(2, 3)); | |
| if (ter(x1, y1) != t_slope_down) | |
| { | |
| ter(x1, y1) = t_dirt; | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| case ot_fungal_bloom: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (one_in(10)) | |
| { | |
| ter(i, j) = t_tree_fungal; | |
| } | |
| else if (one_in(300)) | |
| { | |
| ter(i, j) = t_marloss; | |
| add_item(i, j, (*itypes)[itm_marloss_berry], turn); | |
| } | |
| else if (one_in(3)) | |
| { | |
| ter(i, j) = t_dirt; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_fungus; | |
| } | |
| } | |
| } | |
| square(this, t_fungus, SEEX - 3, SEEY - 3, SEEX + 3, SEEY + 3); | |
| add_spawn(mon_fungaloid_queen, 1, 12, 12); | |
| break; | |
| case ot_road_ns: | |
| case ot_road_ew: | |
| if ((t_west >= ot_house_north && t_west <= ot_sub_station_west) || | |
| (t_east >= ot_house_north && t_east <= ot_sub_station_west) || | |
| (t_north >= ot_house_north && t_north <= ot_sub_station_west) || | |
| (t_south >= ot_house_north && t_south <= ot_sub_station_west)) | |
| { | |
| rn = 1; // rn = 1 if this road has sidewalks | |
| } | |
| else | |
| { | |
| rn = 0; | |
| } | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i < 4 || i >= SEEX * 2 - 4) | |
| { | |
| if (rn == 1) | |
| { | |
| ter(i, j) = t_sidewalk; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| else | |
| { | |
| if ((i == SEEX - 1 || i == SEEX) && j % 4 != 0) | |
| { | |
| ter(i, j) = t_pavement_y; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| } | |
| } | |
| } | |
| if (terrain_type == ot_road_ew) | |
| { | |
| rotate(1); | |
| } | |
| place_items(mi_road, 5, 0, 0, SEEX * 2 - 1, SEEX * 2 - 1, false, turn); | |
| break; | |
| case ot_road_ne: | |
| case ot_road_es: | |
| case ot_road_sw: | |
| case ot_road_wn: | |
| if ((t_west >= ot_house_north && t_west <= ot_sub_station_west) || | |
| (t_east >= ot_house_north && t_east <= ot_sub_station_west) || | |
| (t_north >= ot_house_north && t_north <= ot_sub_station_west) || | |
| (t_south >= ot_house_north && t_south <= ot_sub_station_west)) | |
| { | |
| rn = 1; // rn = 1 if this road has sidewalks | |
| } | |
| else | |
| { | |
| rn = 0; | |
| } | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if ((i >= SEEX * 2 - 4 && j < 4) || i < 4 || j >= SEEY * 2 - 4) | |
| { | |
| if (rn == 1) | |
| { | |
| ter(i, j) = t_sidewalk; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| else | |
| { | |
| if (((i == SEEX - 1 || i == SEEX) && j % 4 != 0 && j < SEEY - 1) || | |
| ((j == SEEY - 1 || j == SEEY) && i % 4 != 0 && i > SEEX)) | |
| { | |
| ter(i, j) = t_pavement_y; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| } | |
| } | |
| } | |
| if (terrain_type == ot_road_es) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_road_sw) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_road_wn) | |
| { | |
| rotate(3); | |
| } | |
| place_items(mi_road, 5, 0, 0, SEEX * 2 - 1, SEEX * 2 - 1, false, turn); | |
| break; | |
| case ot_road_nes: | |
| case ot_road_new: | |
| case ot_road_nsw: | |
| case ot_road_esw: | |
| if ((t_west >= ot_house_north && t_west <= ot_sub_station_west) || | |
| (t_east >= ot_house_north && t_east <= ot_sub_station_west) || | |
| (t_north >= ot_house_north && t_north <= ot_sub_station_west) || | |
| (t_south >= ot_house_north && t_south <= ot_sub_station_west)) | |
| { | |
| rn = 1; // rn = 1 if this road has sidewalks | |
| } | |
| else | |
| { | |
| rn = 0; | |
| } | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i < 4 || (i >= SEEX * 2 - 4 && (j < 4 || j >= SEEY * 2 - 4))) | |
| { | |
| if (rn == 1) | |
| { | |
| ter(i, j) = t_sidewalk; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| else | |
| { | |
| if (((i == SEEX - 1 || i == SEEX) && j % 4 != 0) || | |
| ((j == SEEY - 1 || j == SEEY) && i % 4 != 0 && i > SEEX)) | |
| { | |
| ter(i, j) = t_pavement_y; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| } | |
| } | |
| } | |
| if (terrain_type == ot_road_esw) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_road_nsw) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_road_new) | |
| { | |
| rotate(3); | |
| } | |
| place_items(mi_road, 5, 0, 0, SEEX * 2 - 1, SEEX * 2 - 1, false, turn); | |
| break; | |
| case ot_road_nesw: | |
| case ot_road_nesw_manhole: | |
| if ((t_west == ot_road_nesw || t_west == ot_road_nesw_manhole) && | |
| (t_east == ot_road_nesw || t_east == ot_road_nesw_manhole) && | |
| (t_north == ot_road_nesw || t_north == ot_road_nesw_manhole) && | |
| (t_south == ot_road_nesw || t_south == ot_road_nesw_manhole)) | |
| { | |
| rn = 2; // rn = 2 if this is actually a plaza | |
| } | |
| else | |
| { | |
| rn = 1; // rn = 1 if this road has sidewalks | |
| } | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (rn == 2) | |
| { | |
| ter(i, j) = t_sidewalk; | |
| } | |
| else if ((i < 4 || i >= SEEX * 2 - 4) && (j < 4 || j >= SEEY * 2 - 4)) | |
| { | |
| if (rn == 1) | |
| { | |
| ter(i, j) = t_sidewalk; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| else | |
| { | |
| if (((i == SEEX - 1 || i == SEEX) && j % 4 != 0) || | |
| ((j == SEEY - 1 || j == SEEY) && i % 4 != 0)) | |
| { | |
| ter(i, j) = t_pavement_y; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| } | |
| } | |
| } | |
| if (rn == 2) // Special embellishments for a plaza | |
| { | |
| if (one_in(10)) // Fountain | |
| { | |
| for (int i = SEEX - 2; i <= SEEX + 2; i++) | |
| { | |
| ter(i, i) = t_water_sh; | |
| ter(i, SEEX * 2 - i) = t_water_sh; | |
| } | |
| } | |
| if (one_in(10)) // Small trees in center | |
| { | |
| ter(SEEX - 1, SEEY - 2) = t_tree_young; | |
| ter(SEEX , SEEY - 2) = t_tree_young; | |
| ter(SEEX - 1, SEEY + 2) = t_tree_young; | |
| ter(SEEX , SEEY + 2) = t_tree_young; | |
| ter(SEEX - 2, SEEY - 1) = t_tree_young; | |
| ter(SEEX - 2, SEEY) = t_tree_young; | |
| ter(SEEX + 2, SEEY - 1) = t_tree_young; | |
| ter(SEEX + 2, SEEY) = t_tree_young; | |
| } | |
| if (one_in(14)) // Rows of small trees | |
| { | |
| int gap = rng(2, 4); | |
| int start = rng(0, 4); | |
| for (int i = 2; i < SEEX * 2 - start; i += gap) | |
| { | |
| ter(i , start) = t_tree_young; | |
| ter(SEEX * 2 - 1 - i, start) = t_tree_young; | |
| ter(start, i) = t_tree_young; | |
| ter(start, SEEY * 2 - 1 - i) = t_tree_young; | |
| } | |
| } | |
| place_items(mi_trash, 5, 0, 0, SEEX * 2 - 1, SEEX * 2 - 1, true, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_road, 5, 0, 0, SEEX * 2 - 1, SEEX * 2 - 1, false, turn); | |
| } | |
| if (terrain_type == ot_road_nesw_manhole) | |
| { | |
| ter(rng(6, SEEX * 2 - 6), rng(6, SEEX * 2 - 6)) = t_manhole_cover; | |
| } | |
| break; | |
| case ot_bridge_ns: | |
| case ot_bridge_ew: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i < 4 || i >= SEEX * 2 - 4) | |
| { | |
| ter(i, j) = t_water_dp; | |
| } | |
| else if (i == 4 || i == SEEX * 2 - 5) | |
| { | |
| ter(i, j) = t_railing_v; | |
| } | |
| else | |
| { | |
| if ((i == SEEX - 1 || i == SEEX) && j % 4 != 0) | |
| { | |
| ter(i, j) = t_pavement_y; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| } | |
| } | |
| } | |
| if (terrain_type == ot_bridge_ew) | |
| { | |
| rotate(1); | |
| } | |
| place_items(mi_road, 5, 0, 0, SEEX * 2 - 1, SEEX * 2 - 1, false, turn); | |
| break; | |
| case ot_hiway_ns: | |
| case ot_hiway_ew: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i < 3 || i >= SEEX * 2 - 3) | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| else if (i == 3 || i == SEEX * 2 - 4) | |
| { | |
| ter(i, j) = t_railing_v; | |
| } | |
| else | |
| { | |
| if ((i == SEEX - 1 || i == SEEX) && j % 4 != 0) | |
| { | |
| ter(i, j) = t_pavement_y; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| } | |
| } | |
| } | |
| if (terrain_type == ot_hiway_ew) | |
| { | |
| rotate(1); | |
| } | |
| place_items(mi_road, 8, 0, 0, SEEX * 2 - 1, SEEX * 2 - 1, false, turn); | |
| break; | |
| case ot_river_center: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_water_dp; | |
| } | |
| } | |
| break; | |
| case ot_river_c_not_ne: | |
| case ot_river_c_not_se: | |
| case ot_river_c_not_sw: | |
| case ot_river_c_not_nw: | |
| for (int i = SEEX * 2 - 1; i >= 0; i--) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (j < 4 && i >= SEEX * 2 - 4) | |
| { | |
| ter(i, j) = t_water_sh; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_water_dp; | |
| } | |
| } | |
| } | |
| if (terrain_type == ot_river_c_not_se) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_river_c_not_sw) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_river_c_not_nw) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_river_north: | |
| case ot_river_east: | |
| case ot_river_south: | |
| case ot_river_west: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (j < 4) | |
| { | |
| ter(i, j) = t_water_sh; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_water_dp; | |
| } | |
| } | |
| } | |
| if (terrain_type == ot_river_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_river_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_river_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_river_ne: | |
| case ot_river_se: | |
| case ot_river_sw: | |
| case ot_river_nw: | |
| for (int i = SEEX * 2 - 1; i >= 0; i--) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i >= SEEX * 2 - 4 || j < 4) | |
| { | |
| ter(i, j) = t_water_sh; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_water_dp; | |
| } | |
| } | |
| } | |
| if (terrain_type == ot_river_se) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_river_sw) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_river_nw) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_house_base_north: | |
| case ot_house_base_east: | |
| case ot_house_base_south: | |
| case ot_house_base_west: | |
| case ot_house_north: | |
| case ot_house_east: | |
| case ot_house_south: | |
| case ot_house_west: | |
| lw = rng(0, 4); // West external wall | |
| mw = lw + rng(7, 10); // Middle wall between bedroom & kitchen/bath | |
| rw = SEEX * 2 - rng(1, 5); // East external wall | |
| tw = rng(1, 6); // North external wall | |
| bw = SEEX * 2 - rng(2, 5); // South external wall | |
| cw = tw + rng(4, 7); // Middle wall between living room & kitchen/bed | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i > lw && i < rw && j > tw && j < bw) | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| if (i >= lw && i <= rw && (j == tw || j == bw)) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| if ((i == lw || i == rw) && j > tw && j < bw) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| } | |
| } | |
| switch (rng(1, 3)) | |
| { | |
| case 1: // Quadrants, essentially | |
| mw = rng(lw + 5, rw - 5); | |
| cw = tw + rng(4, 7); | |
| house_room(this, room_living, mw, tw, rw, cw); | |
| house_room(this, room_kitchen, lw, tw, mw, cw); | |
| ter(mw, rng(tw + 2, cw - 2)) = (one_in(3) ? t_door_c : t_floor); | |
| rn = rng(lw + 1, cw - 2); | |
| ter(rn , tw) = t_window_domestic; | |
| ter(rn + 1, tw) = t_window_domestic; | |
| rn = rng(cw + 1, rw - 2); | |
| ter(rn , tw) = t_window_domestic; | |
| ter(rn + 1, tw) = t_window_domestic; | |
| mw = rng(lw + 3, rw - 3); | |
| if (mw <= lw + 5) // Bedroom on right, bathroom on left | |
| { | |
| rn = rng(cw + 2, rw - 2); | |
| if (bw - cw >= 10 && mw - lw >= 6) | |
| { | |
| house_room(this, room_bathroom, lw, bw - 5, mw, bw); | |
| house_room(this, room_bedroom, lw, cw, mw, bw - 5); | |
| ter(mw - 1, cw) = t_door_c; | |
| } | |
| else | |
| { | |
| if (bw - cw > 4) // Too big for a bathroom, not big enough for 2nd bedrm | |
| { | |
| house_room(this, room_bathroom, lw, bw - 4, mw, bw); | |
| for (int i = lw + 1; i <= mw - 1; i++) | |
| { | |
| ter(i, cw) = t_floor; | |
| } | |
| } | |
| else | |
| { | |
| house_room(this, room_bathroom, lw, cw, mw, bw); | |
| } | |
| } | |
| house_room(this, room_bedroom, mw, cw, rw, bw); | |
| ter(mw, rng(bw - 4, bw - 1)) = t_door_c; | |
| } | |
| else // Bedroom on left, bathroom on right | |
| { | |
| rn = rng(lw + 2, cw - 2); | |
| if (bw - cw >= 10 && rw - mw >= 6) | |
| { | |
| house_room(this, room_bathroom, mw, bw - 5, rw, bw); | |
| house_room(this, room_bedroom, mw, cw, rw, bw - 5); | |
| ter(rw - 1, cw) = t_door_c; | |
| } | |
| else | |
| { | |
| if (bw - cw > 4) // Too big for a bathroom, not big enough for 2nd bedrm | |
| { | |
| house_room(this, room_bathroom, mw, bw - 4, rw, bw); | |
| for (int i = mw + 1; i <= rw - 1; i++) | |
| { | |
| ter(i, cw) = t_floor; | |
| } | |
| } | |
| else | |
| { | |
| house_room(this, room_bathroom, mw, cw, rw, bw); | |
| } | |
| } | |
| house_room(this, room_bedroom, lw, cw, mw, bw); | |
| ter(mw, rng(bw - 4, bw - 1)) = t_door_c; | |
| } | |
| ter(rn , bw) = t_window_domestic; | |
| ter(rn + 1, bw) = t_window_domestic; | |
| if (!one_in(3)) // Potential side windows | |
| { | |
| rn = rng(tw + 2, bw - 5); | |
| ter(rw, rn) = t_window_domestic; | |
| ter(rw, rn + 4) = t_window_domestic; | |
| } | |
| if (!one_in(3)) // Potential side windows | |
| { | |
| rn = rng(tw + 2, bw - 5); | |
| ter(lw, rn) = t_window_domestic; | |
| ter(lw, rn + 4) = t_window_domestic; | |
| } | |
| ter(rng(lw + 1, lw + 2), cw) = t_door_c; | |
| if (one_in(4)) | |
| { | |
| ter(rw - 2, cw) = t_door_c; | |
| } | |
| else | |
| { | |
| ter(mw, rng(cw + 1, bw - 1)) = t_door_c; | |
| } | |
| if (one_in(2)) // Placement of the main door | |
| { | |
| ter(rng(lw + 2, cw - 1), tw) = (one_in(6) ? t_door_c : t_door_locked); | |
| if (one_in(5)) | |
| { | |
| ter(rw, rng(tw + 2, cw - 2)) = (one_in(6) ? t_door_c : t_door_locked); | |
| } | |
| } | |
| else | |
| { | |
| ter(rng(cw + 1, rw - 2), tw) = (one_in(6) ? t_door_c : t_door_locked); | |
| if (one_in(5)) | |
| { | |
| ter(lw, rng(tw + 2, cw - 2)) = (one_in(6) ? t_door_c : t_door_locked); | |
| } | |
| } | |
| break; | |
| case 2: // Old-style; simple | |
| cw = tw + rng(3, 6); | |
| mw = rng(lw + 7, rw - 4); | |
| // Plop down the rooms | |
| house_room(this, room_living, lw, tw, rw, cw); | |
| house_room(this, room_kitchen, mw, cw, rw, bw - 3); | |
| house_room(this, room_bedroom, lw, cw, mw, bw); | |
| house_room(this, room_bathroom, mw, bw - 3, rw, bw); | |
| // Space between kitchen & living room: | |
| rn = rng(mw + 1, rw - 3); | |
| ter(rn , cw) = t_floor; | |
| ter(rn + 1, cw) = t_floor; | |
| // Front windows | |
| rn = rng(2, 5); | |
| ter(lw + rn , tw) = t_window_domestic; | |
| ter(lw + rn + 1, tw) = t_window_domestic; | |
| ter(rw - rn , tw) = t_window_domestic; | |
| ter(rw - rn + 1, tw) = t_window_domestic; | |
| // Front door | |
| ter(rng(lw + 4, rw - 4), tw) = (one_in(6) ? t_door_c : t_door_locked); | |
| if (one_in(3)) // Kitchen windows | |
| { | |
| rn = rng(cw + 1, bw - 5); | |
| ter(rw, rn) = t_window_domestic; | |
| ter(rw, rn + 1) = t_window_domestic; | |
| } | |
| if (one_in(3)) // Bedroom windows | |
| { | |
| rn = rng(cw + 1, bw - 2); | |
| ter(lw, rn) = t_window_domestic; | |
| ter(lw, rn + 1) = t_window_domestic; | |
| } | |
| // Door to bedroom | |
| if (one_in(4)) | |
| { | |
| ter(rng(lw + 1, mw - 1), cw) = t_door_c; | |
| } | |
| else | |
| { | |
| ter(mw, rng(cw + 3, bw - 4)) = t_door_c; | |
| } | |
| // Door to bathrom | |
| if (one_in(4)) | |
| { | |
| ter(mw, bw - 1) = t_door_c; | |
| } | |
| else | |
| { | |
| ter(rng(mw + 2, rw - 2), bw - 3) = t_door_c; | |
| } | |
| // Back windows | |
| rn = rng(lw + 1, mw - 2); | |
| ter(rn , bw) = t_window_domestic; | |
| ter(rn + 1, bw) = t_window_domestic; | |
| rn = rng(mw + 1, rw - 1); | |
| ter(rn, bw) = t_window_domestic; | |
| break; | |
| case 3: // Long center hallway | |
| mw = int((lw + rw) / 2); | |
| cw = bw - rng(5, 7); | |
| // Hallway doors and windows | |
| ter(mw , tw) = (one_in(6) ? t_door_c : t_door_locked); | |
| if (one_in(4)) | |
| { | |
| ter(mw - 1, tw) = t_window_domestic; | |
| ter(mw + 1, tw) = t_window_domestic; | |
| } | |
| for (int i = tw + 1; i < cw; i++) // Hallway walls | |
| { | |
| ter(mw - 2, i) = t_wall_v; | |
| ter(mw + 2, i) = t_wall_v; | |
| } | |
| if (one_in(2)) // Front rooms are kitchen or living room | |
| { | |
| house_room(this, room_living, lw, tw, mw - 2, cw); | |
| house_room(this, room_kitchen, mw + 2, tw, rw, cw); | |
| } | |
| else | |
| { | |
| house_room(this, room_kitchen, lw, tw, mw - 2, cw); | |
| house_room(this, room_living, mw + 2, tw, rw, cw); | |
| } | |
| // Front windows | |
| rn = rng(lw + 1, mw - 4); | |
| ter(rn , tw) = t_window_domestic; | |
| ter(rn + 1, tw) = t_window_domestic; | |
| rn = rng(mw + 3, rw - 2); | |
| ter(rn , tw) = t_window_domestic; | |
| ter(rn + 1, tw) = t_window_domestic; | |
| if (one_in(4)) // Side windows? | |
| { | |
| rn = rng(tw + 1, cw - 2); | |
| ter(lw, rn) = t_window_domestic; | |
| ter(lw, rn + 1) = t_window_domestic; | |
| } | |
| if (one_in(4)) // Side windows? | |
| { | |
| rn = rng(tw + 1, cw - 2); | |
| ter(rw, rn) = t_window_domestic; | |
| ter(rw, rn + 1) = t_window_domestic; | |
| } | |
| if (one_in(2)) // Bottom rooms are bedroom or bathroom | |
| { | |
| house_room(this, room_bedroom, lw, cw, rw - 3, bw); | |
| house_room(this, room_bathroom, rw - 3, cw, rw, bw); | |
| ter(rng(lw + 2, mw - 3), cw) = t_door_c; | |
| if (one_in(4)) | |
| { | |
| ter(rng(rw - 2, rw - 1), cw) = t_door_c; | |
| } | |
| else | |
| { | |
| ter(rw - 3, rng(cw + 2, bw - 2)) = t_door_c; | |
| } | |
| rn = rng(lw + 1, rw - 5); | |
| ter(rn , bw) = t_window_domestic; | |
| ter(rn + 1, bw) = t_window_domestic; | |
| if (one_in(4)) | |
| { | |
| ter(rng(rw - 2, rw - 1), bw) = t_window_domestic; | |
| } | |
| else | |
| { | |
| ter(rw, rng(cw + 1, bw - 1)); | |
| } | |
| } | |
| else | |
| { | |
| house_room(this, room_bathroom, lw, cw, lw + 3, bw); | |
| house_room(this, room_bedroom, lw + 3, cw, rw, bw); | |
| if (one_in(4)) | |
| { | |
| ter(rng(lw + 1, lw + 2), cw) = t_door_c; | |
| } | |
| else | |
| { | |
| ter(lw + 3, rng(cw + 2, bw - 2)) = t_door_c; | |
| } | |
| rn = rng(lw + 4, rw - 2); | |
| ter(rn , bw) = t_window_domestic; | |
| ter(rn + 1, bw) = t_window_domestic; | |
| if (one_in(4)) | |
| { | |
| ter(rng(lw + 1, lw + 2), bw) = t_window_domestic; | |
| } | |
| else | |
| { | |
| ter(lw, rng(cw + 1, bw - 1)); | |
| } | |
| } | |
| // Doors off the sides of the hallway | |
| ter(mw - 2, rng(tw + 3, cw - 3)) = t_door_c; | |
| ter(mw + 2, rng(tw + 3, cw - 3)) = t_door_c; | |
| ter(mw, cw) = t_door_c; | |
| break; | |
| } // Done with the various house structures | |
| if (rng(2, 7) < tw) // Big front yard has a chance for a fence | |
| { | |
| for (int i = lw; i <= rw; i++) | |
| { | |
| ter(i, 0) = t_fence_h; | |
| } | |
| for (int i = 1; i < tw; i++) | |
| { | |
| ter(lw, i) = t_fence_v; | |
| ter(rw, i) = t_fence_v; | |
| } | |
| int hole = rng(SEEX - 3, SEEX + 2); | |
| ter(hole, 0) = t_dirt; | |
| ter(hole + 1, 0) = t_dirt; | |
| if (one_in(tw)) | |
| { | |
| ter(hole - 1, 1) = t_tree_young; | |
| ter(hole + 2, 1) = t_tree_young; | |
| } | |
| } | |
| if (terrain_type >= ot_house_base_north && | |
| terrain_type <= ot_house_base_west) | |
| { | |
| do | |
| { | |
| rn = rng(lw + 1, rw - 1); | |
| } | |
| while (ter(rn, bw - 1) != t_floor); | |
| ter(rn, bw - 1) = t_stairs_down; | |
| } | |
| if (one_in(100)) // Houses have a 1 in 100 chance of wasps! | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (ter(i, j) == t_door_c || ter(i, j) == t_door_locked) | |
| { | |
| ter(i, j) = t_door_frame; | |
| } | |
| if (ter(i, j) == t_window_domestic && !one_in(3)) | |
| { | |
| ter(i, j) = t_window_frame; | |
| } | |
| if ((ter(i, j) == t_wall_h || ter(i, j) == t_wall_v) && one_in(8)) | |
| { | |
| ter(i, j) = t_paper; | |
| } | |
| } | |
| } | |
| int num_pods = rng(8, 12); | |
| for (int i = 0; i < num_pods; i++) | |
| { | |
| int podx = rng(1, SEEX * 2 - 2), pody = rng(1, SEEY * 2 - 2); | |
| int nonx = 0, nony = 0; | |
| while (nonx == 0 && nony == 0) | |
| { | |
| nonx = rng(-1, 1); | |
| nony = rng(-1, 1); | |
| } | |
| for (int x = -1; x <= 1; x++) | |
| { | |
| for (int y = -1; y <= 1; y++) | |
| { | |
| if ((x != nonx || y != nony) && (x != 0 || y != 0)) | |
| { | |
| ter(podx + x, pody + y) = t_paper; | |
| } | |
| } | |
| } | |
| add_spawn(mon_wasp, 1, podx, pody); | |
| } | |
| place_items(mi_rare, 70, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, false, turn); | |
| } | |
| else if (one_in(150)) // No wasps; black widows? | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (ter(i, j) == t_floor) | |
| { | |
| if (one_in(15)) | |
| { | |
| add_spawn(mon_spider_widow, rng(1, 2), i, j); | |
| for (int x = i - 1; x <= i + 1; x++) | |
| { | |
| for (int y = j - 1; y <= j + 1; y++) | |
| { | |
| if (ter(x, y) == t_floor) | |
| { | |
| add_field(NULL, x, y, fd_web, rng(2, 3)); | |
| } | |
| } | |
| } | |
| } | |
| else if (move_cost(i, j) > 0 && field_at(i, j).is_null() && one_in(5)) | |
| { | |
| add_field(NULL, x, y, fd_web, 1); | |
| } | |
| } | |
| } | |
| } | |
| place_items(mi_rare, 60, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, false, turn); | |
| } | |
| if (terrain_type == ot_house_east || terrain_type == ot_house_base_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_house_south || terrain_type == ot_house_base_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_house_west || terrain_type == ot_house_base_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_s_lot: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if ((j == 5 || j == 9 || j == 13 || j == 17 || j == 21) && | |
| ((i > 1 && i < 8) || (i > 14 && i < SEEX * 2 - 2))) | |
| { | |
| ter(i, j) = t_pavement_y; | |
| } | |
| else if ((j < 2 && i > 7 && i < 17) || | |
| (j >= 2 && j < SEEY * 2 - 2 && i > 1 && i < SEEX * 2 - 2)) | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| } | |
| if (x_in_y(2, 3)) | |
| { | |
| int vx = rng(0, 3) * 4 + 5; | |
| int vy = 4; | |
| vhtype_id vt = veh_null; | |
| int r = rng(1, 100); | |
| if (r <= 10)//specials | |
| { | |
| int ra = rng(1, 100); | |
| if (ra <= 3) | |
| { | |
| vt = veh_armytruck; | |
| } | |
| else if (ra <= 10) | |
| { | |
| vt = veh_bubblecar; | |
| } | |
| else if (ra <= 20) | |
| { | |
| vt = veh_schoolbus; | |
| } | |
| else | |
| { | |
| vt = veh_sandbike; | |
| } | |
| } | |
| else if (r <= 30)//commercial | |
| { | |
| int rb = rng(1, 100); | |
| if (rb <= 25) | |
| { | |
| vt = veh_trucktrailer; | |
| } | |
| else if (rb <= 35) | |
| { | |
| vt = veh_semi; | |
| } | |
| else | |
| { | |
| vt = veh_truck; | |
| } | |
| } | |
| else//commons | |
| { | |
| int rc = rng(1, 100); | |
| if (rc <= 4) | |
| { | |
| vt = veh_golfcart; | |
| } | |
| else if (rc <= 11) | |
| { | |
| vt = veh_scooter; | |
| } | |
| else if (rc <= 21) | |
| { | |
| vt = veh_bug; | |
| } | |
| else if (rc <= 50) | |
| { | |
| vt = veh_car; | |
| } | |
| else if (rc <= 75) | |
| { | |
| vt = veh_bicycle; | |
| } | |
| else | |
| { | |
| vt = veh_motorcycle; | |
| } | |
| } | |
| add_vehicle(g, vt, vx, vy, one_in(2) ? 90 : 270); | |
| } | |
| place_items(mi_road, 8, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, false, turn); | |
| if (t_east >= ot_road_null && t_east <= ot_road_nesw_manhole) | |
| { | |
| rotate(1); | |
| } | |
| if (t_south >= ot_road_null && t_south <= ot_road_nesw_manhole) | |
| { | |
| rotate(2); | |
| } | |
| if (t_west >= ot_road_null && t_west <= ot_road_nesw_manhole) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_park: | |
| { | |
| if (one_in(3)) // Playground | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_grass; | |
| } | |
| } | |
| square(this, t_sandbox, 16, 4, 17, 5); | |
| square(this, t_monkey_bars, 4, 7, 6, 9); | |
| line(this, t_slide, 11, 8, 11, 11); | |
| line(this, t_bench, 6, 14, 6, 15); | |
| ter(3, 9) = t_tree; | |
| ter(5, 15) = t_tree; | |
| ter(6, 4) = t_tree; | |
| ter(9, 17) = t_tree; | |
| ter(13, 3) = t_tree; | |
| ter(15, 16) = t_tree; | |
| ter(19, 14) = t_tree; | |
| ter(20, 8) = t_tree; | |
| rotate(rng(0, 3)); | |
| } | |
| else // Basketball court | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| } | |
| line(this, t_pavement_y, 1, 11, 22, 11); | |
| line(this, t_pavement_y, 6, 2, 6, 8); | |
| line(this, t_pavement_y, 16, 2, 16, 8); | |
| line(this, t_pavement_y, 6, 14, 6, 20); | |
| line(this, t_pavement_y, 16, 14, 16, 20); | |
| square(this, t_pavement_y, 9, 2, 13, 4); | |
| square(this, t_pavement_y, 9, 18, 13, 20); | |
| square(this, t_pavement, 10, 2, 12, 3); | |
| square(this, t_pavement, 10, 19, 12, 20); | |
| ter(7, 9) = t_pavement_y; | |
| ter(8, 10) = t_pavement_y; | |
| ter(15, 9) = t_pavement_y; | |
| ter(14, 10) = t_pavement_y; | |
| ter(8, 12) = t_pavement_y; | |
| ter(7, 13) = t_pavement_y; | |
| ter(14, 12) = t_pavement_y; | |
| ter(15, 13) = t_pavement_y; | |
| line(this, t_bench, 1, 4, 1, 10); | |
| line(this, t_bench, 1, 12, 1, 18); | |
| line(this, t_bench, 22, 4, 22, 10); | |
| line(this, t_bench, 22, 12, 22, 18); | |
| ter(11, 2) = t_backboard; | |
| ter(11, 20) = t_backboard; | |
| line(this, t_chainfence_v, 0, 1, 0, 21); | |
| line(this, t_chainfence_v, 23, 1, 23, 21); | |
| line(this, t_chainfence_h, 1, 1, 22, 1); | |
| line(this, t_chainfence_h, 1, 21, 22, 21); | |
| ter(2, 1) = t_chaingate_l; | |
| ter(21, 1) = t_chaingate_l; | |
| ter(2, 21) = t_chaingate_l; | |
| ter(21, 21) = t_chaingate_l; | |
| rotate(rng(0, 3)); | |
| } | |
| add_spawn(mon_zombie_child, rng(2, 8), SEEX, SEEY); | |
| } | |
| break; | |
| case ot_s_gas_north: | |
| case ot_s_gas_east: | |
| case ot_s_gas_south: | |
| case ot_s_gas_west: | |
| tw = rng(5, 14); | |
| bw = SEEY * 2 - rng(1, 2); | |
| mw = rng(tw + 5, bw - 3); | |
| if (mw < bw - 5) | |
| { | |
| mw = bw - 5; | |
| } | |
| lw = rng(0, 3); | |
| rw = SEEX * 2 - rng(1, 4); | |
| cw = rng(lw + 4, rw - 5); | |
| rn = rng(3, 6); // Frequency of gas pumps | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEX * 2; j++) | |
| { | |
| if (j < tw && (tw - j) % 4 == 0 && i > lw && i < rw && | |
| (i - (1 + lw)) % rn == 0) | |
| { | |
| ter(i, j) = t_gas_pump; | |
| } | |
| else if ((j < 2 && i > 7 && i < 16) || (j < tw && i > lw && i < rw)) | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| else if (j == tw && (i == lw + 6 || i == lw + 7 || i == rw - 7 || i == rw - 6)) | |
| { | |
| ter(i, j) = t_window; | |
| } | |
| else if (((j == tw || j == bw) && i >= lw && i <= rw) || | |
| (j == mw && (i >= cw && i < rw))) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else if (((i == lw || i == rw) && j > tw && j < bw) || | |
| (j > mw && j < bw && (i == cw || i == rw - 2))) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else if (i == lw + 1 && j > tw && j < bw) | |
| { | |
| ter(i, j) = t_glass_fridge; | |
| } | |
| else if (i > lw + 2 && i < lw + 12 && i < cw && i % 2 == 1 && | |
| j > tw + 1 && j < mw - 1) | |
| { | |
| ter(i, j) = t_rack; | |
| } | |
| else if ((i == rw - 5 && j > tw + 1 && j < tw + 4) || | |
| (j == tw + 3 && i > rw - 5 && i < rw)) | |
| { | |
| ter(i, j) = t_counter; | |
| } | |
| else if (i > lw && i < rw && j > tw && j < bw) | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| } | |
| ter(cw, rng(mw + 1, bw - 1)) = t_door_c; | |
| ter(rw - 1, mw) = t_door_c; | |
| ter(rw - 1, bw - 1) = t_toilet; | |
| ter(rng(10, 13), tw) = t_door_c; | |
| if (one_in(5)) | |
| { | |
| ter(rng(lw + 1, cw - 1), bw) = (one_in(4) ? t_door_c : t_door_locked); | |
| } | |
| for (int i = lw + (lw % 2 == 0 ? 3 : 4); i < cw && i < lw + 12; i += 2) | |
| { | |
| if (!one_in(3)) | |
| { | |
| place_items(mi_snacks, 74, i, tw + 2, i, mw - 2, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_magazines, 74, i, tw + 2, i, mw - 2, false, 0); | |
| } | |
| } | |
| place_items(mi_fridgesnacks, 82, lw + 1, tw + 1, lw + 1, bw - 1, false, 0); | |
| place_items(mi_road, 12, 0, 0, SEEX * 2 - 1, tw - 1, false, 0); | |
| place_items(mi_behindcounter, 70, rw - 4, tw + 1, rw - 1, tw + 2, false, 0); | |
| place_items(mi_softdrugs, 12, rw - 1, bw - 2, rw - 1, bw - 2, false, 0); | |
| if (terrain_type == ot_s_gas_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_s_gas_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_s_gas_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_s_pharm_north: | |
| case ot_s_pharm_east: | |
| case ot_s_pharm_south: | |
| case ot_s_pharm_west: | |
| tw = rng(0, 4); | |
| bw = SEEY * 2 - rng(1, 5); | |
| mw = bw - rng(3, 4); // Top of the storage room | |
| lw = rng(0, 4); | |
| rw = SEEX * 2 - rng(1, 5); | |
| cw = rng(13, rw - 5); // Left side of the storage room | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (j == tw && ((i > lw + 2 && i < lw + 6) || (i > rw - 6 && i < rw - 2))) | |
| { | |
| ter(i, j) = t_window; | |
| } | |
| else if ((j == tw && (i == lw + 8 || i == lw + 9)) || | |
| (i == cw && j == mw + 1)) | |
| { | |
| ter(i, j) = t_door_c; | |
| } | |
| else if (((j == tw || j == bw) && i >= lw && i <= rw) || | |
| (j == mw && i >= cw && i < rw)) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else if (((i == lw || i == rw) && j > tw && j < bw) || | |
| (i == cw && j > mw && j < bw)) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else if (((i == lw + 8 || i == lw + 9 || i == rw - 4 || i == rw - 3) && | |
| j > tw + 3 && j < mw - 2) || | |
| (j == bw - 1 && i > lw + 1 && i < cw - 1)) | |
| { | |
| ter(i, j) = t_rack; | |
| } | |
| else if ((i == lw + 1 && j > tw + 8 && j < mw - 1) || | |
| (j == mw - 1 && i > cw + 1 && i < rw)) | |
| { | |
| ter(i, j) = t_glass_fridge; | |
| } | |
| else if ((j == mw && i > lw + 1 && i < cw) || | |
| (j == tw + 6 && i > lw + 1 && i < lw + 6) || | |
| (i == lw + 5 && j > tw && j < tw + 7)) | |
| { | |
| ter(i, j) = t_counter; | |
| } | |
| else if (i > lw && i < rw && j > tw && j < bw) | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| } | |
| if (one_in(3)) | |
| { | |
| place_items(mi_snacks, 74, lw + 8, tw + 4, lw + 8, mw - 3, false, 0); | |
| } | |
| else if (one_in(4)) | |
| { | |
| place_items(mi_cleaning, 74, lw + 8, tw + 4, lw + 8, mw - 3, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_magazines, 74, lw + 8, tw + 4, lw + 8, mw - 3, false, 0); | |
| } | |
| if (one_in(5)) | |
| { | |
| place_items(mi_softdrugs, 84, lw + 9, tw + 4, lw + 9, mw - 3, false, 0); | |
| } | |
| else if (one_in(4)) | |
| { | |
| place_items(mi_cleaning, 74, lw + 9, tw + 4, lw + 9, mw - 3, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_snacks, 74, lw + 9, tw + 4, lw + 9, mw - 3, false, 0); | |
| } | |
| if (one_in(5)) | |
| { | |
| place_items(mi_softdrugs, 84, rw - 4, tw + 4, rw - 4, mw - 3, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_snacks, 74, rw - 4, tw + 4, rw - 4, mw - 3, false, 0); | |
| } | |
| if (one_in(3)) | |
| { | |
| place_items(mi_snacks, 70, rw - 3, tw + 4, rw - 3, mw - 3, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_softdrugs, 80, rw - 3, tw + 4, rw - 3, mw - 3, false, 0); | |
| } | |
| place_items(mi_fridgesnacks, 74, lw + 1, tw + 9, lw + 1, mw - 2, false, 0); | |
| place_items(mi_fridgesnacks, 74, cw + 2, mw - 1, rw - 1, mw - 1, false, 0); | |
| place_items(mi_harddrugs, 88, lw + 2, bw - 1, cw - 2, bw - 1, false, 0); | |
| place_items(mi_behindcounter, 78, lw + 1, tw + 1, lw + 4, tw + 5, false, 0); | |
| if (terrain_type == ot_s_pharm_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_s_pharm_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_s_pharm_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_s_grocery_north: | |
| case ot_s_grocery_east: | |
| case ot_s_grocery_south: | |
| case ot_s_grocery_west: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (j == 2 && ((i > 4 && i < 8) || (i > 15 && i < 19))) | |
| { | |
| ter(i, j) = t_window; | |
| } | |
| else if ((j == 2 && (i == 11 || i == 12)) || (i == 6 && j == 20)) | |
| { | |
| ter(i, j) = t_door_c; | |
| } | |
| else if (((j == 2 || j == SEEY * 2 - 3) && i > 1 && i < SEEX * 2 - 2) || | |
| (j == 18 && i > 2 && i < 7)) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else if (((i == 2 || i == SEEX * 2 - 3) && j > 2 && j < SEEY * 2 - 3) || | |
| (i == 6 && j == 19)) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else if (j > 4 && j < 8) | |
| { | |
| if (i == 5 || i == 9 || i == 13 || i == 17) | |
| { | |
| ter(i, j) = t_counter; | |
| } | |
| else if (i == 8 || i == 12 || i == 16 || i == 20) | |
| { | |
| ter(i, j) = t_rack; | |
| } | |
| else if (i > 2 && i < SEEX * 2 - 3) | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| else if ((j == 7 && (i == 3 || i == 4)) || | |
| ((j == 11 || j == 14) && (i == 18 || i == 19)) || | |
| ((j > 9 && j < 16) && (i == 6 || i == 7 || i == 10 || | |
| i == 11 || i == 14 || i == 15 || | |
| i == 20))) | |
| { | |
| ter(i, j) = t_rack; | |
| } | |
| else if ((j == 18 && i > 15 && i < 21) || (j == 19 && i == 16)) | |
| { | |
| ter(i, j) = t_counter; | |
| } | |
| else if ((i == 3 && j > 9 && j < 16) || | |
| (j == 20 && ((i > 7 && i < 15) || (i > 18 && i < 21)))) | |
| { | |
| ter(i, j) = t_glass_fridge; | |
| } | |
| else if (i > 2 && i < SEEX * 2 - 3 && j > 2 && j < SEEY * 2 - 3) | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| } | |
| place_items(mi_fridgesnacks, 65, 3, 10, 3, 15, false, 0); | |
| place_items(mi_fridge, 70, 8, 20, 14, 20, false, 0); | |
| place_items(mi_fridge, 50, 19, 20, 20, 20, false, 0); | |
| place_items(mi_softdrugs, 55, 6, 10, 6, 15, false, 0); | |
| place_items(mi_cleaning, 88, 7, 10, 7, 15, false, 0); | |
| place_items(mi_kitchen, 75, 10, 10, 10, 15, false, 0); | |
| place_items(mi_snacks, 78, 11, 10, 11, 15, false, 0); | |
| place_items(mi_cannedfood, 80, 14, 10, 14, 15, false, 0); | |
| place_items(mi_pasta, 74, 15, 10, 15, 15, false, 0); | |
| place_items(mi_produce, 60, 20, 10, 20, 15, false, 0); | |
| place_items(mi_produce, 50, 18, 11, 19, 11, false, 0); | |
| place_items(mi_produce, 50, 18, 10, 20, 15, false, 0); | |
| for (int i = 8; i < 21; i += 4) // Checkout snacks & magazines | |
| { | |
| place_items(mi_snacks, 50, i, 5, i, 6, false, 0); | |
| place_items(mi_magazines, 70, i, 7, i, 7, false, 0); | |
| } | |
| if (terrain_type == ot_s_grocery_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_s_grocery_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_s_grocery_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_s_hardware_north: | |
| case ot_s_hardware_east: | |
| case ot_s_hardware_south: | |
| case ot_s_hardware_west: | |
| rn = 0; // No back door | |
| // if (!one_in(3)) | |
| // rn = 1; // Old-style back door | |
| if (!one_in(6)) | |
| { | |
| rn = 2; // Paved back area | |
| } | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (j == 3 && ((i > 5 && i < 9) || (i > 14 && i < 18))) | |
| { | |
| ter(i, j) = t_window; | |
| } | |
| else if ((j == 3 && i > 1 && i < SEEX * 2 - 2) || | |
| (j == 15 && i > 1 && i < 14) || | |
| (j == SEEY * 2 - 3 && i > 12 && i < SEEX * 2 - 2)) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else if ((i == 2 && j > 3 && j < 15) || | |
| (i == SEEX * 2 - 3 && j > 3 && j < SEEY * 2 - 3) || | |
| (i == 13 && j > 15 && j < SEEY * 2 - 3)) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else if ((i > 3 && i < 10 && j == 6) || (i == 9 && j > 3 && j < 7)) | |
| { | |
| ter(i, j) = t_counter; | |
| } | |
| else if (((i == 3 || i == 6 || i == 7 || i == 10 || i == 11) && | |
| j > 8 && j < 15) || | |
| (i == SEEX * 2 - 4 && j > 3 && j < SEEX * 2 - 4) || | |
| (i > 14 && i < 18 && | |
| (j == 8 || j == 9 || j == 12 || j == 13)) || | |
| (j == SEEY * 2 - 4 && i > 13 && i < SEEX * 2 - 4) || | |
| (i > 15 && i < 18 && j > 15 && j < 18) || | |
| (i == 9 && j == 7)) | |
| { | |
| ter(i, j) = t_rack; | |
| } | |
| else if ((i > 2 && i < SEEX * 2 - 3 && j > 3 && j < 15) || | |
| (i > 13 && i < SEEX * 2 - 3 && j > 14 && j < SEEY * 2 - 3)) | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| else if (rn == 2 && i > 1 && i < 13 && j > 15 && j < SEEY * 2 - 3) | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| } | |
| ter(rng(10, 13), 3) = t_door_c; | |
| if (rn > 0) | |
| { | |
| ter(13, rng(16, 19)) = (one_in(3) ? t_door_c : t_door_locked); | |
| } | |
| if (rn == 2) | |
| { | |
| if (one_in(5)) | |
| { | |
| ter(rng(4, 10), 16) = t_gas_pump; | |
| } | |
| else | |
| { | |
| ter(rng(4, 10), 16) = t_recycler; | |
| } | |
| if (one_in(3)) // Place a dumpster | |
| { | |
| int startx = rng(2, 11), starty = rng(18, 19); | |
| if (startx == 11) | |
| { | |
| starty = 18; | |
| } | |
| bool hori = (starty == 18 ? false : true); | |
| for (int i = startx; i <= startx + (hori ? 3 : 2); i++) | |
| { | |
| for (int j = starty; j <= starty + (hori ? 2 : 3); j++) | |
| { | |
| ter(i, j) = t_dumpster; | |
| } | |
| } | |
| if (hori) | |
| { | |
| place_items(mi_trash, 30, startx, starty, startx + 3, starty + 2, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_trash, 30, startx, starty, startx + 2, starty + 3, false, 0); | |
| } | |
| } | |
| place_items(mi_road, 30, 2, 16, 12, SEEY * 2 - 3, false, 0); | |
| } | |
| place_items(mi_magazines, 70, 9, 7, 9, 7, false, 0); | |
| if (one_in(4)) | |
| { | |
| place_items(mi_snacks, 70, 9, 7, 9, 7, false, 0); | |
| } | |
| if (!one_in(3)) | |
| { | |
| place_items(mi_hardware, 80, 3, 9, 3, 14, false, 0); | |
| } | |
| else if (!one_in(3)) | |
| { | |
| place_items(mi_tools, 80, 3, 9, 3, 14, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_bigtools, 80, 3, 9, 3, 14, false, 0); | |
| } | |
| if (!one_in(3)) | |
| { | |
| place_items(mi_hardware, 80, 6, 9, 6, 14, false, 0); | |
| } | |
| else if (!one_in(3)) | |
| { | |
| place_items(mi_tools, 80, 6, 9, 6, 14, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_bigtools, 80, 6, 9, 6, 14, false, 0); | |
| } | |
| if (!one_in(4)) | |
| { | |
| place_items(mi_tools, 80, 7, 9, 7, 14, false, 0); | |
| } | |
| else if (one_in(4)) | |
| { | |
| place_items(mi_mischw, 80, 7, 9, 7, 14, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_hardware, 80, 7, 9, 7, 14, false, 0); | |
| } | |
| if (!one_in(4)) | |
| { | |
| place_items(mi_tools, 80, 10, 9, 10, 14, false, 0); | |
| } | |
| else if (one_in(4)) | |
| { | |
| place_items(mi_mischw, 80, 10, 9, 10, 14, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_hardware, 80, 10, 9, 10, 14, false, 0); | |
| } | |
| if (!one_in(3)) | |
| { | |
| place_items(mi_bigtools, 75, 11, 9, 11, 14, false, 0); | |
| } | |
| else if (one_in(2)) | |
| { | |
| place_items(mi_cleaning, 75, 11, 9, 11, 14, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_tools, 75, 11, 9, 11, 14, false, 0); | |
| } | |
| if (one_in(2)) | |
| { | |
| place_items(mi_cleaning, 65, 15, 8, 17, 8, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_snacks, 65, 15, 8, 17, 8, false, 0); | |
| } | |
| if (one_in(4)) | |
| { | |
| place_items(mi_hardware, 74, 15, 9, 17, 9, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_cleaning, 74, 15, 9, 17, 9, false, 0); | |
| } | |
| if (one_in(4)) | |
| { | |
| place_items(mi_hardware, 74, 15, 12, 17, 12, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_cleaning, 74, 15, 12, 17, 12, false, 0); | |
| } | |
| place_items(mi_mischw, 90, 20, 4, 20, 19, false, 0); | |
| if (terrain_type == ot_s_hardware_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_s_hardware_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_s_hardware_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_s_electronics_north: | |
| case ot_s_electronics_east: | |
| case ot_s_electronics_south: | |
| case ot_s_electronics_west: | |
| square(this, grass_or_dirt(), 0, 0, SEEX * 2, SEEY * 2); | |
| square(this, t_floor, 4, 4, SEEX * 2 - 4, SEEY * 2 - 4); | |
| line(this, t_wall_v, 3, 4, 3, SEEY * 2 - 4); | |
| line(this, t_wall_v, SEEX * 2 - 3, 4, SEEX * 2 - 3, SEEY * 2 - 4); | |
| line(this, t_wall_h, 3, 3, SEEX * 2 - 3, 3); | |
| line(this, t_wall_h, 3, SEEY * 2 - 3, SEEX * 2 - 3, SEEY * 2 - 3); | |
| ter(13, 3) = t_door_c; | |
| line(this, t_window, 10, 3, 11, 3); | |
| line(this, t_window, 16, 3, 18, 3); | |
| line(this, t_window, SEEX * 2 - 3, 9, SEEX * 2 - 3, 11); | |
| line(this, t_window, SEEX * 2 - 3, 14, SEEX * 2 - 3, 16); | |
| line(this, t_counter, 4, SEEY * 2 - 4, SEEX * 2 - 4, SEEY * 2 - 4); | |
| line(this, t_counter, 4, SEEY * 2 - 5, 4, SEEY * 2 - 9); | |
| line(this, t_counter, SEEX * 2 - 4, SEEY * 2 - 5, SEEX * 2 - 4, SEEY * 2 - 9); | |
| line(this, t_counter, SEEX * 2 - 7, 4, SEEX * 2 - 7, 6); | |
| line(this, t_counter, SEEX * 2 - 7, 7, SEEX * 2 - 5, 7); | |
| line(this, t_rack, 9, SEEY * 2 - 5, 9, SEEY * 2 - 9); | |
| line(this, t_rack, SEEX * 2 - 9, SEEY * 2 - 5, SEEX * 2 - 9, SEEY * 2 - 9); | |
| line(this, t_rack, 4, 4, 4, SEEY * 2 - 10); | |
| line(this, t_rack, 5, 4, 8, 4); | |
| place_items(mi_consumer_electronics, 85, 4, SEEY * 2 - 4, SEEX * 2 - 4, | |
| SEEY * 2 - 4, false, turn - 50); | |
| place_items(mi_consumer_electronics, 85, 4, SEEY * 2 - 5, 4, SEEY * 2 - 9, | |
| false, turn - 50); | |
| place_items(mi_consumer_electronics, 85, SEEX * 2 - 4, SEEY * 2 - 5, | |
| SEEX * 2 - 4, SEEY * 2 - 9, false, turn - 50); | |
| place_items(mi_consumer_electronics, 85, 9, SEEY * 2 - 5, 9, SEEY * 2 - 9, | |
| false, turn - 50); | |
| place_items(mi_consumer_electronics, 85, SEEX * 2 - 9, SEEY * 2 - 5, | |
| SEEX * 2 - 9, SEEY * 2 - 9, false, turn - 50); | |
| place_items(mi_consumer_electronics, 85, 4, 4, 4, SEEY * 2 - 10, false, | |
| turn - 50); | |
| place_items(mi_consumer_electronics, 85, 5, 4, 8, 4, false, turn - 50); | |
| if (terrain_type == ot_s_electronics_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_s_electronics_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_s_electronics_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_s_sports_north: | |
| case ot_s_sports_east: | |
| case ot_s_sports_south: | |
| case ot_s_sports_west: | |
| lw = rng(0, 3); | |
| rw = SEEX * 2 - 1 - rng(0, 3); | |
| tw = rng(3, 10); | |
| bw = SEEY * 2 - 1 - rng(0, 3); | |
| cw = bw - rng(3, 5); | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (((j == tw || j == bw) && i >= lw && i <= rw) || | |
| (j == cw && i > lw && i < rw)) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else if ((i == lw || i == rw) && j > tw && j < bw) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else if ((j == cw - 1 && i > lw && i < rw - 4) || | |
| (j < cw - 3 && j > tw && (i == lw + 1 || i == rw - 1))) | |
| { | |
| ter(i, j) = t_rack; | |
| } | |
| else if (j == cw - 3 && i > lw && i < rw - 4) | |
| { | |
| ter(i, j) = t_counter; | |
| } | |
| else if (j > tw && j < bw && i > lw && i < rw) | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| else if (tw >= 6 && j >= tw - 6 && j < tw && i >= lw && i <= rw) | |
| { | |
| if ((i - lw) % 4 == 0) | |
| { | |
| ter(i, j) = t_pavement_y; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| } | |
| rn = rng(tw + 2, cw - 6); | |
| for (int i = lw + 3; i <= rw - 5; i += 4) | |
| { | |
| if (cw - 6 > tw + 1) | |
| { | |
| ter(i , rn + 1) = t_rack; | |
| ter(i , rn) = t_rack; | |
| ter(i + 1, rn + 1) = t_rack; | |
| ter(i + 1, rn) = t_rack; | |
| place_items(mi_camping, 86, i, rn, i + 1, rn + 1, false, 0); | |
| } | |
| else if (cw - 5 > tw + 1) | |
| { | |
| ter(i , cw - 5) = t_rack; | |
| ter(i + 1, cw - 5) = t_rack; | |
| place_items(mi_camping, 80, i, cw - 5, i + 1, cw - 5, false, 0); | |
| } | |
| } | |
| ter(rw - rng(2, 3), cw) = t_door_c; | |
| rn = rng(2, 4); | |
| for (int i = lw + 2; i <= lw + 2 + rn; i++) | |
| { | |
| ter(i, tw) = t_window; | |
| } | |
| for (int i = rw - 2; i >= rw - 2 - rn; i--) | |
| { | |
| ter(i, tw) = t_window; | |
| } | |
| ter(rng(lw + 3 + rn, rw - 3 - rn), tw) = t_door_c; | |
| if (one_in(4)) | |
| { | |
| ter(rng(lw + 2, rw - 2), bw) = t_door_locked; | |
| } | |
| place_items(mi_allsporting, 90, lw + 1, cw - 1, rw - 5, cw - 1, false, 0); | |
| place_items(mi_sports, 82, lw + 1, tw + 1, lw + 1, cw - 4, false, 0); | |
| place_items(mi_sports, 82, rw - 1, tw + 1, rw - 1, cw - 4, false, 0); | |
| if (!one_in(4)) | |
| { | |
| place_items(mi_allsporting, 92, lw + 1, cw + 1, rw - 1, bw - 1, false, 0); | |
| } | |
| if (terrain_type == ot_s_sports_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_s_sports_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_s_sports_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_s_liquor_north: | |
| case ot_s_liquor_east: | |
| case ot_s_liquor_south: | |
| case ot_s_liquor_west: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (j == 2 && (i == 5 || i == 18)) | |
| { | |
| ter(i, j) = t_window; | |
| } | |
| else if (((j == 2 || j == 12) && i > 2 && i < SEEX * 2 - 3) || | |
| (j == 9 && i > 3 && i < 8)) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else if (((i == 3 || i == SEEX * 2 - 4) && j > 2 && j < 12) || | |
| (i == 7 && j > 9 && j < 12)) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else if ((i == 19 && j > 6 && j < 12) || (j == 11 && i > 16 && i < 19)) | |
| { | |
| ter(i, j) = t_glass_fridge; | |
| } | |
| else if (((i == 4 || i == 7 || i == 8) && j > 2 && j < 8) || | |
| (j == 3 && i > 8 && i < 12) || | |
| (i > 10 && i < 13 && j > 4 && j < 7) || | |
| (i > 10 && i < 16 && j > 7 && j < 10)) | |
| { | |
| ter(i, j) = t_rack; | |
| } | |
| else if ((i == 16 && j > 2 && j < 6) || (j == 5 && i > 16 && i < 19)) | |
| { | |
| ter(i, j) = t_counter; | |
| } | |
| else if ((i > 4 && i < 8 && j > 12 && j < 15) || | |
| (i > 17 && i < 20 && j > 14 && j < 18)) | |
| { | |
| ter(i, j) = t_dumpster; | |
| } | |
| else if (i > 2 && i < SEEX * 2 - 3) | |
| { | |
| if (j > 2 && j < 12) | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| else if (j > 12 && j < SEEY * 2 - 1) | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| } | |
| ter(rng(13, 15), 2) = t_door_c; | |
| ter(rng(4, 6), 9) = t_door_c; | |
| ter(rng(9, 16), 12) = t_door_c; | |
| place_items(mi_alcohol, 96, 4, 3, 4, 7, false, 0); | |
| place_items(mi_alcohol, 96, 7, 3, 11, 3, false, 0); | |
| place_items(mi_alcohol, 96, 7, 4, 8, 7, false, 0); | |
| place_items(mi_alcohol, 96, 11, 8, 15, 9, false, 0); | |
| place_items(mi_snacks, 85, 11, 5, 12, 6, false, 0); | |
| place_items(mi_fridgesnacks, 90, 19, 7, 19, 10, false, 0); | |
| place_items(mi_fridgesnacks, 90, 17, 11, 19, 11, false, 0); | |
| place_items(mi_behindcounter, 80, 17, 3, 19, 4, false, 0); | |
| place_items(mi_trash, 30, 5, 14, 7, 14, false, 0); | |
| place_items(mi_trash, 30, 18, 15, 18, 17, false, 0); | |
| if (terrain_type == ot_s_liquor_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_s_liquor_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_s_liquor_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_s_gun_north: | |
| case ot_s_gun_east: | |
| case ot_s_gun_south: | |
| case ot_s_gun_west: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if ((i == 2 || i == SEEX * 2 - 3) && j > 6 && j < SEEY * 2 - 1) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else if ((i == 8 && j > 6 && j < 13) || | |
| (j == 16 && (i == 5 || i == 8 || i == 11 || i == 14 || i == 17))) | |
| { | |
| ter(i, j) = t_counter; | |
| } | |
| else if ((j == 6 && ((i > 4 && i < 8) || (i > 15 && i < 19)))) | |
| { | |
| ter(i, j) = t_window; | |
| } | |
| else if ((j == 14 && i > 3 && i < 15)) | |
| { | |
| ter(i, j) = t_wall_glass_h; | |
| } | |
| else if (j == 16 && i == SEEX * 2 - 4) | |
| { | |
| ter(i, j) = t_door_c; | |
| } | |
| else if (((j == 6 || j == SEEY * 2 - 1) && i > 1 && i < SEEX * 2 - 2) || | |
| ((j == 16 || j == 14) && i > 2 && i < SEEX * 2 - 3)) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else if (((i == 3 || i == SEEX * 2 - 4) && j > 6 && j < 14) || | |
| ((j > 8 && j < 12) && (i == 12 || i == 13 || i == 16)) || | |
| (j == 13 && i > 15 && i < SEEX * 2 - 4)) | |
| { | |
| ter(i, j) = t_rack; | |
| } | |
| else if (i > 2 && i < SEEX * 2 - 3 && j > 6 && j < SEEY * 2 - 1) | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| else if ((j > 0 && j < 6 && | |
| (i == 2 || i == 6 || i == 10 || i == 17 || i == SEEX * 2 - 3))) | |
| { | |
| ter(i, j) = t_pavement_y; | |
| } | |
| else if (j < 6 && i > 1 && i < SEEX * 2 - 2) | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| } | |
| ter(rng(11, 14), 6) = t_door_c; | |
| ter(rng(5, 14), 14) = t_door_c; | |
| place_items(mi_pistols, 70, 12, 9, 13, 11, false, 0); | |
| place_items(mi_shotguns, 60, 16, 9, 16, 11, false, 0); | |
| place_items(mi_rifles, 80, 20, 7, 20, 12, false, 0); | |
| place_items(mi_smg, 25, 3, 7, 3, 8, false, 0); | |
| place_items(mi_assault, 18, 3, 9, 3, 10, false, 0); | |
| place_items(mi_ammo, 93, 3, 11, 3, 13, false, 0); | |
| place_items(mi_allguns, 12, 5, 16, 17, 16, false, 0); | |
| place_items(mi_gunxtras, 67, 16, 13, 19, 13, false, 0); | |
| if (terrain_type == ot_s_gun_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_s_gun_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_s_gun_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_s_clothes_north: | |
| case ot_s_clothes_east: | |
| case ot_s_clothes_south: | |
| case ot_s_clothes_west: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (j == 2 && (i == 11 || i == 12)) | |
| { | |
| ter(i, j) = t_door_glass_c; | |
| } | |
| else if (j == 2 && i > 3 && i < SEEX * 2 - 4) | |
| { | |
| ter(i, j) = t_wall_glass_h; | |
| } | |
| else if (((j == 2 || j == SEEY * 2 - 2) && i > 1 && i < SEEX * 2 - 2) || | |
| (j == 4 && i > 12 && i < SEEX * 2 - 3) || | |
| (j == 17 && i > 2 && i < 12) || | |
| (j == 20 && i > 2 && i < 11)) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else if (((i == 2 || i == SEEX * 2 - 3) && j > 1 && j < SEEY * 2 - 1) || | |
| (i == 11 && (j == 18 || j == 20 || j == 21)) || | |
| (j == 21 && (i == 5 || i == 8))) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else if ((i == 16 && j > 4 && j < 9) || | |
| (j == 8 && (i == 17 || i == 18)) || | |
| (j == 18 && i > 2 && i < 11)) | |
| { | |
| ter(i, j) = t_counter; | |
| } | |
| else if ((i == 3 && j > 4 && j < 13) || | |
| (i == SEEX * 2 - 4 && j > 9 && j < 20) || | |
| ((j == 10 || j == 11) && i > 6 && i < 13) || | |
| ((j == 14 || j == 15) && i > 4 && i < 13) || | |
| ((i == 15 || i == 16) && j > 10 && j < 18) || | |
| (j == SEEY * 2 - 3 && i > 11 && i < 18)) | |
| { | |
| ter(i, j) = t_rack; | |
| } | |
| else if (i > 2 && i < SEEX * 2 - 3 && j > 2 && j < SEEY * 2 - 2) | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| } | |
| for (int i = 3; i <= 9; i += 3) | |
| { | |
| if (one_in(2)) | |
| { | |
| ter(i, SEEY * 2 - 4) = t_door_c; | |
| } | |
| else | |
| { | |
| ter(i + 1, SEEY * 2 - 4) = t_door_c; | |
| } | |
| } | |
| place_items(mi_shoes, 70, 7, 10, 12, 10, false, 0); | |
| place_items(mi_pants, 88, 5, 14, 12, 14, false, 0); | |
| place_items(mi_shirts, 88, 7, 11, 12, 11, false, 0); | |
| place_items(mi_jackets, 80, 3, 5, 3, 12, false, 0); | |
| place_items(mi_winter, 60, 5, 15, 12, 15, false, 0); | |
| place_items(mi_bags, 70, 15, 11, 15, 17, false, 0); | |
| place_items(mi_dresser, 50, 12, 21, 17, 21, false, 0); | |
| place_items(mi_allclothes, 20, 3, 21, 10, 21, false, 0); | |
| place_items(mi_allclothes, 20, 3, 18, 10, 18, false, 0); | |
| switch (rng(0, 2)) | |
| { | |
| case 0: | |
| place_items(mi_pants, 70, 16, 11, 16, 17, false, 0); | |
| break; | |
| case 1: | |
| place_items(mi_shirts, 70, 16, 11, 16, 17, false, 0); | |
| break; | |
| case 2: | |
| place_items(mi_bags, 70, 16, 11, 16, 17, false, 0); | |
| break; | |
| } | |
| switch (rng(0, 2)) | |
| { | |
| case 0: | |
| place_items(mi_pants, 75, 20, 10, 20, 19, false, 0); | |
| break; | |
| case 1: | |
| place_items(mi_shirts, 75, 20, 10, 20, 19, false, 0); | |
| break; | |
| case 2: | |
| place_items(mi_jackets, 75, 20, 10, 20, 19, false, 0); | |
| break; | |
| } | |
| if (terrain_type == ot_s_clothes_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_s_clothes_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_s_clothes_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_s_library_north: | |
| case ot_s_library_east: | |
| case ot_s_library_south: | |
| case ot_s_library_west: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (j == 2) | |
| { | |
| if (i == 5 || i == 6 || i == 17 || i == 18) | |
| { | |
| ter(i, j) = t_window_domestic; | |
| } | |
| else if (i == 11 || i == 12) | |
| { | |
| ter(i, j) = t_door_c; | |
| } | |
| else if (i > 1 && i < SEEX * 2 - 2) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| else if (j == 17 && i > 1 && i < SEEX * 2 - 2) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else if (i == 2) | |
| { | |
| if (j == 6 || j == 7 || j == 10 || j == 11 || j == 14 || j == 15) | |
| { | |
| ter(i, j) = t_window_domestic; | |
| } | |
| else if (j > 1 && j < 17) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| else if (i == SEEX * 2 - 3) | |
| { | |
| if (j == 6 || j == 7) | |
| { | |
| ter(i, j) = t_window_domestic; | |
| } | |
| else if (j > 1 && j < 17) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| else if (((j == 4 || j == 5) && i > 2 && i < 10) || | |
| ((j == 8 || j == 9 || j == 12 || j == 13 || j == 16) && | |
| i > 2 && i < 16) || (i == 20 && j > 7 && j < 17)) | |
| { | |
| ter(i, j) = t_bookcase; | |
| } | |
| else if ((i == 14 && j < 6 && j > 2) || (j == 5 && i > 14 && i < 19)) | |
| { | |
| ter(i, j) = t_counter; | |
| } | |
| else if (i > 2 && i < SEEX * 2 - 3 && j > 2 && j < 17) | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| } | |
| if (!one_in(3)) | |
| { | |
| ter(18, 17) = t_door_c; | |
| } | |
| place_items(mi_magazines, 70, 3, 4, 9, 4, false, 0); | |
| place_items(mi_magazines, 70, 20, 8, 20, 16, false, 0); | |
| place_items(mi_novels, 96, 3, 5, 9, 5, false, 0); | |
| place_items(mi_novels, 96, 3, 8, 15, 9, false, 0); | |
| place_items(mi_manuals, 92, 3, 12, 15, 13, false, 0); | |
| place_items(mi_textbooks, 88, 3, 16, 15, 16, false, 0); | |
| if (terrain_type == ot_s_library_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_s_library_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_s_library_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_s_restaurant_north: | |
| case ot_s_restaurant_east: | |
| case ot_s_restaurant_south: | |
| case ot_s_restaurant_west: | |
| { | |
| // Init to grass/dirt | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| ter_id doortype = (one_in(4) ? t_door_c : t_door_glass_c); | |
| lw = rng(0, 4); | |
| rw = rng(19, 23); | |
| tw = rng(0, 4); | |
| bw = rng(17, 23); | |
| // Fill in with floor | |
| square(this, t_floor, lw + 1, tw + 1, rw - 1, bw - 1); | |
| // Draw the walls | |
| line(this, t_wall_h, lw, tw, rw, tw); | |
| line(this, t_wall_h, lw, bw, rw, bw); | |
| line(this, t_wall_v, lw, tw + 1, lw, bw - 1); | |
| line(this, t_wall_v, rw, tw + 1, rw, bw - 1); | |
| // What's the front wall look like? | |
| switch (rng(1, 3)) | |
| { | |
| case 1: // Door to one side | |
| case 2: | |
| // Mirror it? | |
| if (one_in(2)) | |
| { | |
| ter(lw + 2, tw) = doortype; | |
| } | |
| else | |
| { | |
| ter(rw - 2, tw) = doortype; | |
| } | |
| break; | |
| case 3: // Double-door in center | |
| line(this, doortype, (lw + rw) / 2, tw, 1 + ((lw + rw) / 2), tw); | |
| break; | |
| } | |
| // What type of windows? | |
| switch (rng(1, 6)) | |
| { | |
| case 1: // None! | |
| break; | |
| case 2: | |
| case 3: // Glass walls everywhere | |
| for (int i = lw + 1; i <= rw - 1; i++) | |
| { | |
| if (ter(i, tw) == t_wall_h) | |
| { | |
| ter(i, tw) = t_wall_glass_h; | |
| } | |
| } | |
| while (!one_in(3)) // 2 in 3 chance of having some walls too | |
| { | |
| rn = rng(1, 3); | |
| if (ter(lw + rn, tw) == t_wall_glass_h) | |
| { | |
| ter(lw + rn, tw) = t_wall_h; | |
| } | |
| if (ter(rw - rn, tw) == t_wall_glass_h) | |
| { | |
| ter(rw - rn, tw) = t_wall_h; | |
| } | |
| } | |
| break; | |
| case 4: | |
| case 5: | |
| case 6: // Just some windows | |
| { | |
| rn = rng(1, 3); | |
| int win_width = rng(1, 3); | |
| for (int i = rn; i <= rn + win_width; i++) | |
| { | |
| if (ter(lw + i, tw) == t_wall_h) | |
| { | |
| ter(lw + i, tw) = t_window; | |
| } | |
| if (ter(rw - i, tw) == t_wall_h) | |
| { | |
| ter(rw - i, tw) = t_window; | |
| } | |
| } | |
| } | |
| break; | |
| } // Done building windows | |
| // Build a kitchen | |
| mw = rng(bw - 6, bw - 3); | |
| cw = (one_in(3) ? rw - 3 : rw - 1); // 1 in 3 chance for corridor to back | |
| line(this, t_wall_h, lw + 1, mw, cw, mw); | |
| line(this, t_wall_v, cw, mw + 1, cw, bw - 1); | |
| ter(lw + 1, mw + 1) = t_fridge; | |
| ter(lw + 2, mw + 1) = t_fridge; | |
| place_items(mi_fridge, 80, lw + 1, mw + 1, lw + 2, mw + 1, false, 0); | |
| line(this, t_counter, lw + 3, mw + 1, cw - 1, mw + 1); | |
| place_items(mi_kitchen, 70, lw + 3, mw + 1, cw - 1, mw + 1, false, 0); | |
| // Place a door to the kitchen | |
| if (cw != rw - 1 && one_in(2)) // side door | |
| { | |
| ter(cw, rng(mw + 2, bw - 1)) = t_door_c; | |
| } | |
| else // north-facing door | |
| { | |
| rn = rng(lw + 4, cw - 2); | |
| // Clear the counters around the door | |
| line(this, t_floor, rn - 1, mw + 1, rn + 1, mw + 1); | |
| ter(rn, mw) = t_door_c; | |
| } | |
| // Back door? | |
| if (bw <= 19 || one_in(3)) | |
| { | |
| // If we have a corridor, put it over there | |
| if (cw == rw - 3) | |
| { | |
| // One in two chance of a double-door | |
| if (one_in(2)) | |
| { | |
| line(this, t_door_locked, cw + 1, bw, rw - 1, bw); | |
| } | |
| else | |
| { | |
| ter(rng(cw + 1, rw - 1), bw) = t_door_locked; | |
| } | |
| } | |
| else // No corridor | |
| { | |
| ter(rng(lw + 1, rw - 1), bw) = t_door_locked; | |
| } | |
| } | |
| // Build a dining area | |
| int table_spacing = rng(2, 4); | |
| for (int i = lw + table_spacing + 1; i <= rw - 2 - table_spacing; | |
| i += table_spacing + 2) | |
| { | |
| for (int j = tw + table_spacing + 1; j <= mw - 1 - table_spacing; | |
| j += table_spacing + 2) | |
| { | |
| square(this, t_table, i, j, i + 1, j + 1); | |
| place_items(mi_dining, 70, i, j, i + 1, j + 1, false, 0); | |
| } | |
| } | |
| // Dumpster out back? | |
| if (rng(18, 21) > bw) | |
| { | |
| square(this, t_pavement, lw, bw + 1, rw, 24); | |
| rn = rng(lw + 1, rw - 4); | |
| square(this, t_dumpster, rn, 22, rn + 2, 23); | |
| place_items(mi_trash, 40, rn, 22, rn + 3, 23, false, 0); | |
| place_items(mi_fridge, 50, rn, 22, rn + 3, 23, false, 0); | |
| } | |
| if (terrain_type == ot_s_restaurant_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_s_restaurant_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_s_restaurant_west) | |
| { | |
| rotate(3); | |
| } | |
| } | |
| break; | |
| //.... | |
| case ot_shelter: | |
| { | |
| // Init to grass & dirt; | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| //square(this, t_floor_l, 5, 5, SEEX * 2 - 6, SEEY * 2 - 6); | |
| square(this, t_floor, 5, 5, SEEX * 2 - 6, SEEY * 2 - 6); | |
| /*ter(6,6) = t_counter; | |
| ter(6,7) = t_console_broken;*/ | |
| square(this, t_stairs_down, SEEX - 1, SEEY - 1, SEEX, SEEY); | |
| line(this, t_wall_h, 4, 4, SEEX * 2 - 5, 4); | |
| line(this, t_door_c, SEEX - 1, 4, SEEX, 4); | |
| line(this, t_locker, SEEX - 7, 5, SEEX, 5); | |
| line(this, t_floor, SEEX - 3, 5, SEEX, 5); | |
| line(this, t_wall_h, 4, SEEY * 2 - 5, SEEX * 2 - 5, SEEY * 2 - 5); | |
| line(this, t_door_c, SEEX - 1, SEEY * 2 - 5, SEEX, SEEY * 2 - 5); | |
| line(this, t_wall_v, 4, 5, 4, SEEY * 2 - 6); | |
| line(this, t_door_c, 4, SEEY - 1, 4, SEEY); | |
| line(this, t_wall_v, SEEX * 2 - 5, 5, SEEX * 2 - 5, SEEY * 2 - 6); | |
| line(this, t_door_c, SEEX * 2 - 5, SEEY - 1, SEEX * 2 - 5, SEEY); | |
| ter(SEEX * 2 - 5, SEEY - 3) = t_window_domestic; | |
| ter(SEEX * 2 - 5, SEEY + 2) = t_window_domestic; | |
| ter(4, SEEY - 3) = t_window_domestic; | |
| ter(4, SEEY + 2) = t_window_domestic; | |
| ter(SEEX - 3, 4) = t_window_domestic; | |
| ter(SEEX + 2, 4) = t_window_domestic; | |
| line(this, t_counter, SEEX + 3, 5, SEEX + 3, SEEY - 4); | |
| ter(SEEX + 6, 5) = t_console; | |
| this->add_computer(SEEX + 6, 5, "Evac shelter computer", 0); | |
| line(this, t_counter, SEEX + 3, SEEY + 3, SEEX + 3, SEEY * 2 - 6); | |
| ter(SEEX + 6, SEEY * 2 - 6) = t_console_broken; | |
| line(this, t_bench, 6, 6, 6, SEEY - 3); | |
| line(this, t_bench, 8, 6, 8, SEEY - 3); | |
| line(this, t_bench, 10, 6, 10, SEEY - 3); | |
| line(this, t_bench, 6, SEEY + 2, 6, SEEY * 2 - 7); | |
| line(this, t_bench, 8, SEEY + 2, 8, SEEY * 2 - 7); | |
| line(this, t_bench, 10, SEEY + 2, 10, SEEY * 2 - 7); | |
| } | |
| break; | |
| //.... | |
| case ot_shelter_under: | |
| square(this, t_rock, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1); | |
| square(this, t_rock_floor, 8, 8, SEEX * 2 - 9, SEEY * 2 - 9); | |
| line(this, t_stairs_up, SEEX - 1, SEEY * 2 - 8, SEEX, SEEY * 2 - 8); | |
| place_items(mi_shelter, 80, 8, 8, SEEX * 2 - 9, SEEY * 2 - 9, false, 0); | |
| break; | |
| //.... | |
| case ot_lmoe: | |
| { | |
| // Init to grass & dirt; | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| square(this, t_shrub, 7, 6, 16, 12); | |
| square(this, t_rock, 10, 9, 13, 12); | |
| square(this, t_rock_floor, 11, 10, 12, 11); | |
| line(this, t_stairs_down, 11, 10, 12, 10); | |
| ter(11, 12) = t_door_metal_c; | |
| line(this, t_tree, 9, 8, 14, 8); | |
| line(this, t_tree, 9, 8, 9, 12); | |
| line(this, t_tree, 14, 8, 14, 12); | |
| square(this, t_shrub, 13, 13, 15, 14); | |
| square(this, t_shrub, 8, 13, 10, 14); | |
| ter(10, 6) = t_tree_young; | |
| ter(14, 6) = t_tree_young; | |
| line(this, t_tree_young, 9, 7, 10, 7); | |
| ter(12, 7) = t_tree_young; | |
| ter(14, 7) = t_tree_young; | |
| ter(8, 9) = t_tree_young; | |
| line(this, t_tree_young, 7, 11, 8, 11); | |
| line(this, t_tree_young, 15, 10, 15, 11); | |
| ter(16, 12) = t_tree_young; | |
| ter(9, 13) = t_tree_young; | |
| ter(12, 13) = t_tree_young; | |
| ter(16, 12) = t_tree_young; | |
| line(this, t_tree_young, 14, 13, 15, 13); | |
| ter(10, 14) = t_tree_young; | |
| ter(13, 14) = t_tree_young; | |
| } | |
| break; | |
| //.... | |
| case ot_lmoe_under: | |
| square(this, t_rock, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1); | |
| square(this, t_rock_floor, 3, 3, 20, 20); | |
| line(this, t_stairs_up, 11, 20, 12, 20); | |
| line(this, t_wall_metal_h, 3, 12, 20, 12); | |
| line(this, t_wall_metal_v, 10, 12, 10, 20); | |
| line(this, t_wall_metal_v, 13, 12, 13, 20); | |
| line(this, t_chainfence_v, 7, 3, 7, 6); | |
| line(this, t_chainfence_h, 3, 6, 6, 6); | |
| line(this, t_wall_metal_v, 15, 3, 15, 10); | |
| line(this, t_wall_metal_h, 15, 9, 20, 9); | |
| line(this, t_wall_metal_v, 17, 10, 17, 11); | |
| ter(10, 16) = t_door_metal_c; | |
| ter(13, 16) = t_door_metal_c; | |
| ter(5, 6) = t_chaingate_c; | |
| line(this, t_door_metal_c, 11, 12, 12, 12); | |
| ter(17, 11) = t_door_metal_c; | |
| ter(15, 6) = t_door_metal_c; | |
| square(this, t_rubble, 18, 18, 20, 20); | |
| line(this, t_rubble, 16, 20, 20, 16); | |
| line(this, t_rubble, 17, 20, 20, 17); | |
| line(this, t_water_sh, 15, 20, 20, 15); | |
| //square(this, t_emergency_light_flicker, 11, 13, 12, 19); | |
| ter(17, 16) = t_woodstove; | |
| ter(14, 13) = t_chair; | |
| ter(14, 18) = t_chair; | |
| square(this, t_crate_c, 18, 13, 20, 14); | |
| line(this, t_crate_c, 17, 13, 19, 15); | |
| line(this, t_counter, 3, 13, 3, 20); | |
| line(this, t_counter, 3, 20, 9, 20); | |
| line(this, t_bookcase, 5, 13, 8, 13); | |
| square(this, t_table, 5, 15, 6, 17); | |
| ter(7, 16) = t_chair; | |
| line(this, t_rack, 3, 11, 7, 11); | |
| line(this, t_rack, 3, 9, 7, 9); | |
| line(this, t_rack, 3, 3, 6, 3); | |
| ter(10, 7) = t_column; | |
| ter(13, 7) = t_column; | |
| line(this, t_bookcase, 16, 3, 16, 5); | |
| square(this, t_bed, 19, 3, 20, 4); | |
| ter(19, 7) = t_chair; | |
| ter(20, 7) = t_desk; | |
| line(this, t_rubble, 15, 10, 16, 10); | |
| ter(19, 10) = t_sink; | |
| ter(20, 11) = t_toilet; | |
| place_items(mi_allguns, 80, 3, 3, 6, 3, false, 0); | |
| place_items(mi_ammo, 80, 3, 3, 6, 3, false, 0); | |
| place_items(mi_cannedfood, 90, 3, 9, 7, 9, false, 0); | |
| place_items(mi_survival_tools, 80, 3, 11, 7, 11, false, 0); | |
| place_items(mi_bags, 50, 3, 11, 7, 11, false, 0); | |
| place_items(mi_softdrugs, 50, 3, 11, 7, 11, false, 0); | |
| place_items(mi_manuals, 60, 5, 13, 8, 13, false, 0); | |
| place_items(mi_textbooks, 60, 5, 13, 8, 13, false, 0); | |
| place_items(mi_tools, 90, 5, 15, 6, 17, false, 0); | |
| place_items(mi_hardware, 70, 3, 13, 3, 20, false, 0); | |
| place_items(mi_stash_wood, 70, 3, 20, 9, 20, false, 0); | |
| place_items(mi_shelter, 70, 18, 13, 20, 14, false, 0); | |
| place_items(mi_novels, 70, 16, 3, 16, 5, false, 0); | |
| place_items(mi_office, 50, 20, 7, 20, 7, false, 0); | |
| //place_items(whatever, 80, 0, 0, 0, 0, false, 0); | |
| break; | |
| case ot_lab: | |
| case ot_lab_stairs: | |
| case ot_lab_core: | |
| // Check for adjacent sewers; used below | |
| tw = 0; | |
| rw = 0; | |
| bw = 0; | |
| lw = 0; | |
| if (t_north >= ot_sewer_ns && t_north <= ot_sewer_nesw && connects_to(t_north, 2)) | |
| { | |
| tw = SEEY * 2; | |
| } | |
| if (t_east >= ot_sewer_ns && t_east <= ot_sewer_nesw && connects_to(t_east, 3)) | |
| { | |
| rw = SEEX * 2; | |
| } | |
| if (t_south >= ot_sewer_ns && t_south <= ot_sewer_nesw && connects_to(t_south, 0)) | |
| { | |
| bw = SEEY * 2; | |
| } | |
| if (t_west >= ot_sewer_ns && t_west <= ot_sewer_nesw && connects_to(t_west, 1)) | |
| { | |
| lw = SEEX * 2; | |
| } | |
| if (t_above == ot_null) // We're on ground level | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i <= 1 || i >= SEEX * 2 - 2 || | |
| (j > 1 && j < SEEY * 2 - 2 && (i == SEEX - 2 || i == SEEX + 1))) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else if (j <= 1 || j >= SEEY * 2 - 2) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| } | |
| } | |
| ter(SEEX - 1, 0) = t_dirt; | |
| ter(SEEX - 1, 1) = t_door_metal_locked; | |
| ter(SEEX , 0) = t_dirt; | |
| ter(SEEX , 1) = t_door_metal_locked; | |
| ter(SEEX - 2 + rng(0, 1) * 4, 0) = t_card_science; | |
| ter(SEEX - 2, SEEY) = t_door_metal_c; | |
| ter(SEEX + 1, SEEY) = t_door_metal_c; | |
| ter(SEEX - 2, SEEY - 1) = t_door_metal_c; | |
| ter(SEEX + 1, SEEY - 1) = t_door_metal_c; | |
| ter(SEEX - 1, SEEY * 2 - 3) = t_stairs_down; | |
| ter(SEEX , SEEY * 2 - 3) = t_stairs_down; | |
| science_room(this, 2 , 2, SEEX - 3 , SEEY * 2 - 3, 1); | |
| science_room(this, SEEX + 2, 2, SEEX * 2 - 3, SEEY * 2 - 3, 3); | |
| add_spawn(mon_turret, 1, SEEX, 5); | |
| if (t_east > ot_road_null && t_east <= ot_road_nesw_manhole) | |
| { | |
| rotate(1); | |
| } | |
| else if (t_south > ot_road_null && t_south <= ot_road_nesw_manhole) | |
| { | |
| rotate(2); | |
| } | |
| else if (t_west > ot_road_null && t_west <= ot_road_nesw_manhole) | |
| { | |
| rotate(3); | |
| } | |
| } | |
| else if (tw != 0 || rw != 0 || lw != 0 || bw != 0) // Sewers! | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| if (((i < lw || i > SEEX * 2 - 1 - rw) && j > SEEY - 3 && j < SEEY + 2) || | |
| ((j < tw || j > SEEY * 2 - 1 - bw) && i > SEEX - 3 && i < SEEX + 2)) | |
| { | |
| ter(i, j) = t_sewage; | |
| } | |
| if ((i == 0 && t_east >= ot_lab && t_east <= ot_lab_core) || | |
| i == SEEX * 2 - 1) | |
| { | |
| if (ter(i, j) == t_sewage) | |
| { | |
| ter(i, j) = t_bars; | |
| } | |
| else if (j == SEEY - 1 || j == SEEY) | |
| { | |
| ter(i, j) = t_door_metal_c; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_concrete_v; | |
| } | |
| } | |
| else if ((j == 0 && t_north >= ot_lab && t_north <= ot_lab_core) || | |
| j == SEEY * 2 - 1) | |
| { | |
| if (ter(i, j) == t_sewage) | |
| { | |
| ter(i, j) = t_bars; | |
| } | |
| else if (i == SEEX - 1 || i == SEEX) | |
| { | |
| ter(i, j) = t_door_metal_c; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_concrete_h; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| else // We're below ground, and no sewers | |
| { | |
| // Set up the boudaries of walls (connect to adjacent lab squares) | |
| tw = (t_north >= ot_lab && t_north <= ot_lab_finale) ? 0 : 2; | |
| rw = (t_east >= ot_lab && t_east <= ot_lab_finale) ? 1 : 2; | |
| bw = (t_south >= ot_lab && t_south <= ot_lab_finale) ? 1 : 2; | |
| lw = (t_west >= ot_lab && t_west <= ot_lab_finale) ? 0 : 2; | |
| switch (rng(1, 3)) // Pick a random lab layout | |
| { | |
| case 1: // Cross shaped | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if ((i < lw || i > SEEX * 2 - 1 - rw) || | |
| ((j < SEEY - 1 || j > SEEY) && (i == SEEX - 2 || i == SEEX + 1))) | |
| { | |
| ter(i, j) = t_concrete_v; | |
| } | |
| else if ((j < tw || j > SEEY * 2 - 1 - bw) || | |
| ((i < SEEX - 1 || i > SEEX) && (j == SEEY - 2 || j == SEEY + 1))) | |
| { | |
| ter(i, j) = t_concrete_h; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (t_above == ot_lab_stairs) | |
| { | |
| ter(rng(SEEX - 1, SEEX), rng(SEEY - 1, SEEY)) = t_stairs_up; | |
| } | |
| // Top left | |
| if (one_in(2)) | |
| { | |
| ter(SEEX - 2, int(SEEY / 2)) = t_door_metal_c; | |
| science_room(this, lw, tw, SEEX - 3, SEEY - 3, 1); | |
| } | |
| else | |
| { | |
| ter(int(SEEX / 2), SEEY - 2) = t_door_metal_c; | |
| science_room(this, lw, tw, SEEX - 3, SEEY - 3, 2); | |
| } | |
| // Top right | |
| if (one_in(2)) | |
| { | |
| ter(SEEX + 1, int(SEEY / 2)) = t_door_metal_c; | |
| science_room(this, SEEX + 2, tw, SEEX * 2 - 1 - rw, SEEY - 3, 3); | |
| } | |
| else | |
| { | |
| ter(SEEX + int(SEEX / 2), SEEY - 2) = t_door_metal_c; | |
| science_room(this, SEEX + 2, tw, SEEX * 2 - 1 - rw, SEEY - 3, 2); | |
| } | |
| // Bottom left | |
| if (one_in(2)) | |
| { | |
| ter(int(SEEX / 2), SEEY + 1) = t_door_metal_c; | |
| science_room(this, lw, SEEY + 2, SEEX - 3, SEEY * 2 - 1 - bw, 0); | |
| } | |
| else | |
| { | |
| ter(SEEX - 2, SEEY + int(SEEY / 2)) = t_door_metal_c; | |
| science_room(this, lw, SEEY + 2, SEEX - 3, SEEY * 2 - 1 - bw, 1); | |
| } | |
| // Bottom right | |
| if (one_in(2)) | |
| { | |
| ter(SEEX + int(SEEX / 2), SEEY + 1) = t_door_metal_c; | |
| science_room(this, SEEX + 2, SEEY + 2, SEEX * 2 - 1 - rw, SEEY * 2 - 1 - bw, 0); | |
| } | |
| else | |
| { | |
| ter(SEEX + 1, SEEY + int(SEEY / 2)) = t_door_metal_c; | |
| science_room(this, SEEX + 2, SEEY + 2, SEEX * 2 - 1 - rw, SEEY * 2 - 1 - bw, 3); | |
| } | |
| if (rw == 1) | |
| { | |
| ter(SEEX * 2 - 1, SEEY - 1) = t_door_metal_c; | |
| ter(SEEX * 2 - 1, SEEY) = t_door_metal_c; | |
| } | |
| if (bw == 1) | |
| { | |
| ter(SEEX - 1, SEEY * 2 - 1) = t_door_metal_c; | |
| ter(SEEX , SEEY * 2 - 1) = t_door_metal_c; | |
| } | |
| if (terrain_type == ot_lab_stairs) // Stairs going down | |
| { | |
| std::vector<point> stair_points; | |
| if (tw != 0) | |
| { | |
| stair_points.push_back(point(SEEX - 1, 2)); | |
| stair_points.push_back(point(SEEX - 1, 2)); | |
| stair_points.push_back(point(SEEX , 2)); | |
| stair_points.push_back(point(SEEX , 2)); | |
| } | |
| if (rw != 1) | |
| { | |
| stair_points.push_back(point(SEEX * 2 - 3, SEEY - 1)); | |
| stair_points.push_back(point(SEEX * 2 - 3, SEEY - 1)); | |
| stair_points.push_back(point(SEEX * 2 - 3, SEEY)); | |
| stair_points.push_back(point(SEEX * 2 - 3, SEEY)); | |
| } | |
| if (bw != 1) | |
| { | |
| stair_points.push_back(point(SEEX - 1, SEEY * 2 - 3)); | |
| stair_points.push_back(point(SEEX - 1, SEEY * 2 - 3)); | |
| stair_points.push_back(point(SEEX , SEEY * 2 - 3)); | |
| stair_points.push_back(point(SEEX , SEEY * 2 - 3)); | |
| } | |
| if (lw != 0) | |
| { | |
| stair_points.push_back(point(2, SEEY - 1)); | |
| stair_points.push_back(point(2, SEEY - 1)); | |
| stair_points.push_back(point(2, SEEY)); | |
| stair_points.push_back(point(2, SEEY)); | |
| } | |
| stair_points.push_back(point(int(SEEX / 2) , SEEY)); | |
| stair_points.push_back(point(int(SEEX / 2) , SEEY - 1)); | |
| stair_points.push_back(point(int(SEEX / 2) + SEEX, SEEY)); | |
| stair_points.push_back(point(int(SEEX / 2) + SEEX, SEEY - 1)); | |
| stair_points.push_back(point(SEEX , int(SEEY / 2))); | |
| stair_points.push_back(point(SEEX + 2, int(SEEY / 2))); | |
| stair_points.push_back(point(SEEX , int(SEEY / 2) + SEEY)); | |
| stair_points.push_back(point(SEEX + 2, int(SEEY / 2) + SEEY)); | |
| rn = rng(0, stair_points.size() - 1); | |
| ter(stair_points[rn].x, stair_points[rn].y) = t_stairs_down; | |
| } | |
| break; | |
| case 2: // tic-tac-toe # layout | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i < lw || i > SEEX * 2 - 1 - rw || i == SEEX - 4 || i == SEEX + 3) | |
| { | |
| ter(i, j) = t_concrete_v; | |
| } | |
| else if (j < lw || j > SEEY * 2 - 1 - bw || j == SEEY - 4 || j == SEEY + 3) | |
| { | |
| ter(i, j) = t_concrete_h; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (t_above == ot_lab_stairs) | |
| { | |
| ter(SEEX - 1, SEEY - 1) = t_stairs_up; | |
| ter(SEEX , SEEY - 1) = t_stairs_up; | |
| ter(SEEX - 1, SEEY) = t_stairs_up; | |
| ter(SEEX , SEEY) = t_stairs_up; | |
| } | |
| ter(SEEX - rng(0, 1), SEEY - 4) = t_door_metal_c; | |
| ter(SEEX - rng(0, 1), SEEY + 3) = t_door_metal_c; | |
| ter(SEEX - 4, SEEY + rng(0, 1)) = t_door_metal_c; | |
| ter(SEEX + 3, SEEY + rng(0, 1)) = t_door_metal_c; | |
| ter(SEEX - 4, int(SEEY / 2)) = t_door_metal_c; | |
| ter(SEEX + 3, int(SEEY / 2)) = t_door_metal_c; | |
| ter(int(SEEX / 2), SEEY - 4) = t_door_metal_c; | |
| ter(int(SEEX / 2), SEEY + 3) = t_door_metal_c; | |
| ter(SEEX + int(SEEX / 2), SEEY - 4) = t_door_metal_c; | |
| ter(SEEX + int(SEEX / 2), SEEY + 3) = t_door_metal_c; | |
| ter(SEEX - 4, SEEY + int(SEEY / 2)) = t_door_metal_c; | |
| ter(SEEX + 3, SEEY + int(SEEY / 2)) = t_door_metal_c; | |
| science_room(this, lw, tw, SEEX - 5, SEEY - 5, rng(1, 2)); | |
| science_room(this, SEEX - 3, tw, SEEX + 2, SEEY - 5, 2); | |
| science_room(this, SEEX + 4, tw, SEEX * 2 - 1 - rw, SEEY - 5, rng(2, 3)); | |
| science_room(this, lw, SEEY - 3, SEEX - 5, SEEY + 2, 1); | |
| science_room(this, SEEX + 4, SEEY - 3, SEEX * 2 - 1 - rw, SEEY + 2, 3); | |
| science_room(this, lw, SEEY + 4, SEEX - 5, SEEY * 2 - 1 - bw, rng(0, 1)); | |
| science_room(this, SEEX - 3, SEEY + 4, SEEX + 2, SEEY * 2 - 1 - bw, 0); | |
| science_room(this, SEEX + 4, SEEX + 4, SEEX * 2 - 1 - rw, SEEY * 2 - 1 - bw, 3 * rng(0, 1)); | |
| if (rw == 1) | |
| { | |
| ter(SEEX * 2 - 1, SEEY - 1) = t_door_metal_c; | |
| ter(SEEX * 2 - 1, SEEY) = t_door_metal_c; | |
| } | |
| if (bw == 1) | |
| { | |
| ter(SEEX - 1, SEEY * 2 - 1) = t_door_metal_c; | |
| ter(SEEX , SEEY * 2 - 1) = t_door_metal_c; | |
| } | |
| if (terrain_type == ot_lab_stairs) | |
| { | |
| ter(SEEX - 3 + 5 * rng(0, 1), SEEY - 3 + 5 * rng(0, 1)) = t_stairs_down; | |
| } | |
| break; | |
| case 3: // Big room | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i < lw || i >= SEEX * 2 - 1 - rw) | |
| { | |
| ter(i, j) = t_concrete_v; | |
| } | |
| else if (j < tw || j >= SEEY * 2 - 1 - bw) | |
| { | |
| ter(i, j) = t_concrete_h; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| science_room(this, lw, tw, SEEX * 2 - 1 - rw, SEEY * 2 - 1 - bw, rng(0, 3)); | |
| if (t_above == ot_lab_stairs) | |
| { | |
| int sx, sy; | |
| do | |
| { | |
| sx = rng(lw, SEEX * 2 - 1 - rw); | |
| sy = rng(tw, SEEY * 2 - 1 - bw); | |
| } | |
| while (ter(sx, sy) != t_rock_floor); | |
| ter(sx, sy) = t_stairs_up; | |
| } | |
| if (rw == 1) | |
| { | |
| ter(SEEX * 2 - 1, SEEY - 1) = t_door_metal_c; | |
| ter(SEEX * 2 - 1, SEEY) = t_door_metal_c; | |
| } | |
| if (bw == 1) | |
| { | |
| ter(SEEX - 1, SEEY * 2 - 1) = t_door_metal_c; | |
| ter(SEEX , SEEY * 2 - 1) = t_door_metal_c; | |
| } | |
| if (terrain_type == ot_lab_stairs) | |
| { | |
| int sx, sy; | |
| do | |
| { | |
| sx = rng(lw, SEEX * 2 - 1 - rw); | |
| sy = rng(tw, SEEY * 2 - 1 - bw); | |
| } | |
| while (ter(sx, sy) != t_rock_floor); | |
| ter(sx, sy) = t_stairs_down; | |
| } | |
| break; | |
| } | |
| } | |
| // Ants will totally wreck up the place | |
| tw = 0; | |
| rw = 0; | |
| bw = 0; | |
| lw = 0; | |
| if (t_north >= ot_ants_ns && t_north <= ot_ants_nesw && connects_to(t_north, 2)) | |
| { | |
| tw = SEEY; | |
| } | |
| if (t_east >= ot_ants_ns && t_east <= ot_ants_nesw && connects_to(t_east, 3)) | |
| { | |
| rw = SEEX; | |
| } | |
| if (t_south >= ot_ants_ns && t_south <= ot_ants_nesw && connects_to(t_south, 0)) | |
| { | |
| bw = SEEY + 1; | |
| } | |
| if (t_west >= ot_ants_ns && t_west <= ot_ants_nesw && connects_to(t_west, 1)) | |
| { | |
| lw = SEEX + 1; | |
| } | |
| if (tw != 0 || rw != 0 || bw != 0 || lw != 0) | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if ((i < SEEX * 2 - lw && (!one_in(3) || (j > SEEY - 6 && j < SEEY + 5))) || | |
| (i > rw && (!one_in(3) || (j > SEEY - 6 && j < SEEY + 5))) || | |
| (j > tw && (!one_in(3) || (i > SEEX - 6 && i < SEEX + 5))) || | |
| (j < SEEY * 2 - bw && (!one_in(3) || (i > SEEX - 6 && i < SEEX + 5)))) | |
| { | |
| if (one_in(5)) | |
| { | |
| ter(i, j) = t_rubble; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // Slimes pretty much wreck up the place, too, but only underground | |
| tw = (t_north == ot_slimepit ? SEEY : 0); | |
| rw = (t_east == ot_slimepit ? SEEX + 1 : 0); | |
| bw = (t_south == ot_slimepit ? SEEY + 1 : 0); | |
| lw = (t_west == ot_slimepit ? SEEX : 0); | |
| if (tw != 0 || rw != 0 || bw != 0 || lw != 0) | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (((j <= tw || i >= rw) && i >= j && (SEEX * 2 - 1 - i) <= j) || | |
| ((j >= bw || i <= lw) && i <= j && (SEEY * 2 - 1 - j) <= i)) | |
| { | |
| if (one_in(5)) | |
| { | |
| ter(i, j) = t_rubble; | |
| } | |
| else if (!one_in(5)) | |
| { | |
| ter(i, j) = t_slime; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| case ot_lab_finale: | |
| tw = (t_north >= ot_lab && t_north <= ot_lab_finale) ? 0 : 2; | |
| rw = (t_east >= ot_lab && t_east <= ot_lab_finale) ? 1 : 2; | |
| bw = (t_south >= ot_lab && t_south <= ot_lab_finale) ? 1 : 2; | |
| lw = (t_west >= ot_lab && t_west <= ot_lab_finale) ? 0 : 2; | |
| // Start by setting up a large, empty room. | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i < lw || i > SEEX * 2 - 1 - rw) | |
| { | |
| ter(i, j) = t_concrete_v; | |
| } | |
| else if (j < tw || j > SEEY * 2 - 1 - bw) | |
| { | |
| ter(i, j) = t_concrete_h; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| } | |
| } | |
| if (rw == 1) | |
| { | |
| ter(SEEX * 2 - 1, SEEY - 1) = t_door_metal_c; | |
| ter(SEEX * 2 - 1, SEEY) = t_door_metal_c; | |
| } | |
| if (bw == 1) | |
| { | |
| ter(SEEX - 1, SEEY * 2 - 1) = t_door_metal_c; | |
| ter(SEEX , SEEY * 2 - 1) = t_door_metal_c; | |
| } | |
| switch (rng(1, 3)) | |
| { | |
| case 1: // Weapons testing | |
| add_spawn(mon_secubot, 1, 6, 6); | |
| add_spawn(mon_secubot, 1, SEEX * 2 - 7, 6); | |
| add_spawn(mon_secubot, 1, 6, SEEY * 2 - 7); | |
| add_spawn(mon_secubot, 1, SEEX * 2 - 7, SEEY * 2 - 7); | |
| add_trap(SEEX - 2, SEEY - 2, tr_dissector); | |
| add_trap(SEEX + 1, SEEY - 2, tr_dissector); | |
| add_trap(SEEX - 2, SEEY + 1, tr_dissector); | |
| add_trap(SEEX + 1, SEEY + 1, tr_dissector); | |
| if (!one_in(3)) | |
| { | |
| rn = dice(4, 3); | |
| for (int i = 0; i < rn; i++) | |
| { | |
| add_item(SEEX - 1, SEEY - 1, (*itypes)[itm_laser_pack], 0); | |
| add_item(SEEX + 1, SEEY - 1, (*itypes)[itm_laser_pack], 0); | |
| } | |
| add_item(SEEX - 1, SEEY , (*itypes)[itm_v29], 0); | |
| add_item(SEEX + 1, SEEY , (*itypes)[itm_ftk93], 0); | |
| } | |
| else if (!one_in(3)) | |
| { | |
| rn = dice(3, 6); | |
| for (int i = 0; i < rn; i++) | |
| { | |
| add_item(SEEX - 1, SEEY - 1, (*itypes)[itm_mininuke], 0); | |
| add_item(SEEX , SEEY - 1, (*itypes)[itm_mininuke], 0); | |
| add_item(SEEX - 1, SEEY , (*itypes)[itm_mininuke], 0); | |
| add_item(SEEX , SEEY , (*itypes)[itm_mininuke], 0); | |
| } | |
| } | |
| else | |
| { | |
| ter(SEEX - 2, SEEY - 1) = t_rack; | |
| ter(SEEX - 1, SEEY - 1) = t_rack; | |
| ter(SEEX , SEEY - 1) = t_rack; | |
| ter(SEEX + 1, SEEY - 1) = t_rack; | |
| ter(SEEX - 2, SEEY) = t_rack; | |
| ter(SEEX - 1, SEEY) = t_rack; | |
| ter(SEEX , SEEY) = t_rack; | |
| ter(SEEX + 1, SEEY) = t_rack; | |
| place_items(mi_ammo, 96, SEEX - 2, SEEY - 1, SEEX + 1, SEEY - 1, false, 0); | |
| place_items(mi_allguns, 96, SEEX - 2, SEEY, SEEX + 1, SEEY, false, 0); | |
| } | |
| break; | |
| case 2: // Netherworld access | |
| { | |
| if (!one_in(4)) // Trapped netherworld monsters | |
| { | |
| tw = rng(SEEY + 3, SEEY + 5); | |
| bw = tw + 4; | |
| lw = rng(SEEX - 6, SEEX - 2); | |
| rw = lw + 6; | |
| for (int i = lw; i <= rw; i++) | |
| { | |
| for (int j = tw; j <= bw; j++) | |
| { | |
| if (j == tw || j == bw) | |
| { | |
| if ((i - lw) % 2 == 0) | |
| { | |
| ter(i, j) = t_concrete_h; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_reinforced_glass_h; | |
| } | |
| } | |
| else if ((i - lw) % 2 == 0) | |
| { | |
| ter(i, j) = t_concrete_v; | |
| } | |
| else if (j == tw + 2) | |
| { | |
| ter(i, j) = t_concrete_h; | |
| } | |
| else // Empty space holds monsters! | |
| { | |
| mon_id type = mon_id(rng(mon_flying_polyp, mon_gozu)); | |
| add_spawn(type, 1, i, j); | |
| } | |
| } | |
| } | |
| } | |
| tmpcomp = add_computer(SEEX, 8, "Sub-prime contact console", 7); | |
| tmpcomp->add_option("Terminate Specimens", COMPACT_TERMINATE, 2); | |
| tmpcomp->add_option("Release Specimens", COMPACT_RELEASE, 3); | |
| tmpcomp->add_option("Toggle Portal", COMPACT_PORTAL, 8); | |
| tmpcomp->add_option("Activate Resonance Cascade", COMPACT_CASCADE, 10); | |
| tmpcomp->add_failure(COMPFAIL_MANHACKS); | |
| tmpcomp->add_failure(COMPFAIL_SECUBOTS); | |
| ter(SEEX - 2, 4) = t_radio_tower; | |
| ter(SEEX + 1, 4) = t_radio_tower; | |
| ter(SEEX - 2, 7) = t_radio_tower; | |
| ter(SEEX + 1, 7) = t_radio_tower; | |
| } | |
| break; | |
| case 3: // Bionics | |
| add_spawn(mon_secubot, 1, 6, 6); | |
| add_spawn(mon_secubot, 1, SEEX * 2 - 7, 6); | |
| add_spawn(mon_secubot, 1, 6, SEEY * 2 - 7); | |
| add_spawn(mon_secubot, 1, SEEX * 2 - 7, SEEY * 2 - 7); | |
| add_trap(SEEX - 2, SEEY - 2, tr_dissector); | |
| add_trap(SEEX + 1, SEEY - 2, tr_dissector); | |
| add_trap(SEEX - 2, SEEY + 1, tr_dissector); | |
| add_trap(SEEX + 1, SEEY + 1, tr_dissector); | |
| square(this, t_counter, SEEX - 1, SEEY - 1, SEEX, SEEY); | |
| place_items(mi_bionics, 75, SEEX - 1, SEEY - 1, SEEX, SEEY, false, 0); | |
| line(this, t_reinforced_glass_h, SEEX - 2, SEEY - 2, SEEX + 1, SEEY - 2); | |
| line(this, t_reinforced_glass_h, SEEX - 2, SEEY + 1, SEEX + 1, SEEY + 1); | |
| line(this, t_reinforced_glass_v, SEEX - 2, SEEY - 1, SEEX - 2, SEEY); | |
| line(this, t_reinforced_glass_v, SEEX + 1, SEEY - 1, SEEX + 1, SEEY); | |
| ter(SEEX - 3, SEEY - 3) = t_console; | |
| tmpcomp = add_computer(SEEX - 3, SEEY - 3, "Bionic access", 3); | |
| tmpcomp->add_option("Manifest", COMPACT_LIST_BIONICS, 0); | |
| tmpcomp->add_option("Open Chambers", COMPACT_RELEASE, 5); | |
| tmpcomp->add_failure(COMPFAIL_MANHACKS); | |
| tmpcomp->add_failure(COMPFAIL_SECUBOTS); | |
| break; | |
| } | |
| break; | |
| case ot_bunker: | |
| if (t_above == ot_null) // We're on ground level | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| line(this, t_wall_metal_h, 7, 7, 16, 7); | |
| line(this, t_wall_metal_h, 8, 8, 15, 8); | |
| line(this, t_wall_metal_h, 8, 15, 15, 15); | |
| line(this, t_wall_metal_h, 7, 16, 10, 16); | |
| line(this, t_wall_metal_h, 14, 16, 16, 16); | |
| line(this, t_wall_metal_v, 7, 8, 7, 15); | |
| line(this, t_wall_metal_v, 16, 8, 16, 15); | |
| line(this, t_wall_metal_v, 8, 9, 8, 14); | |
| line(this, t_wall_metal_v, 15, 9, 15, 14); | |
| square(this, t_floor, 9, 10, 14, 14); | |
| line(this, t_stairs_down, 11, 9, 12, 9); | |
| line(this, t_door_metal_locked, 11, 15, 12, 15); | |
| for (int i = 9; i <= 13; i += 2) | |
| { | |
| line(this, t_wall_metal_h, 9, i, 10, i); | |
| line(this, t_wall_metal_h, 13, i, 14, i); | |
| add_spawn(mon_turret, 1, 9, i + 1); | |
| add_spawn(mon_turret, 1, 14, i + 1); | |
| } | |
| ter(13, 16) = t_card_military; | |
| } | |
| else // Below ground! | |
| { | |
| square(this, t_rock, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1); | |
| square(this, t_floor, 1, 1, SEEX * 2 - 2, SEEY * 2 - 2); | |
| line(this, t_wall_metal_h, 2, 8, 8, 8); | |
| line(this, t_wall_metal_h, 15, 8, 21, 8); | |
| line(this, t_wall_metal_h, 2, 15, 8, 15); | |
| line(this, t_wall_metal_h, 15, 15, 21, 15); | |
| for (int j = 2; j <= 16; j += 7) | |
| { | |
| ter(9, j) = t_card_military; | |
| ter(14, j) = t_card_military; | |
| ter(9, j + 1) = t_door_metal_locked; | |
| ter(14, j + 1) = t_door_metal_locked; | |
| line(this, t_reinforced_glass_v, 9, j + 2, 9, j + 4); | |
| line(this, t_reinforced_glass_v, 14, j + 2, 14, j + 4); | |
| line(this, t_wall_metal_v, 9, j + 5, 9, j + 6); | |
| line(this, t_wall_metal_v, 14, j + 5, 14, j + 6); | |
| // Fill rooms with items! | |
| for (int i = 2; i <= 15; i += 13) | |
| { | |
| items_location goods; | |
| int size; | |
| switch (rng(1, 14)) | |
| { | |
| case 1: | |
| case 2: | |
| goods = mi_bots; | |
| size = 85; | |
| break; | |
| case 3: | |
| case 4: | |
| goods = mi_launchers; | |
| size = 83; | |
| break; | |
| case 5: | |
| case 6: | |
| goods = mi_mil_rifles; | |
| size = 87; | |
| break; | |
| case 7: | |
| case 8: | |
| goods = mi_grenades; | |
| size = 88; | |
| break; | |
| case 9: | |
| case 10: | |
| goods = mi_mil_armor; | |
| size = 85; | |
| break; | |
| case 11: | |
| case 12: | |
| case 13: | |
| goods = mi_mil_food; | |
| size = 90; | |
| break; | |
| case 14: | |
| goods = mi_bionics_mil; | |
| size = 78; | |
| break; | |
| } | |
| place_items(goods, size, i, j, i + 6, j + 5, false, 0); | |
| } | |
| } | |
| line(this, t_wall_metal_h, 1, 1, SEEX * 2 - 2, 1); | |
| line(this, t_wall_metal_h, 1, SEEY * 2 - 2, SEEX * 2 - 2, SEEY * 2 - 2); | |
| line(this, t_wall_metal_v, 1, 2, 1, SEEY * 2 - 3); | |
| line(this, t_wall_metal_v, SEEX * 2 - 2, 2, SEEX * 2 - 2, SEEY * 2 - 3); | |
| ter(SEEX - 1, 21) = t_stairs_up; | |
| ter(SEEX, 21) = t_stairs_up; | |
| } | |
| break; | |
| case ot_outpost: | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| square(this, t_dirt, 3, 3, 20, 20); | |
| line(this, t_chainfence_h, 2, 2, 10, 2); | |
| line(this, t_chainfence_h, 13, 2, 21, 2); | |
| line(this, t_chaingate_l, 11, 2, 12, 2); | |
| line(this, t_chainfence_h, 2, 21, 10, 21); | |
| line(this, t_chainfence_h, 13, 21, 21, 21); | |
| line(this, t_chaingate_l, 11, 21, 12, 21); | |
| line(this, t_chainfence_v, 2, 3, 2, 10); | |
| line(this, t_chainfence_v, 21, 3, 21, 10); | |
| line(this, t_chaingate_l, 2, 11, 2, 12); | |
| line(this, t_chainfence_v, 2, 13, 2, 20); | |
| line(this, t_chainfence_v, 21, 13, 21, 20); | |
| line(this, t_chaingate_l, 21, 11, 21, 12); | |
| // Place some random buildings | |
| bool okay = true; | |
| while (okay) | |
| { | |
| int buildx = rng(6, 17), buildy = rng(6, 17); | |
| int buildwidthmax = (buildx <= 11 ? buildx - 3 : 20 - buildx), | |
| buildheightmax = (buildy <= 11 ? buildy - 3 : 20 - buildy); | |
| int buildwidth = rng(3, buildwidthmax), buildheight = rng(3, buildheightmax); | |
| if (ter(buildx, buildy) != t_dirt) | |
| { | |
| okay = false; | |
| } | |
| else | |
| { | |
| int bx1 = buildx - buildwidth, bx2 = buildx + buildwidth, | |
| by1 = buildy - buildheight, by2 = buildy + buildheight; | |
| square(this, t_floor, bx1, by1, bx2, by2); | |
| line(this, t_concrete_h, bx1, by1, bx2, by1); | |
| line(this, t_concrete_h, bx1, by2, bx2, by2); | |
| line(this, t_concrete_v, bx1, by1, bx1, by2); | |
| line(this, t_concrete_v, bx2, by1, bx2, by2); | |
| switch (rng(1, 3)) // What type of building? | |
| { | |
| case 1: // Barracks | |
| for (int i = by1 + 1; i <= by2 - 1; i += 2) | |
| { | |
| line(this, t_bed, bx1 + 1, i, bx1 + 2, i); | |
| line(this, t_bed, bx2 - 2, i, bx2 - 1, i); | |
| } | |
| place_items(mi_bedroom, 84, bx1 + 1, by1 + 1, bx2 - 1, by2 - 1, false, 0); | |
| break; | |
| case 2: // Armory | |
| line(this, t_counter, bx1 + 1, by1 + 1, bx2 - 1, by1 + 1); | |
| line(this, t_counter, bx1 + 1, by2 - 1, bx2 - 1, by2 - 1); | |
| line(this, t_counter, bx1 + 1, by1 + 2, bx1 + 1, by2 - 2); | |
| line(this, t_counter, bx2 - 1, by1 + 2, bx2 - 1, by2 - 2); | |
| place_items(mi_mil_rifles, 40, bx1 + 1, by1 + 1, bx2 - 1, by1 + 1, false, 0); | |
| place_items(mi_launchers, 40, bx1 + 1, by2 - 1, bx2 - 1, by2 - 1, false, 0); | |
| place_items(mi_grenades, 40, bx1 + 1, by1 + 2, bx1 + 1, by2 - 2, false, 0); | |
| place_items(mi_mil_armor, 40, bx2 - 1, by1 + 2, bx2 - 1, by2 - 2, false, 0); | |
| break; | |
| case 3: // Supplies | |
| for (int i = by1 + 1; i <= by2 - 1; i += 3) | |
| { | |
| line(this, t_rack, bx1 + 2, i, bx2 - 2, i); | |
| place_items(mi_mil_food, 78, bx1 + 2, i, bx2 - 2, i, false, 0); | |
| } | |
| break; | |
| } | |
| std::vector<direction> doorsides; | |
| if (bx1 > 3) | |
| { | |
| doorsides.push_back(WEST); | |
| } | |
| if (bx2 < 20) | |
| { | |
| doorsides.push_back(EAST); | |
| } | |
| if (by1 > 3) | |
| { | |
| doorsides.push_back(NORTH); | |
| } | |
| if (by2 < 20) | |
| { | |
| doorsides.push_back(SOUTH); | |
| } | |
| int doorx, doory; | |
| switch (doorsides[rng(0, doorsides.size() - 1)]) | |
| { | |
| case WEST: | |
| doorx = bx1; | |
| doory = rng(by1 + 1, by2 - 1); | |
| break; | |
| case EAST: | |
| doorx = bx2; | |
| doory = rng(by1 + 1, by2 - 1); | |
| break; | |
| case NORTH: | |
| doorx = rng(bx1 + 1, bx2 - 1); | |
| doory = by1; | |
| break; | |
| case SOUTH: | |
| doorx = rng(bx1 + 1, bx2 - 1); | |
| doory = by2; | |
| break; | |
| } | |
| for (int i = doorx - 1; i <= doorx + 1; i++) | |
| { | |
| for (int j = doory - 1; j <= doory + 1; j++) | |
| { | |
| i_clear(i, j); | |
| if (ter(i, j) == t_bed || ter(i, j) == t_rack || ter(i, j) == t_counter) | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| } | |
| } | |
| ter(doorx, doory) = t_door_c; | |
| } | |
| } | |
| // Seal up the entrances if there's walls there | |
| if (ter(11, 3) != t_dirt) | |
| { | |
| ter(11, 2) = t_concrete_h; | |
| } | |
| if (ter(12, 3) != t_dirt) | |
| { | |
| ter(12, 2) = t_concrete_h; | |
| } | |
| if (ter(11, 20) != t_dirt) | |
| { | |
| ter(11, 2) = t_concrete_h; | |
| } | |
| if (ter(12, 20) != t_dirt) | |
| { | |
| ter(12, 2) = t_concrete_h; | |
| } | |
| if (ter(3, 11) != t_dirt) | |
| { | |
| ter(2, 11) = t_concrete_v; | |
| } | |
| if (ter(3, 12) != t_dirt) | |
| { | |
| ter(2, 12) = t_concrete_v; | |
| } | |
| if (ter(3, 11) != t_dirt) | |
| { | |
| ter(2, 11) = t_concrete_v; | |
| } | |
| if (ter(3, 12) != t_dirt) | |
| { | |
| ter(2, 12) = t_concrete_v; | |
| } | |
| // Place turrets by (possible) entrances | |
| add_spawn(mon_turret, 1, 3, 11); | |
| add_spawn(mon_turret, 1, 3, 12); | |
| add_spawn(mon_turret, 1, 20, 11); | |
| add_spawn(mon_turret, 1, 20, 12); | |
| add_spawn(mon_turret, 1, 11, 3); | |
| add_spawn(mon_turret, 1, 12, 3); | |
| add_spawn(mon_turret, 1, 11, 20); | |
| add_spawn(mon_turret, 1, 12, 20); | |
| // Finally, scatter dead bodies / mil zombies | |
| for (int i = 0; i < 20; i++) | |
| { | |
| int rnx = rng(3, 20), rny = rng(3, 20); | |
| if (move_cost(rnx, rny) != 0) | |
| { | |
| if (one_in(5)) // Military zombie | |
| { | |
| add_spawn(mon_zombie_soldier, 1, rnx, rny); | |
| } | |
| else if (one_in(2)) | |
| { | |
| item body; | |
| body.make_corpse(g->itypes[itm_corpse], g->mtypes[mon_null], 0); | |
| add_item(rnx, rny, body); | |
| place_items(mi_launchers, 10, rnx, rny, rnx, rny, true, 0); | |
| place_items(mi_mil_rifles, 30, rnx, rny, rnx, rny, true, 0); | |
| place_items(mi_mil_armor, 70, rnx, rny, rnx, rny, true, 0); | |
| place_items(mi_mil_food, 40, rnx, rny, rnx, rny, true, 0); | |
| add_item(rnx, rny, (*itypes)[itm_id_military], 0); | |
| } | |
| else if (one_in(20)) | |
| { | |
| rough_circle(this, t_rubble, rnx, rny, rng(3, 6)); | |
| } | |
| } | |
| } | |
| // Oh wait--let's also put radiation in any rubble | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| radiation(i, j) += (one_in(5) ? rng(1, 2) : 0); | |
| if (ter(i, j) == t_rubble) | |
| { | |
| radiation(i, j) += rng(1, 3); | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| case ot_silo: | |
| if (t_above == ot_null) // We're on ground level | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (trig_dist(i, j, SEEX, SEEY) <= 6) | |
| { | |
| ter(i, j) = t_metal_floor; | |
| } | |
| else | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| } | |
| switch (rng(1, 4)) // Placement of stairs | |
| { | |
| case 1: | |
| lw = 3; | |
| mw = 5; | |
| tw = 3; | |
| break; | |
| case 2: | |
| lw = 3; | |
| mw = 5; | |
| tw = SEEY * 2 - 4; | |
| break; | |
| case 3: | |
| lw = SEEX * 2 - 7; | |
| mw = lw; | |
| tw = 3; | |
| break; | |
| case 4: | |
| lw = SEEX * 2 - 7; | |
| mw = lw; | |
| tw = SEEY * 2 - 4; | |
| break; | |
| } | |
| for (int i = lw; i <= lw + 2; i++) | |
| { | |
| ter(i, tw) = t_wall_metal_h; | |
| ter(i, tw + 2) = t_wall_metal_h; | |
| } | |
| ter(lw , tw + 1) = t_wall_metal_v; | |
| ter(lw + 1, tw + 1) = t_stairs_down; | |
| ter(lw + 2, tw + 1) = t_wall_metal_v; | |
| ter(mw , tw + 1) = t_door_metal_locked; | |
| ter(mw , tw + 2) = t_card_military; | |
| } | |
| else // We are NOT above ground. | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (trig_dist(i, j, SEEX, SEEY) > 7) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| else if (trig_dist(i, j, SEEX, SEEY) > 5) | |
| { | |
| ter(i, j) = t_metal_floor; | |
| if (one_in(30)) | |
| { | |
| add_field(NULL, i, j, fd_nuke_gas, 2); // NULL game; no messages | |
| } | |
| } | |
| else if (trig_dist(i, j, SEEX, SEEY) == 5) | |
| { | |
| ter(i, j) = t_hole; | |
| add_trap(i, j, tr_ledge); | |
| } | |
| else | |
| { | |
| ter(i, j) = t_missile; | |
| } | |
| } | |
| } | |
| silo_rooms(this); | |
| } | |
| break; | |
| case ot_silo_finale: | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i == 5) | |
| { | |
| if (j > 4 && j < SEEY) | |
| { | |
| ter(i, j) = t_reinforced_glass_v; | |
| } | |
| else if (j == SEEY * 2 - 4) | |
| { | |
| ter(i, j) = t_door_metal_c; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| ter(0, 0) = t_stairs_up; | |
| tmpcomp = add_computer(4, 5, "Missile Controls", 8); | |
| tmpcomp->add_option("Launch Missile", COMPACT_MISS_LAUNCH, 10); | |
| tmpcomp->add_option("Disarm Missile", COMPACT_MISS_DISARM, 8); | |
| tmpcomp->add_failure(COMPFAIL_SECUBOTS); | |
| tmpcomp->add_failure(COMPFAIL_DAMAGE); | |
| } | |
| break; | |
| case ot_temple: | |
| case ot_temple_stairs: | |
| if (t_above == ot_null) // Ground floor | |
| { | |
| // TODO: More varieties? | |
| square(this, t_dirt, 0, 0, 23, 23); | |
| square(this, t_grate, SEEX - 1, SEEY - 1, SEEX, SEEX); | |
| ter(SEEX + 1, SEEY + 1) = t_pedestal_temple; | |
| } | |
| else // Underground! Shit's about to get interesting! | |
| { | |
| // Start with all rock floor | |
| square(this, t_rock_floor, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1); | |
| // We always start at the south and go north. | |
| // We use (g->levx / 2 + g->levz) % 5 to guarantee that rooms don't repeat. | |
| switch (1 + int(g->levy / 2 + g->levz) % 4) // TODO: More varieties! | |
| { | |
| case 1: // Flame bursts | |
| square(this, t_rock, 0, 0, SEEX - 1, SEEY * 2 - 1); | |
| square(this, t_rock, SEEX + 2, 0, SEEX * 2 - 1, SEEY * 2 - 1); | |
| for (int i = 2; i < SEEY * 2 - 4; i++) | |
| { | |
| add_field(g, SEEX , i, fd_fire_vent, rng(1, 3)); | |
| add_field(g, SEEX + 1, i, fd_fire_vent, rng(1, 3)); | |
| } | |
| break; | |
| case 2: // Spreading water | |
| square(this, t_water_dp, 4, 4, 5, 5); | |
| add_spawn(mon_sewer_snake, 1, 4, 4); | |
| square(this, t_water_dp, SEEX * 2 - 5, 4, SEEX * 2 - 4, 6); | |
| add_spawn(mon_sewer_snake, 1, SEEX * 2 - 5, 4); | |
| square(this, t_water_dp, 4, SEEY * 2 - 5, 6, SEEY * 2 - 4); | |
| square(this, t_water_dp, SEEX * 2 - 5, SEEY * 2 - 5, SEEX * 2 - 4, | |
| SEEY * 2 - 4); | |
| square(this, t_rock, 0, SEEY * 2 - 2, SEEX - 1, SEEY * 2 - 1); | |
| square(this, t_rock, SEEX + 2, SEEY * 2 - 2, SEEX * 2 - 1, SEEY * 2 - 1); | |
| line(this, t_grate, SEEX, 1, SEEX + 1, 1); // To drain the water | |
| add_trap(SEEX, SEEY * 2 - 2, tr_temple_flood); | |
| add_trap(SEEX + 1, SEEY * 2 - 2, tr_temple_flood); | |
| for (int y = 2; y < SEEY * 2 - 2; y++) | |
| { | |
| for (int x = 2; x < SEEX * 2 - 2; x++) | |
| { | |
| if (ter(x, y) == t_rock_floor && one_in(4)) | |
| { | |
| add_trap(x, y, tr_temple_flood); | |
| } | |
| } | |
| } | |
| break; | |
| case 3: // Flipping walls puzzle | |
| { | |
| line(this, t_rock, 0, 0, SEEX - 1, 0); | |
| line(this, t_rock, SEEX + 2, 0, SEEX * 2 - 1, 0); | |
| line(this, t_rock, SEEX - 1, 1, SEEX - 1, 6); | |
| line(this, t_bars, SEEX + 2, 1, SEEX + 2, 6); | |
| ter(14, 1) = t_switch_rg; | |
| ter(15, 1) = t_switch_gb; | |
| ter(16, 1) = t_switch_rb; | |
| ter(17, 1) = t_switch_even; | |
| // Start with clear floors--then work backwards to the starting state | |
| line(this, t_floor_red, SEEX, 1, SEEX + 1, 1); | |
| line(this, t_floor_green, SEEX, 2, SEEX + 1, 2); | |
| line(this, t_floor_blue, SEEX, 3, SEEX + 1, 3); | |
| line(this, t_floor_red, SEEX, 4, SEEX + 1, 4); | |
| line(this, t_floor_green, SEEX, 5, SEEX + 1, 5); | |
| line(this, t_floor_blue, SEEX, 6, SEEX + 1, 6); | |
| // Now, randomly choose actions | |
| // Set up an actions vector so that there's not undue repetion | |
| std::vector<int> actions; | |
| actions.push_back(1); | |
| actions.push_back(2); | |
| actions.push_back(3); | |
| actions.push_back(4); | |
| actions.push_back(rng(1, 3)); | |
| while (!actions.empty()) | |
| { | |
| int index = rng(0, actions.size() - 1); | |
| int action = actions[index]; | |
| actions.erase(actions.begin() + index); | |
| for (int y = 1; y < 7; y++) | |
| { | |
| for (int x = SEEX; x <= SEEX + 1; x++) | |
| { | |
| switch (action) | |
| { | |
| case 1: // Toggle RG | |
| if (ter(x, y) == t_floor_red) | |
| { | |
| ter(x, y) = t_rock_red; | |
| } | |
| else if (ter(x, y) == t_rock_red) | |
| { | |
| ter(x, y) = t_floor_red; | |
| } | |
| else if (ter(x, y) == t_floor_green) | |
| { | |
| ter(x, y) = t_rock_green; | |
| } | |
| else if (ter(x, y) == t_rock_green) | |
| { | |
| ter(x, y) = t_floor_green; | |
| } | |
| break; | |
| case 2: // Toggle GB | |
| if (ter(x, y) == t_floor_blue) | |
| { | |
| ter(x, y) = t_rock_blue; | |
| } | |
| else if (ter(x, y) == t_rock_blue) | |
| { | |
| ter(x, y) = t_floor_blue; | |
| } | |
| else if (ter(x, y) == t_floor_green) | |
| { | |
| ter(x, y) = t_rock_green; | |
| } | |
| else if (ter(x, y) == t_rock_green) | |
| { | |
| ter(x, y) = t_floor_green; | |
| } | |
| break; | |
| case 3: // Toggle RB | |
| if (ter(x, y) == t_floor_blue) | |
| { | |
| ter(x, y) = t_rock_blue; | |
| } | |
| else if (ter(x, y) == t_rock_blue) | |
| { | |
| ter(x, y) = t_floor_blue; | |
| } | |
| else if (ter(x, y) == t_floor_red) | |
| { | |
| ter(x, y) = t_rock_red; | |
| } | |
| else if (ter(x, y) == t_rock_red) | |
| { | |
| ter(x, y) = t_floor_red; | |
| } | |
| break; | |
| case 4: // Toggle Even | |
| if (y % 2 == 0) | |
| { | |
| if (ter(x, y) == t_floor_blue) | |
| { | |
| ter(x, y) = t_rock_blue; | |
| } | |
| else if (ter(x, y) == t_rock_blue) | |
| { | |
| ter(x, y) = t_floor_blue; | |
| } | |
| else if (ter(x, y) == t_floor_red) | |
| { | |
| ter(x, y) = t_rock_red; | |
| } | |
| else if (ter(x, y) == t_rock_red) | |
| { | |
| ter(x, y) = t_floor_red; | |
| } | |
| else if (ter(x, y) == t_floor_green) | |
| { | |
| ter(x, y) = t_rock_green; | |
| } | |
| else if (ter(x, y) == t_rock_green) | |
| { | |
| ter(x, y) = t_floor_green; | |
| } | |
| } | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| case 4: // Toggling walls maze | |
| { | |
| square(this, t_rock, 0, 0, SEEX - 1, 1); | |
| square(this, t_rock, 0, SEEY * 2 - 2, SEEX - 1, SEEY * 2 - 1); | |
| square(this, t_rock, 0, 2, SEEX - 4, SEEY * 2 - 3); | |
| square(this, t_rock, SEEX + 2, 0, SEEX * 2 - 1, 1); | |
| square(this, t_rock, SEEX + 2, SEEY * 2 - 2, SEEX * 2 - 1, SEEY * 2 - 1); | |
| square(this, t_rock, SEEX + 5, 2, SEEX * 2 - 1, SEEY * 2 - 3); | |
| int x = rng(SEEX - 1, SEEX + 2), y = 2; | |
| std::vector<point> path; // Path, from end to start | |
| while (x < SEEX - 1 || x > SEEX + 2 || y < SEEY * 2 - 2) | |
| { | |
| path.push_back(point(x, y)); | |
| ter(x, y) = ter_id(rng(t_floor_red, t_floor_blue)); | |
| if (y == SEEY * 2 - 2) | |
| { | |
| if (x < SEEX - 1) | |
| { | |
| x++; | |
| } | |
| else if (x > SEEX + 2) | |
| { | |
| x--; | |
| } | |
| } | |
| else | |
| { | |
| std::vector<point> next; | |
| for (int nx = x - 1; nx <= x + 1; nx++) | |
| { | |
| for (int ny = y; ny <= y + 1; ny++) | |
| { | |
| if (ter(nx, ny) == t_rock_floor) | |
| { | |
| next.push_back(point(nx, ny)); | |
| } | |
| } | |
| } | |
| int index = rng(0, next.size() - 1); | |
| x = next[index].x; | |
| y = next[index].y; | |
| } | |
| } | |
| // Now go backwards through path (start to finish), toggling any tiles that need | |
| bool toggle_red = false, toggle_green = false, toggle_blue = false; | |
| for (int i = path.size() - 1; i >= 0; i--) | |
| { | |
| if (ter(path[i].x, path[i].y) == t_floor_red) | |
| { | |
| toggle_green = !toggle_green; | |
| if (toggle_red) | |
| { | |
| ter(path[i].x, path[i].y) = t_rock_red; | |
| } | |
| } | |
| else if (ter(path[i].x, path[i].y) == t_floor_green) | |
| { | |
| toggle_blue = !toggle_blue; | |
| if (toggle_green) | |
| { | |
| ter(path[i].x, path[i].y) = t_rock_green; | |
| } | |
| } | |
| else if (ter(path[i].x, path[i].y) == t_floor_blue) | |
| { | |
| toggle_red = !toggle_red; | |
| if (toggle_blue) | |
| { | |
| ter(path[i].x, path[i].y) = t_rock_blue; | |
| } | |
| } | |
| } | |
| // Finally, fill in the rest with random tiles, and place toggle traps | |
| for (int i = SEEX - 3; i <= SEEX + 4; i++) | |
| { | |
| for (int j = 2; j <= SEEY * 2 - 2; j++) | |
| { | |
| add_trap(i, j, tr_temple_toggle); | |
| if (ter(i, j) == t_rock_floor) | |
| { | |
| ter(i, j) = ter_id(rng(t_rock_red, t_floor_blue)); | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| } // Done with room type switch | |
| // Stairs down if we need them | |
| if (terrain_type == ot_temple_stairs) | |
| { | |
| line(this, t_stairs_down, SEEX, 0, SEEX + 1, 0); | |
| } | |
| // Stairs at the south if t_above has stairs down. | |
| if (t_above == ot_temple_stairs) | |
| { | |
| line(this, t_stairs_up, SEEX, SEEY * 2 - 1, SEEX + 1, SEEY * 2 - 1); | |
| } | |
| } // Done with underground-only stuff | |
| break; | |
| case ot_temple_finale: | |
| square(this, t_rock, 0, 0, SEEX * 2 - 1, SEEX * 2 - 1); | |
| square(this, t_rock_floor, SEEX - 1, 1, SEEX + 2, 4); | |
| square(this, t_rock_floor, SEEX, 5, SEEX + 1, SEEY * 2 - 1); | |
| line(this, t_stairs_up, SEEX, SEEY * 2 - 1, SEEX + 1, SEEY * 2 - 1); | |
| add_item(rng(SEEX, SEEX + 1), rng(2, 3), g->new_artifact(), 0); | |
| add_item(rng(SEEX, SEEX + 1), rng(2, 3), g->new_artifact(), 0); | |
| return; | |
| case ot_sewage_treatment: | |
| square(this, t_floor, 0, 0, 23, 23); // Set all to floor | |
| line(this, t_wall_h, 0, 0, 23, 0); // Top wall | |
| line(this, t_window, 1, 0, 6, 0); // Its windows | |
| line(this, t_wall_h, 0, 23, 23, 23); // Bottom wall | |
| line(this, t_wall_h, 1, 5, 6, 5); // Interior wall (front office) | |
| line(this, t_wall_h, 1, 14, 6, 14); // Interior wall (equipment) | |
| line(this, t_wall_h, 1, 20, 7, 20); // Interior wall (stairs) | |
| line(this, t_wall_h, 14, 15, 22, 15); // Interior wall (tank) | |
| line(this, t_wall_v, 0, 1, 0, 22); // Left wall | |
| line(this, t_wall_v, 23, 1, 23, 22); // Right wall | |
| line(this, t_wall_v, 7, 1, 7, 5); // Interior wall (front office) | |
| line(this, t_wall_v, 7, 14, 7, 19); // Interior wall (stairs) | |
| line(this, t_wall_v, 4, 15, 4, 19); // Interior wall (mid-stairs) | |
| line(this, t_wall_v, 14, 15, 14, 20); // Interior wall (tank) | |
| line(this, t_wall_glass_v, 7, 6, 7, 13); // Interior glass (equipment) | |
| line(this, t_wall_glass_h, 8, 20, 13, 20); // Interior glass (flow) | |
| line(this, t_counter, 1, 3, 3, 3); // Desk (front office); | |
| line(this, t_counter, 1, 6, 1, 13); // Counter (equipment); | |
| // Central tanks: | |
| square(this, t_sewage, 10, 3, 13, 6); | |
| square(this, t_sewage, 17, 3, 20, 6); | |
| square(this, t_sewage, 10, 10, 13, 13); | |
| square(this, t_sewage, 17, 10, 20, 13); | |
| // Drainage tank | |
| square(this, t_sewage, 16, 16, 21, 18); | |
| square(this, t_grate, 18, 16, 19, 17); | |
| line(this, t_sewage, 17, 19, 20, 19); | |
| line(this, t_sewage, 18, 20, 19, 20); | |
| line(this, t_sewage, 2, 21, 19, 21); | |
| line(this, t_sewage, 2, 22, 19, 22); | |
| // Pipes and pumps | |
| line(this, t_sewage_pipe, 1, 15, 1, 19); | |
| line(this, t_sewage_pump, 1, 21, 1, 22); | |
| // Stairs down | |
| ter(2, 15) = t_stairs_down; | |
| // Now place doors | |
| ter(rng(2, 5), 0) = t_door_c; | |
| ter(rng(3, 5), 5) = t_door_c; | |
| ter(5, 14) = t_door_c; | |
| ter(7, rng(15, 17)) = t_door_c; | |
| ter(14, rng(17, 19)) = t_door_c; | |
| if (one_in(3)) // back door | |
| { | |
| ter(23, rng(19, 22)) = t_door_locked; | |
| } | |
| ter(4, 19) = t_door_metal_locked; | |
| ter(2, 19) = t_console; | |
| ter(6, 19) = t_console; | |
| // Computers to unlock stair room, and items | |
| tmpcomp = add_computer(2, 19, "EnviroCom OS v2.03", 1); | |
| tmpcomp->add_option("Unlock stairs", COMPACT_OPEN, 0); | |
| tmpcomp->add_failure(COMPFAIL_SHUTDOWN); | |
| tmpcomp = add_computer(6, 19, "EnviroCom OS v2.03", 1); | |
| tmpcomp->add_option("Unlock stairs", COMPACT_OPEN, 0); | |
| tmpcomp->add_failure(COMPFAIL_SHUTDOWN); | |
| place_items(mi_sewage_plant, 80, 1, 6, 1, 13, false, 0); | |
| break; | |
| case ot_sewage_treatment_hub: // Stairs up, center of 3x3 of treatment_below | |
| square(this, t_rock_floor, 0, 0, 23, 23); | |
| // Top & left walls; right & bottom are handled by adjacent terrain | |
| line(this, t_wall_h, 0, 0, 23, 0); | |
| line(this, t_wall_v, 0, 1, 0, 23); | |
| // Top-left room | |
| line(this, t_wall_v, 8, 1, 8, 8); | |
| line(this, t_wall_h, 1, 9, 9, 9); | |
| line(this, t_wall_glass_h, rng(1, 3), 9, rng(4, 7), 9); | |
| ter(2, 15) = t_stairs_up; | |
| ter(8, 8) = t_door_c; | |
| ter(3, 0) = t_door_c; | |
| // Bottom-left room - stairs and equipment | |
| line(this, t_wall_h, 1, 14, 8, 14); | |
| line(this, t_wall_glass_h, rng(1, 3), 14, rng(5, 8), 14); | |
| line(this, t_wall_v, 9, 14, 9, 23); | |
| line(this, t_wall_glass_v, 9, 16, 9, 19); | |
| square(this, t_counter, 5, 16, 6, 20); | |
| place_items(mi_sewage_plant, 80, 5, 16, 6, 20, false, 0); | |
| ter(0, 20) = t_door_c; | |
| ter(9, 20) = t_door_c; | |
| // Bottom-right room | |
| line(this, t_wall_v, 14, 19, 14, 23); | |
| line(this, t_wall_h, 14, 18, 19, 18); | |
| line(this, t_wall_h, 21, 14, 23, 14); | |
| ter(14, 18) = t_wall_h; | |
| ter(14, 20) = t_door_c; | |
| ter(15, 18) = t_door_c; | |
| line(this, t_wall_v, 20, 15, 20, 18); | |
| // Tanks and their content | |
| for (int i = 9; i <= 16; i += 7) | |
| { | |
| for (int j = 2; j <= 9; j += 7) | |
| { | |
| square(this, t_rock, i, j, i + 5, j + 5); | |
| square(this, t_sewage, i + 1, j + 1, i + 4, j + 4); | |
| } | |
| } | |
| square(this, t_rock, 16, 15, 19, 17); // Wall around sewage from above | |
| square(this, t_rock, 10, 15, 14, 17); // Extra walls for southward flow | |
| // Flow in from north, east, and west always connects to the corresponding tank | |
| square(this, t_sewage, 10, 0, 13, 2); // North -> NE tank | |
| square(this, t_sewage, 21, 10, 23, 13); // East -> SE tank | |
| square(this, t_sewage, 0, 10, 9, 13); // West -> SW tank | |
| // Flow from south may go to SW tank or SE tank | |
| square(this, t_sewage, 10, 16, 13, 23); | |
| if (one_in(2)) // To SW tank | |
| { | |
| square(this, t_sewage, 10, 14, 13, 17); | |
| // Then, flow from above may be either to flow from south, to SE tank, or both | |
| switch (rng(1, 5)) | |
| { | |
| case 1: | |
| case 2: // To flow from south | |
| square(this, t_sewage, 14, 16, 19, 17); | |
| line(this, t_bridge, 15, 16, 15, 17); | |
| if (!one_in(4)) | |
| { | |
| line(this, t_wall_glass_h, 16, 18, 19, 18); // Viewing window | |
| } | |
| break; | |
| case 3: | |
| case 4: // To SE tank | |
| square(this, t_sewage, 18, 14, 19, 17); | |
| if (!one_in(4)) | |
| { | |
| line(this, t_wall_glass_v, 20, 15, 20, 17); // Viewing window | |
| } | |
| break; | |
| case 5: // Both! | |
| square(this, t_sewage, 14, 16, 19, 17); | |
| square(this, t_sewage, 18, 14, 19, 17); | |
| line(this, t_bridge, 15, 16, 15, 17); | |
| if (!one_in(4)) | |
| { | |
| line(this, t_wall_glass_h, 16, 18, 19, 18); // Viewing window | |
| } | |
| if (!one_in(4)) | |
| { | |
| line(this, t_wall_glass_v, 20, 15, 20, 17); // Viewing window | |
| } | |
| break; | |
| } | |
| } | |
| else // To SE tank, via flow from above | |
| { | |
| square(this, t_sewage, 14, 16, 19, 17); | |
| square(this, t_sewage, 18, 14, 19, 17); | |
| line(this, t_bridge, 15, 16, 15, 17); | |
| if (!one_in(4)) | |
| { | |
| line(this, t_wall_glass_h, 16, 18, 19, 18); // Viewing window | |
| } | |
| if (!one_in(4)) | |
| { | |
| line(this, t_wall_glass_v, 20, 15, 20, 17); // Viewing window | |
| } | |
| } | |
| // Next, determine how the tanks interconnect. | |
| rn = rng(1, 4); // Which of the 4 possible connections is missing? | |
| if (rn != 1) | |
| { | |
| line(this, t_sewage, 14, 4, 14, 5); | |
| line(this, t_bridge, 15, 4, 15, 5); | |
| line(this, t_sewage, 16, 4, 16, 5); | |
| } | |
| if (rn != 2) | |
| { | |
| line(this, t_sewage, 18, 7, 19, 7); | |
| line(this, t_bridge, 18, 8, 19, 8); | |
| line(this, t_sewage, 18, 9, 19, 9); | |
| } | |
| if (rn != 3) | |
| { | |
| line(this, t_sewage, 14, 11, 14, 12); | |
| line(this, t_bridge, 15, 11, 15, 12); | |
| line(this, t_sewage, 16, 11, 16, 12); | |
| } | |
| if (rn != 4) | |
| { | |
| line(this, t_sewage, 11, 7, 12, 7); | |
| line(this, t_bridge, 11, 8, 12, 8); | |
| line(this, t_sewage, 11, 9, 12, 9); | |
| } | |
| // Bridge connecting bottom two rooms | |
| line(this, t_bridge, 10, 20, 13, 20); | |
| // Possibility of extra equipment shelves | |
| if (!one_in(3)) | |
| { | |
| line(this, t_rack, 23, 1, 23, 4); | |
| place_items(mi_sewage_plant, 60, 23, 1, 23, 4, false, 0); | |
| } | |
| // Finally, choose what the top-left and bottom-right rooms do. | |
| if (one_in(2)) // Upper left is sampling, lower right valuable finds | |
| { | |
| // Upper left... | |
| line(this, t_wall_h, 1, 3, 2, 3); | |
| line(this, t_wall_h, 1, 5, 2, 5); | |
| line(this, t_wall_h, 1, 7, 2, 7); | |
| ter(1, 4) = t_sewage_pump; | |
| ter(2, 4) = t_counter; | |
| ter(1, 6) = t_sewage_pump; | |
| ter(2, 6) = t_counter; | |
| ter(1, 2) = t_console; | |
| tmpcomp = add_computer(1, 2, "EnviroCom OS v2.03", 0); | |
| tmpcomp->add_option("Download Sewer Maps", COMPACT_MAP_SEWER, 0); | |
| tmpcomp->add_option("Divert sample", COMPACT_SAMPLE, 3); | |
| tmpcomp->add_failure(COMPFAIL_PUMP_EXPLODE); | |
| tmpcomp->add_failure(COMPFAIL_PUMP_LEAK); | |
| // Lower right... | |
| line(this, t_counter, 15, 23, 22, 23); | |
| place_items(mi_sewer, 65, 15, 23, 22, 23, false, 0); | |
| line(this, t_counter, 23, 15, 23, 19); | |
| place_items(mi_sewer, 65, 23, 15, 23, 19, false, 0); | |
| } | |
| else // Upper left is valuable finds, lower right is sampling | |
| { | |
| // Upper left... | |
| line(this, t_counter, 1, 1, 1, 7); | |
| place_items(mi_sewer, 65, 1, 1, 1, 7, false, 0); | |
| line(this, t_counter, 7, 1, 7, 7); | |
| place_items(mi_sewer, 65, 7, 1, 7, 7, false, 0); | |
| // Lower right... | |
| line(this, t_wall_v, 17, 22, 17, 23); | |
| line(this, t_wall_v, 19, 22, 19, 23); | |
| line(this, t_wall_v, 21, 22, 21, 23); | |
| ter(18, 23) = t_sewage_pump; | |
| ter(18, 22) = t_counter; | |
| ter(20, 23) = t_sewage_pump; | |
| ter(20, 22) = t_counter; | |
| ter(16, 23) = t_console; | |
| tmpcomp = add_computer(16, 23, "EnviroCom OS v2.03", 0); | |
| tmpcomp->add_option("Download Sewer Maps", COMPACT_MAP_SEWER, 0); | |
| tmpcomp->add_option("Divert sample", COMPACT_SAMPLE, 3); | |
| tmpcomp->add_failure(COMPFAIL_PUMP_EXPLODE); | |
| tmpcomp->add_failure(COMPFAIL_PUMP_LEAK); | |
| } | |
| break; | |
| case ot_sewage_treatment_under: | |
| square(this, t_floor, 0, 0, 23, 23); | |
| if (t_north == ot_sewage_treatment_under || t_north == ot_sewage_treatment_hub || | |
| (t_north >= ot_sewer_ns && t_north <= ot_sewer_nesw && | |
| connects_to(t_north, 2))) | |
| { | |
| if (t_north == ot_sewage_treatment_under || | |
| t_north == ot_sewage_treatment_hub) | |
| { | |
| line(this, t_wall_h, 0, 0, 23, 0); | |
| ter(3, 0) = t_door_c; | |
| } | |
| n_fac = 1; | |
| square(this, t_sewage, 10, 0, 13, 13); | |
| } | |
| if (t_east == ot_sewage_treatment_under || | |
| t_east == ot_sewage_treatment_hub || | |
| (t_east >= ot_sewer_ns && t_east <= ot_sewer_nesw && | |
| connects_to(t_east, 3))) | |
| { | |
| e_fac = 1; | |
| square(this, t_sewage, 10, 10, 23, 13); | |
| } | |
| if (t_south == ot_sewage_treatment_under || | |
| t_south == ot_sewage_treatment_hub || | |
| (t_south >= ot_sewer_ns && t_south <= ot_sewer_nesw && | |
| connects_to(t_south, 0))) | |
| { | |
| s_fac = 1; | |
| square(this, t_sewage, 10, 10, 13, 23); | |
| } | |
| if (t_west == ot_sewage_treatment_under || | |
| t_west == ot_sewage_treatment_hub || | |
| (t_west >= ot_sewer_ns && t_west <= ot_sewer_nesw && | |
| connects_to(t_west, 1))) | |
| { | |
| if (t_west == ot_sewage_treatment_under || | |
| t_west == ot_sewage_treatment_hub) | |
| { | |
| line(this, t_wall_v, 0, 1, 0, 23); | |
| ter(0, 20) = t_door_c; | |
| } | |
| w_fac = 1; | |
| square(this, t_sewage, 0, 10, 13, 13); | |
| } | |
| break; | |
| case ot_mine_entrance: | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| int tries = 0; | |
| bool build_shaft = true; | |
| do | |
| { | |
| int x1 = rng(1, SEEX * 2 - 10), y1 = rng(1, SEEY * 2 - 10); | |
| int x2 = x1 + rng(4, 9), y2 = y1 + rng(4, 9); | |
| if (build_shaft) | |
| { | |
| build_mine_room(this, room_mine_shaft, x1, y1, x2, y2); | |
| build_shaft = false; | |
| } | |
| else | |
| { | |
| bool okay = true; | |
| for (int x = x1; x <= x2 && okay; x++) | |
| { | |
| for (int y = y1; y <= y2 && okay; y++) | |
| { | |
| if (ter(x, y) != t_grass && ter(x, y) != t_dirt) | |
| { | |
| okay = false; | |
| } | |
| } | |
| } | |
| if (okay) | |
| { | |
| room_type type = room_type(rng(room_mine_office, room_mine_housing)); | |
| build_mine_room(this, type, x1, y1, x2, y2); | |
| tries = 0; | |
| } | |
| else | |
| { | |
| tries++; | |
| } | |
| } | |
| } | |
| while (tries < 5); | |
| int ladderx = rng(0, SEEX * 2 - 1), laddery = rng(0, SEEY * 2 - 1); | |
| while (ter(ladderx, laddery) != t_dirt && ter(ladderx, laddery) != t_grass) | |
| { | |
| ladderx = rng(0, SEEX * 2 - 1); | |
| laddery = rng(0, SEEY * 2 - 1); | |
| } | |
| ter(ladderx, laddery) = t_manhole_cover; | |
| } | |
| break; | |
| case ot_mine_shaft: // Not intended to actually be inhabited! | |
| square(this, t_rock, 0, 0, 23, 23); | |
| square(this, t_hole, SEEX - 3, SEEY - 3, SEEX + 2, SEEY + 2); | |
| line(this, t_grate, SEEX - 3, SEEY - 4, SEEX + 2, SEEY - 4); | |
| ter(SEEX - 3, SEEY - 5) = t_ladder_up; | |
| ter(SEEX + 2, SEEY - 5) = t_ladder_down; | |
| rotate(rng(0, 3)); | |
| break; | |
| case ot_mine: | |
| case ot_mine_down: | |
| if (t_north >= ot_mine && t_north <= ot_mine_finale) | |
| { | |
| n_fac = (one_in(10) ? 0 : -2); | |
| } | |
| else | |
| { | |
| n_fac = 4; | |
| } | |
| if (t_east >= ot_mine && t_east <= ot_mine_finale) | |
| { | |
| e_fac = (one_in(10) ? 0 : -2); | |
| } | |
| else | |
| { | |
| e_fac = 4; | |
| } | |
| if (t_south >= ot_mine && t_south <= ot_mine_finale) | |
| { | |
| s_fac = (one_in(10) ? 0 : -2); | |
| } | |
| else | |
| { | |
| s_fac = 4; | |
| } | |
| if (t_west >= ot_mine && t_west <= ot_mine_finale) | |
| { | |
| w_fac = (one_in(10) ? 0 : -2); | |
| } | |
| else | |
| { | |
| w_fac = 4; | |
| } | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i >= w_fac + rng(0, 2) && i <= SEEX * 2 - 1 - e_fac - rng(0, 2) && | |
| j >= n_fac + rng(0, 2) && j <= SEEY * 2 - 1 - s_fac - rng(0, 2) && | |
| i + j >= 4 && (SEEX * 2 - i) + (SEEY * 2 - j) >= 6) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| } | |
| } | |
| if (t_above == ot_mine_shaft) // We need the entrance room | |
| { | |
| square(this, t_floor, 10, 10, 15, 15); | |
| line(this, t_wall_h, 9, 9, 16, 9); | |
| line(this, t_wall_h, 9, 16, 16, 16); | |
| line(this, t_wall_v, 9, 10, 9, 15); | |
| line(this, t_wall_v, 16, 10, 16, 15); | |
| line(this, t_wall_h, 10, 11, 12, 11); | |
| ter(10, 10) = t_elevator_control; | |
| ter(11, 10) = t_elevator; | |
| ter(10, 12) = t_ladder_up; | |
| line(this, t_counter, 10, 15, 15, 15); | |
| place_items(mi_mine_equipment, 86, 10, 15, 15, 15, false, 0); | |
| if (one_in(2)) | |
| { | |
| ter(9, 12) = t_door_c; | |
| } | |
| else | |
| { | |
| ter(16, 12) = t_door_c; | |
| } | |
| } | |
| else // Not an entrance; maybe some hazards! | |
| { | |
| switch (rng(0, 6)) | |
| { | |
| case 0: | |
| break; // Nothing! Lucky! | |
| case 1: // Toxic gas | |
| { | |
| int cx = rng(9, 14), cy = rng(9, 14); | |
| ter(cx, cy) = t_rock; | |
| add_field(g, cx, cy, fd_gas_vent, 1); | |
| } | |
| break; | |
| case 2: // Lava | |
| { | |
| int x1 = rng(6, SEEX), y1 = rng(6, SEEY), | |
| x2 = rng(SEEX + 1, SEEX * 2 - 7), y2 = rng(SEEY + 1, SEEY * 2 - 7); | |
| int num = rng(2, 4); | |
| for (int i = 0; i < num; i++) | |
| { | |
| int lx1 = x1 + rng(-1, 1), lx2 = x2 + rng(-1, 1), | |
| ly1 = y1 + rng(-1, 1), ly2 = y2 + rng(-1, 1); | |
| line(this, t_lava, lx1, ly1, lx2, ly2); | |
| } | |
| } | |
| break; | |
| case 3: // Wrecked equipment | |
| { | |
| int x = rng(9, 14), y = rng(9, 14); | |
| for (int i = x - 3; i < x + 3; i++) | |
| { | |
| for (int j = y - 3; j < y + 3; j++) | |
| { | |
| if (!one_in(4)) | |
| { | |
| ter(i, j) = t_wreckage; | |
| } | |
| } | |
| } | |
| place_items(mi_wreckage, 70, x - 3, y - 3, x + 2, y + 2, false, 0); | |
| } | |
| break; | |
| case 4: // Dead miners | |
| { | |
| int num_bodies = rng(4, 8); | |
| for (int i = 0; i < num_bodies; i++) | |
| { | |
| int tries = 0; | |
| point body; | |
| do | |
| { | |
| body = point(-1, -1); | |
| int x = rng(0, SEEX * 2 - 1), y = rng(0, SEEY * 2 - 1); | |
| if (move_cost(x, y) == 2) | |
| { | |
| body = point(x, y); | |
| } | |
| else | |
| { | |
| tries++; | |
| } | |
| } | |
| while (body.x == -1 && tries < 10); | |
| if (tries < 10) | |
| { | |
| item miner; | |
| miner.make_corpse(g->itypes[itm_corpse], g->mtypes[mon_null], 0); | |
| add_item(body.x, body.y, miner); | |
| place_items(mi_mine_equipment, 60, body.x, body.y, body.x, body.y, | |
| false, 0); | |
| } | |
| } | |
| } | |
| break; | |
| case 5: // Dark worm! | |
| { | |
| int num_worms = rng(1, 5); | |
| for (int i = 0; i < num_worms; i++) | |
| { | |
| std::vector<direction> sides; | |
| if (n_fac == 6) | |
| { | |
| sides.push_back(NORTH); | |
| } | |
| if (e_fac == 6) | |
| { | |
| sides.push_back(EAST); | |
| } | |
| if (s_fac == 6) | |
| { | |
| sides.push_back(SOUTH); | |
| } | |
| if (w_fac == 6) | |
| { | |
| sides.push_back(WEST); | |
| } | |
| if (sides.empty()) | |
| { | |
| add_spawn(mon_dark_wyrm, 1, SEEX, SEEY); | |
| i = num_worms; | |
| } | |
| else | |
| { | |
| direction side = sides[rng(0, sides.size() - 1)]; | |
| point p; | |
| switch (side) | |
| { | |
| case NORTH: | |
| p = point(rng(1, SEEX * 2 - 2), rng(1, 5)); | |
| break; | |
| case EAST: | |
| p = point(SEEX * 2 - rng(2, 6), rng(1, SEEY * 2 - 2)); | |
| break; | |
| case SOUTH: | |
| p = point(rng(1, SEEX * 2 - 2), SEEY * 2 - rng(2, 6)); | |
| break; | |
| case WEST: | |
| p = point(rng(1, 5) , rng(1, SEEY * 2 - 2)); | |
| break; | |
| } | |
| ter(p.x, p.y) = t_rock_floor; | |
| add_spawn(mon_dark_wyrm, 1, p.x, p.y); | |
| } | |
| } | |
| } | |
| break; | |
| case 6: // Spiral | |
| { | |
| int orx = rng(SEEX - 4, SEEX), ory = rng(SEEY - 4, SEEY); | |
| line(this, t_rock, orx , ory , orx + 5, ory); | |
| line(this, t_rock, orx + 5, ory , orx + 5, ory + 5); | |
| line(this, t_rock, orx + 1, ory + 5, orx + 5, ory + 5); | |
| line(this, t_rock, orx + 1, ory + 2, orx + 1, ory + 4); | |
| line(this, t_rock, orx + 1, ory + 2, orx + 3, ory + 2); | |
| ter(orx + 3, ory + 3) = t_rock; | |
| item miner; | |
| miner.make_corpse(g->itypes[itm_corpse], g->mtypes[mon_null], 0); | |
| add_item(orx + 2, ory + 3, miner); | |
| place_items(mi_mine_equipment, 60, orx + 2, ory + 3, orx + 2, ory + 3, | |
| false, 0); | |
| } | |
| break; | |
| } | |
| } | |
| if (terrain_type == ot_mine_down) // Don't forget to build a slope down! | |
| { | |
| std::vector<direction> open; | |
| if (n_fac == 4) | |
| { | |
| open.push_back(NORTH); | |
| } | |
| if (e_fac == 4) | |
| { | |
| open.push_back(EAST); | |
| } | |
| if (s_fac == 4) | |
| { | |
| open.push_back(SOUTH); | |
| } | |
| if (w_fac == 4) | |
| { | |
| open.push_back(WEST); | |
| } | |
| if (open.empty()) // We'll have to build it in the center | |
| { | |
| int tries = 0; | |
| point p; | |
| bool okay = true; | |
| do | |
| { | |
| p.x = rng(SEEX - 6, SEEX + 1); | |
| p.y = rng(SEEY - 6, SEEY + 1); | |
| okay = true; | |
| for (int i = p.x; i <= p.x + 5 && okay; i++) | |
| { | |
| for (int j = p.y; j <= p.y + 5 && okay; j++) | |
| { | |
| if (ter(i, j) != t_rock_floor) | |
| { | |
| okay = false; | |
| } | |
| } | |
| } | |
| if (!okay) | |
| { | |
| tries++; | |
| } | |
| } | |
| while (!okay && tries < 10); | |
| if (tries == 10) // Clear the area around the slope down | |
| { | |
| square(this, t_rock_floor, p.x, p.y, p.x + 5, p.y + 5); | |
| } | |
| square(this, t_slope_down, p.x + 1, p.y + 1, p.x + 2, p.y + 2); | |
| } | |
| else // We can build against a wall | |
| { | |
| direction side = open[rng(0, open.size() - 1)]; | |
| switch (side) | |
| { | |
| case NORTH: | |
| square(this, t_rock_floor, SEEX - 3, 6, SEEX + 2, SEEY); | |
| line(this, t_slope_down, SEEX - 2, 6, SEEX + 1, 6); | |
| break; | |
| case EAST: | |
| square(this, t_rock_floor, SEEX + 1, SEEY - 3, SEEX * 2 - 7, SEEY + 2); | |
| line(this, t_slope_down, SEEX * 2 - 7, SEEY - 2, SEEX * 2 - 7, SEEY + 1); | |
| break; | |
| case SOUTH: | |
| square(this, t_rock_floor, SEEX - 3, SEEY + 1, SEEX + 2, SEEY * 2 - 7); | |
| line(this, t_slope_down, SEEX - 2, SEEY * 2 - 7, SEEX + 1, SEEY * 2 - 7); | |
| break; | |
| case WEST: | |
| square(this, t_rock_floor, 6, SEEY - 3, SEEX, SEEY + 2); | |
| line(this, t_slope_down, 6, SEEY - 2, 6, SEEY + 1); | |
| break; | |
| } | |
| } | |
| } // Done building a slope down | |
| if (t_above == ot_mine_down) // Don't forget to build a slope up! | |
| { | |
| std::vector<direction> open; | |
| if (n_fac == 6 && ter(SEEX, 6) != t_slope_down) | |
| { | |
| open.push_back(NORTH); | |
| } | |
| if (e_fac == 6 && ter(SEEX * 2 - 7, SEEY) != t_slope_down) | |
| { | |
| open.push_back(EAST); | |
| } | |
| if (s_fac == 6 && ter(SEEX, SEEY * 2 - 7) != t_slope_down) | |
| { | |
| open.push_back(SOUTH); | |
| } | |
| if (w_fac == 6 && ter(6, SEEY) != t_slope_down) | |
| { | |
| open.push_back(WEST); | |
| } | |
| if (open.empty()) // We'll have to build it in the center | |
| { | |
| int tries = 0; | |
| point p; | |
| bool okay = true; | |
| do | |
| { | |
| p.x = rng(SEEX - 6, SEEX + 1); | |
| p.y = rng(SEEY - 6, SEEY + 1); | |
| okay = true; | |
| for (int i = p.x; i <= p.x + 5 && okay; i++) | |
| { | |
| for (int j = p.y; j <= p.y + 5 && okay; j++) | |
| { | |
| if (ter(i, j) != t_rock_floor) | |
| { | |
| okay = false; | |
| } | |
| } | |
| } | |
| if (!okay) | |
| { | |
| tries++; | |
| } | |
| } | |
| while (!okay && tries < 10); | |
| if (tries == 10) // Clear the area around the slope down | |
| { | |
| square(this, t_rock_floor, p.x, p.y, p.x + 5, p.y + 5); | |
| } | |
| square(this, t_slope_up, p.x + 1, p.y + 1, p.x + 2, p.y + 2); | |
| } | |
| else // We can build against a wall | |
| { | |
| direction side = open[rng(0, open.size() - 1)]; | |
| switch (side) | |
| { | |
| case NORTH: | |
| line(this, t_slope_up, SEEX - 2, 6, SEEX + 1, 6); | |
| break; | |
| case EAST: | |
| line(this, t_slope_up, SEEX * 2 - 7, SEEY - 2, SEEX * 2 - 7, SEEY + 1); | |
| break; | |
| case SOUTH: | |
| line(this, t_slope_up, SEEX - 2, SEEY * 2 - 7, SEEX + 1, SEEY * 2 - 7); | |
| break; | |
| case WEST: | |
| line(this, t_slope_up, 6, SEEY - 2, 6, SEEY + 1); | |
| break; | |
| } | |
| } | |
| } // Done building a slope up | |
| break; | |
| case ot_mine_finale: | |
| { | |
| // Set up the basic chamber | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i > rng(1, 3) && i < SEEX * 2 - rng(2, 4) && | |
| j > rng(1, 3) && j < SEEY * 2 - rng(2, 4)) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| } | |
| } | |
| std::vector<direction> face; // Which walls are solid, and can be a facing? | |
| // Now draw the entrance(s) | |
| if (t_north == ot_mine) | |
| { | |
| square(this, t_rock_floor, SEEX, 0, SEEX + 1, 3); | |
| } | |
| else | |
| { | |
| face.push_back(NORTH); | |
| } | |
| if (t_east == ot_mine) | |
| { | |
| square(this, t_rock_floor, SEEX * 2 - 4, SEEY, SEEX * 2 - 1, SEEY + 1); | |
| } | |
| else | |
| { | |
| face.push_back(EAST); | |
| } | |
| if (t_south == ot_mine) | |
| { | |
| square(this, t_rock_floor, SEEX, SEEY * 2 - 4, SEEX + 1, SEEY * 2 - 1); | |
| } | |
| else | |
| { | |
| face.push_back(SOUTH); | |
| } | |
| if (t_west == ot_mine) | |
| { | |
| square(this, t_rock_floor, 0, SEEY, 3, SEEY + 1); | |
| } | |
| else | |
| { | |
| face.push_back(WEST); | |
| } | |
| // Now, pick and generate a type of finale! | |
| if (face.empty()) | |
| { | |
| rn = rng(1, 3); // Amigara fault is not valid | |
| } | |
| else | |
| { | |
| rn = rng(1, 4); | |
| } | |
| switch (rn) | |
| { | |
| case 1: // Wyrms | |
| { | |
| int x = rng(SEEX, SEEX + 1), y = rng(SEEY, SEEY + 1); | |
| ter(x, y) = t_pedestal_wyrm; | |
| add_item(x, y, (*itypes)[itm_petrified_eye], 0); | |
| } | |
| break; // That's it! game::examine handles the pedestal/wyrm spawns | |
| case 2: // The Thing dog | |
| { | |
| item miner; | |
| miner.make_corpse(g->itypes[itm_corpse], g->mtypes[mon_null], 0); | |
| int num_bodies = rng(4, 8); | |
| for (int i = 0; i < num_bodies; i++) | |
| { | |
| int x = rng(4, SEEX * 2 - 5), y = rng(4, SEEX * 2 - 5); | |
| add_item(x, y, miner); | |
| place_items(mi_mine_equipment, 60, x, y, x, y, false, 0); | |
| } | |
| add_spawn(mon_dog_thing, 1, rng(SEEX, SEEX + 1), rng(SEEX, SEEX + 1), true); | |
| add_item(rng(SEEX, SEEX + 1), rng(SEEY, SEEY + 1), g->new_artifact(), 0); | |
| } | |
| break; | |
| case 3: // Spiral down | |
| { | |
| line(this, t_rock, 5, 5, 5, 18); | |
| line(this, t_rock, 5, 5, 18, 5); | |
| line(this, t_rock, 18, 5, 18, 18); | |
| line(this, t_rock, 8, 18, 18, 18); | |
| line(this, t_rock, 8, 8, 8, 18); | |
| line(this, t_rock, 8, 8, 15, 8); | |
| line(this, t_rock, 15, 8, 15, 15); | |
| line(this, t_rock, 10, 15, 15, 15); | |
| line(this, t_rock, 10, 10, 10, 15); | |
| line(this, t_rock, 10, 10, 13, 10); | |
| line(this, t_rock, 13, 10, 13, 13); | |
| ter(12, 13) = t_rock; | |
| ter(12, 12) = t_slope_down; | |
| ter(12, 11) = t_slope_down; | |
| } | |
| break; | |
| case 4: // Amigara fault | |
| { | |
| direction fault = face[rng(0, face.size() - 1)]; | |
| // Construct the fault on the appropriate face | |
| switch (fault) | |
| { | |
| case NORTH: | |
| square(this, t_rock, 0, 0, SEEX * 2 - 1, 4); | |
| line(this, t_fault, 4, 4, SEEX * 2 - 5, 4); | |
| break; | |
| case EAST: | |
| square(this, t_rock, SEEX * 2 - 5, 0, SEEY * 2 - 1, SEEX * 2 - 1); | |
| line(this, t_fault, SEEX * 2 - 5, 4, SEEX * 2 - 5, SEEY * 2 - 5); | |
| break; | |
| case SOUTH: | |
| square(this, t_rock, 0, SEEY * 2 - 5, SEEX * 2 - 1, SEEY * 2 - 1); | |
| line(this, t_fault, 4, SEEY * 2 - 5, SEEX * 2 - 5, SEEY * 2 - 5); | |
| break; | |
| case WEST: | |
| square(this, t_rock, 0, 0, 4, SEEY * 2 - 1); | |
| line(this, t_fault, 4, 4, 4, SEEY * 2 - 5); | |
| break; | |
| } | |
| ter(SEEX, SEEY) = t_console; | |
| tmpcomp = add_computer(SEEX, SEEY, "NEPowerOS", 0); | |
| tmpcomp->add_option("Read Logs", COMPACT_AMIGARA_LOG, 0); | |
| tmpcomp->add_option("Initiate Tremors", COMPACT_AMIGARA_START, 4); | |
| tmpcomp->add_failure(COMPFAIL_AMIGARA); | |
| } | |
| break; | |
| } | |
| } | |
| break; | |
| case ot_spiral_hub: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| line(this, t_rock, 23, 0, 23, 23); | |
| line(this, t_rock, 2, 23, 23, 23); | |
| line(this, t_rock, 2, 4, 2, 23); | |
| line(this, t_rock, 2, 4, 18, 4); | |
| line(this, t_rock, 18, 4, 18, 18); // bad | |
| line(this, t_rock, 6, 18, 18, 18); | |
| line(this, t_rock, 6, 7, 6, 18); | |
| line(this, t_rock, 6, 7, 15, 7); | |
| line(this, t_rock, 15, 7, 15, 15); | |
| line(this, t_rock, 8, 15, 15, 15); | |
| line(this, t_rock, 8, 9, 8, 15); | |
| line(this, t_rock, 8, 9, 13, 9); | |
| line(this, t_rock, 13, 9, 13, 13); | |
| line(this, t_rock, 10, 13, 13, 13); | |
| line(this, t_rock, 10, 11, 10, 13); | |
| square(this, t_slope_up, 11, 11, 12, 12); | |
| rotate(rng(0, 3)); | |
| break; | |
| case ot_spiral: | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| int num_spiral = rng(1, 4); | |
| for (int i = 0; i < num_spiral; i++) | |
| { | |
| int orx = rng(SEEX - 4, SEEX), ory = rng(SEEY - 4, SEEY); | |
| line(this, t_rock, orx , ory , orx + 5, ory); | |
| line(this, t_rock, orx + 5, ory , orx + 5, ory + 5); | |
| line(this, t_rock, orx + 1, ory + 5, orx + 5, ory + 5); | |
| line(this, t_rock, orx + 1, ory + 2, orx + 1, ory + 4); | |
| line(this, t_rock, orx + 1, ory + 2, orx + 3, ory + 2); | |
| ter(orx + 3, ory + 3) = t_rock; | |
| ter(orx + 2, ory + 3) = t_rock_floor; | |
| place_items(mi_spiral, 60, orx + 2, ory + 3, orx + 2, ory + 3, false, 0); | |
| } | |
| } | |
| break; | |
| case ot_radio_tower: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| lw = rng(1, SEEX * 2 - 2); | |
| tw = rng(1, SEEY * 2 - 2); | |
| for (int i = lw; i < lw + 4; i++) | |
| { | |
| for (int j = tw; j < tw + 4; j++) | |
| { | |
| ter(i, j) = t_radio_tower; | |
| } | |
| } | |
| rw = -1; | |
| bw = -1; | |
| if (lw <= 4) | |
| { | |
| rw = rng(lw + 5, 10); | |
| } | |
| else if (lw >= 16) | |
| { | |
| rw = rng(3, lw - 13); | |
| } | |
| if (tw <= 3) | |
| { | |
| bw = rng(tw + 5, 10); | |
| } | |
| else if (tw >= 16) | |
| { | |
| bw = rng(3, tw - 7); | |
| } | |
| if (rw != -1 && bw != -1) | |
| { | |
| for (int i = rw; i < rw + 12; i++) | |
| { | |
| for (int j = bw; j < bw + 6; j++) | |
| { | |
| if (j == bw || j == bw + 5) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else if (i == rw || i == rw + 11) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else if (j == bw + 1) | |
| { | |
| ter(i, j) = t_counter; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| } | |
| } | |
| cw = rng(rw + 2, rw + 8); | |
| ter(cw, bw + 5) = t_window; | |
| ter(cw + 1, bw + 5) = t_window; | |
| ter(rng(rw + 2, rw + 8), bw + 5) = t_door_c; | |
| ter(rng(rw + 2, rw + 8), bw + 1) = t_radio_controls; | |
| place_items(mi_radio, 60, rw + 1, bw + 2, rw + 10, bw + 4, true, 0); | |
| } | |
| else // No control room... simple controls near the tower | |
| { | |
| ter(rng(lw, lw + 3), tw + 4) = t_radio_controls; | |
| } | |
| break; | |
| case ot_toxic_dump: | |
| { | |
| square(this, t_dirt, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1); | |
| for (int n = 0; n < 6; n++) | |
| { | |
| int poolx = rng(4, SEEX * 2 - 5), pooly = rng(4, SEEY * 2 - 5); | |
| for (int i = poolx - 3; i <= poolx + 3; i++) | |
| { | |
| for (int j = pooly - 3; j <= pooly + 3; j++) | |
| { | |
| if (rng(2, 5) > rl_dist(poolx, pooly, i, j)) | |
| { | |
| ter(i, j) = t_sewage; | |
| radiation(i, j) += rng(20, 60); | |
| } | |
| } | |
| } | |
| } | |
| int buildx = rng(6, SEEX * 2 - 7), buildy = rng(6, SEEY * 2 - 7); | |
| square(this, t_floor, buildx - 3, buildy - 3, buildx + 3, buildy + 3); | |
| line(this, t_wall_h, buildx - 4, buildy - 4, buildx + 4, buildy - 4); | |
| line(this, t_wall_h, buildx - 4, buildy + 4, buildx + 4, buildy + 4); | |
| line(this, t_wall_v, buildx - 4, buildy - 4, buildx - 4, buildy + 4); | |
| line(this, t_wall_v, buildx + 4, buildy - 4, buildx + 4, buildy + 4); | |
| line(this, t_counter, buildx - 3, buildy - 3, buildx + 3, buildy - 3); | |
| place_items(mi_toxic_dump_equipment, 80, | |
| buildx - 3, buildy - 3, buildx + 3, buildy - 3, false, 0); | |
| add_item(buildx, buildy, g->itypes[itm_id_military], 0); | |
| ter(buildx, buildy + 4) = t_door_locked; | |
| rotate(rng(0, 3)); | |
| } | |
| break; | |
| case ot_cave: | |
| if (t_above == ot_cave) // We're underground! | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (rng(0, 6) < i || SEEX * 2 - rng(1, 7) > i || | |
| rng(0, 6) < j || SEEY * 2 - rng(1, 7) > j) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| } | |
| } | |
| square(this, t_slope_up, SEEX - 1, SEEY - 1, SEEX, SEEY); | |
| switch (rng(1, 3)) // What type of cave is it? | |
| { | |
| case 1: // Bear cave | |
| add_spawn(mon_bear, 1, rng(SEEX - 6, SEEX + 5), rng(SEEY - 6, SEEY + 5)); | |
| if (one_in(4)) | |
| { | |
| add_spawn(mon_bear, 1, rng(SEEX - 6, SEEX + 5), rng(SEEY - 6, SEEY + 5)); | |
| } | |
| place_items(mi_ant_food, 80, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| break; | |
| case 2: // Wolf cave! | |
| do | |
| { | |
| add_spawn(mon_wolf, 1, rng(SEEX - 6, SEEX + 5), rng(SEEY - 6, SEEY + 5)); | |
| } | |
| while (one_in(2)); | |
| place_items(mi_ant_food, 86, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| break; | |
| case 3: // Hermit cave | |
| { | |
| int origx = rng(SEEX - 1, SEEX), origy = rng(SEEY - 1, SEEY), | |
| hermx = rng(SEEX - 6, SEEX + 5), hermy = rng(SEEX - 6, SEEY + 5); | |
| std::vector<point> bloodline = line_to(origx, origy, hermx, hermy, 0); | |
| for (int ii = 0; ii < bloodline.size(); ii++) | |
| { | |
| add_field(g, bloodline[ii].x, bloodline[ii].y, fd_blood, 2); | |
| } | |
| item body; | |
| body.make_corpse(g->itypes[itm_corpse], g->mtypes[mon_null], g->turn); | |
| add_item(hermx, hermy, body); | |
| place_items(mi_rare, 25, hermx - 1, hermy - 1, hermx + 1, hermy + 1, true, 0); | |
| } | |
| break; | |
| } | |
| } | |
| else // We're above ground! | |
| { | |
| // First, draw a forest | |
| draw_map(ot_forest, t_north, t_east, t_south, t_west, t_above, turn, g); | |
| // Clear the center with some rocks | |
| square(this, t_rock, SEEX - 6, SEEY - 6, SEEX + 5, SEEY + 5); | |
| int pathx, pathy; | |
| if (one_in(2)) | |
| { | |
| pathx = rng(SEEX - 6, SEEX + 5); | |
| pathy = (one_in(2) ? SEEY - 8 : SEEY + 7); | |
| } | |
| else | |
| { | |
| pathx = (one_in(2) ? SEEX - 8 : SEEX + 7); | |
| pathy = rng(SEEY - 6, SEEY + 5); | |
| } | |
| std::vector<point> pathline = line_to(pathx, pathy, SEEX - 1, SEEY - 1, 0); | |
| for (int ii = 0; ii < pathline.size(); ii++) | |
| square(this, t_dirt, pathline[ii].x, pathline[ii].y, | |
| pathline[ii].x + 1, pathline[ii].y + 1); | |
| while (!one_in(8)) | |
| { | |
| ter(rng(SEEX - 6, SEEX + 5), rng(SEEY - 6, SEEY + 5)) = t_dirt; | |
| } | |
| square(this, t_slope_down, SEEX - 1, SEEY - 1, SEEX, SEEY); | |
| } | |
| break; | |
| case ot_cave_rat: | |
| square(this, t_rock, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1); | |
| if (t_above == ot_cave_rat) // Finale | |
| { | |
| rough_circle(this, t_rock_floor, SEEX, SEEY, 8); | |
| square(this, t_rock_floor, SEEX - 1, SEEY, SEEX, SEEY * 2 - 2); | |
| line(this, t_slope_up, SEEX - 1, SEEY * 2 - 3, SEEX, SEEY * 2 - 2); | |
| for (int i = SEEX - 4; i <= SEEX + 4; i++) | |
| { | |
| for (int j = SEEY - 4; j <= SEEY + 4; j++) | |
| { | |
| if ((i <= SEEX - 2 || i >= SEEX + 2) && (j <= SEEY - 2 || j >= SEEY + 2)) | |
| { | |
| add_spawn(mon_sewer_rat, 1, i, j); | |
| } | |
| } | |
| } | |
| add_spawn(mon_rat_king, 1, SEEX, SEEY); | |
| place_items(mi_rare, 75, SEEX - 4, SEEY - 4, SEEX + 4, SEEY + 4, true, 0); | |
| } | |
| else // Level 1 | |
| { | |
| int cavex = SEEX, cavey = SEEY * 2 - 3; | |
| int stairsx = SEEX - 1, stairsy = 1; // Default stairs location--may change | |
| int centerx; | |
| do | |
| { | |
| cavex += rng(-1, 1); | |
| cavey -= rng(0, 1); | |
| for (int cx = cavex - 1; cx <= cavex + 1; cx++) | |
| { | |
| for (int cy = cavey - 1; cy <= cavey + 1; cy++) | |
| { | |
| ter(cx, cy) = t_rock_floor; | |
| if (one_in(10)) | |
| { | |
| add_field(g, cx, cy, fd_blood, rng(1, 3)); | |
| } | |
| if (one_in(20)) | |
| { | |
| add_spawn(mon_sewer_rat, 1, cx, cy); | |
| } | |
| } | |
| } | |
| if (cavey == SEEY - 1) | |
| { | |
| centerx = cavex; | |
| } | |
| } | |
| while (cavey > 2); | |
| // Now draw some extra passages! | |
| do | |
| { | |
| int tox = (one_in(2) ? 2 : SEEX * 2 - 3), toy = rng(2, SEEY * 2 - 3); | |
| std::vector<point> path = line_to(centerx, SEEY - 1, tox, toy, 0); | |
| for (int i = 0; i < path.size(); i++) | |
| { | |
| for (int cx = path[i].x - 1; cx <= path[i].x + 1; cx++) | |
| { | |
| for (int cy = path[i].y - 1; cy <= path[i].y + 1; cy++) | |
| { | |
| ter(cx, cy) = t_rock_floor; | |
| if (one_in(10)) | |
| { | |
| add_field(g, cx, cy, fd_blood, rng(1, 3)); | |
| } | |
| if (one_in(20)) | |
| { | |
| add_spawn(mon_sewer_rat, 1, cx, cy); | |
| } | |
| } | |
| } | |
| } | |
| if (one_in(2)) | |
| { | |
| stairsx = tox; | |
| stairsy = toy; | |
| } | |
| } | |
| while (one_in(2)); | |
| // Finally, draw the stairs up and down. | |
| ter(SEEX - 1, SEEX * 2 - 2) = t_slope_up; | |
| ter(SEEX , SEEX * 2 - 2) = t_slope_up; | |
| ter(stairsx, stairsy) = t_slope_down; | |
| } | |
| break; | |
| case ot_sub_station_north: | |
| case ot_sub_station_east: | |
| case ot_sub_station_south: | |
| case ot_sub_station_west: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (j < 9 || j > 12 || i < 4 || i > 19) | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| else if (j < 12 && j > 8 && (i == 4 || i == 19)) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else if (i > 3 && i < 20 && j == 12) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| } | |
| } | |
| ter(16, 10) = t_stairs_down; | |
| if (terrain_type == ot_sub_station_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_sub_station_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_sub_station_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_s_garage_north: | |
| case ot_s_garage_east: | |
| case ot_s_garage_south: | |
| case ot_s_garage_west: | |
| { | |
| square(this, grass_or_dirt(), 0, 0, SEEX * 2, SEEY * 2); | |
| int yard_wdth = 5; | |
| square(this, t_floor, 0, yard_wdth, SEEX * 2 - 4, SEEY * 2 - 4); | |
| line(this, t_wall_v, 0, yard_wdth, 0, SEEY * 2 - 4); | |
| line(this, t_wall_v, SEEX * 2 - 3, yard_wdth, SEEX * 2 - 3, SEEY * 2 - 4); | |
| line(this, t_wall_h, 0, SEEY * 2 - 4, SEEX * 2 - 3, SEEY * 2 - 4); | |
| line(this, t_window, 0, SEEY * 2 - 4, SEEX * 2 - 14, SEEY * 2 - 4); | |
| line(this, t_wall_h, 0, SEEY * 2 - 4, SEEX * 2 - 20, SEEY * 2 - 4); | |
| line(this, t_wall_h, 0, yard_wdth, 2, yard_wdth); | |
| line(this, t_wall_h, 8, yard_wdth, 13, yard_wdth); | |
| line(this, t_wall_h, 20, yard_wdth, 21, yard_wdth); | |
| line(this, t_counter, 1, yard_wdth + 1, 1, yard_wdth + 7); | |
| line(this, t_wall_h, 1, SEEY * 2 - 9, 3, SEEY * 2 - 9); | |
| line(this, t_wall_v, 3, SEEY * 2 - 8, 3, SEEY * 2 - 5); | |
| ter(3, SEEY * 2 - 7) = t_door_frame; | |
| ter(21, SEEY * 2 - 7) = t_door_c; | |
| line(this, t_counter, 4, SEEY * 2 - 5, 15, SEEY * 2 - 5); | |
| //office | |
| line(this, t_wall_glass_h, 16, SEEY * 2 - 9 , 20, SEEY * 2 - 9); | |
| line(this, t_wall_glass_v, 16, SEEY * 2 - 8, 16, SEEY * 2 - 5); | |
| ter(16, SEEY * 2 - 7) = t_door_glass_c; | |
| line(this, t_bench, SEEX * 2 - 6, SEEY * 2 - 8, SEEX * 2 - 4, SEEY * 2 - 8); | |
| ter(SEEX * 2 - 6, SEEY * 2 - 6) = t_console_broken; | |
| ter(SEEX * 2 - 5, SEEY * 2 - 6) = t_bench; | |
| line(this, t_locker, SEEX * 2 - 6, SEEY * 2 - 5, SEEX * 2 - 4, SEEY * 2 - 5); | |
| //gates | |
| line(this, t_door_metal_locked, 3, yard_wdth, 8, yard_wdth); | |
| ter(2, yard_wdth + 1) = t_gates_mech_control; | |
| ter(2, yard_wdth - 1) = t_gates_mech_control; | |
| line(this, t_door_metal_locked, 14, yard_wdth, 19, yard_wdth); | |
| ter(13, yard_wdth + 1) = t_gates_mech_control; | |
| ter(13, yard_wdth - 1) = t_gates_mech_control; | |
| //place items | |
| place_items(mi_mechanics, 90, 1, yard_wdth + 1, 1, yard_wdth + 7, true, 0); | |
| place_items(mi_mechanics, 90, 4, SEEY * 2 - 5, 15, SEEY * 2 - 5, true, 0); | |
| // rotate garage | |
| int vy = 0, vx = 0, theta = 0; | |
| if (terrain_type == ot_s_garage_north) | |
| { | |
| vx = 5, vy = yard_wdth + 6; | |
| theta = 90; | |
| } | |
| else if (terrain_type == ot_s_garage_east) | |
| { | |
| rotate(1); | |
| vx = yard_wdth + 8, vy = 4; | |
| theta = 0; | |
| } | |
| else if (terrain_type == ot_s_garage_south) | |
| { | |
| rotate(2); | |
| vx = SEEX * 2 - 6, vy = SEEY * 2 - (yard_wdth + 3); | |
| theta = 270; | |
| } | |
| else if (terrain_type == ot_s_garage_west) | |
| { | |
| rotate(3); | |
| vx = SEEX * 2 - yard_wdth - 9, vy = SEEY * 2 - 5; | |
| theta = 180; | |
| } | |
| // place vehicle, if any | |
| if (one_in(3)) | |
| { | |
| vhtype_id vt; | |
| if (one_in(3)) | |
| { | |
| vt = one_in(2) ? veh_car : veh_car_chassis; | |
| } | |
| else if (one_in(2)) | |
| { | |
| vt = one_in(2) ? veh_sandbike : veh_sandbike_chassis; | |
| } | |
| else | |
| { | |
| vt = one_in(2) ? veh_motorcycle : veh_motorcycle_chassis; | |
| } | |
| add_vehicle(g, vt, vx, vy, theta); | |
| } | |
| } | |
| break; | |
| case ot_cabin: | |
| { | |
| square(this, t_grass, 0, 0, 23, 23); | |
| //Cabin design 1 Quad | |
| if (one_in(2)) | |
| { | |
| square(this, t_wall_log, 2, 3, 21, 20); | |
| square(this, t_floor, 2, 17, 21, 20);//Front porch | |
| line(this, t_fence_v, 2, 17, 2, 20); | |
| line(this, t_fence_v, 21, 17, 21, 20); | |
| line(this, t_fence_h, 2, 20, 21, 20); | |
| ter(2, 17) = t_column; | |
| ter(2, 20) = t_column; | |
| ter(21, 17) = t_column; | |
| ter(21, 20) = t_column; | |
| ter(10, 20) = t_column; | |
| ter(13, 20) = t_column; | |
| line(this, t_fencegate_c, 11, 20, 12, 20); | |
| line(this, t_bench, 4, 17, 7, 17); | |
| square(this, t_rubble, 19, 18, 20, 19); | |
| ter(20, 17) = t_rubble; | |
| ter(18, 19) = t_rubble; //Porch done | |
| line(this, t_door_c, 11, 16, 12, 16);//Interior | |
| square(this, t_floor, 3, 4, 9, 9); | |
| square(this, t_floor, 3, 11, 9, 15); | |
| square(this, t_floor, 11, 4, 12, 15); | |
| square(this, t_floor, 14, 4, 20, 9); | |
| square(this, t_floor, 14, 11, 20, 15); | |
| line(this, t_wall_log, 7, 4, 7, 8); | |
| square(this, t_wall_log, 8, 8, 9, 9); | |
| line(this, t_rack, 3, 4, 3, 9); //Pantry Racks | |
| line(this, t_curtains, 2, 6, 2, 7); //Windows start | |
| line(this, t_curtains, 2, 12, 2, 13); | |
| line(this, t_window_domestic, 5, 16, 6, 16); | |
| line(this, t_window_domestic, 17, 16, 18, 16); | |
| line(this, t_curtains, 21, 12, 21, 13); | |
| line(this, t_window_empty, 21, 6, 21, 7); | |
| ter(8, 3) = t_curtains;//Windows End | |
| line(this, t_door_c, 11, 3, 12, 3);//Rear Doors | |
| square(this, t_rubble, 20, 3, 21, 4); | |
| ter(19, 3) = t_rubble; | |
| ter(21, 5) = t_rubble; | |
| ter(6, 4) = t_desk; | |
| ter(6, 5) = t_chair; | |
| ter(7, 9) = t_locker; | |
| ter(6, 10) = t_door_c; | |
| ter(10, 6) = t_door_c; | |
| square(this, t_table, 3, 11, 4, 12); | |
| line(this, t_bench, 5, 11, 5, 12); | |
| line(this, t_bench, 3, 13, 4, 13); | |
| line(this, t_cupboard, 3, 15, 7, 15); | |
| ter(4, 15) = t_fridge; | |
| ter(5, 15) = t_sink; | |
| ter(6, 15) = t_oven; | |
| ter(10, 13) = t_door_c; | |
| ter(13, 13) = t_door_c; | |
| ter(14, 11) = t_armchair; | |
| line(this, t_sofa, 16, 11, 18, 11); | |
| square(this, t_rock_floor, 18, 13, 20, 15); | |
| ter(19, 14) = t_woodstove; | |
| ter(19, 10) = t_door_c; | |
| line(this, t_bookcase, 14, 9, 17, 9); | |
| square(this, t_bed, 17, 4, 18, 5); | |
| ter(16, 4) = t_dresser; | |
| ter(19, 4) = t_dresser; | |
| ter(13, 6) = t_door_c; | |
| ter(9, 4) = t_toilet; | |
| line(this, t_bathtub, 8, 7, 9, 7); | |
| ter(8, 5) = t_sink; | |
| place_items(mi_fridge, 65, 4, 15, 4, 15, false, 0); | |
| place_items(mi_homeguns, 30, 7, 9, 7, 9, false, 0); | |
| place_items(mi_home_hw, 60, 7, 9, 7, 9, false, 0); | |
| place_items(mi_kitchen, 60, 3, 15, 3, 15, false, 0); | |
| place_items(mi_kitchen, 60, 7, 15, 7, 15, false, 0); | |
| place_items(mi_dining, 60, 3, 11, 4, 12, false, 0); | |
| place_items(mi_trash, 60, 0, 0, 23, 23, false, 0); | |
| place_items(mi_survival_tools, 30, 3, 4, 3, 9, false, 0); | |
| place_items(mi_cannedfood, 50, 3, 4, 3, 9, false, 0); | |
| place_items(mi_camping, 50, 4, 4, 6, 9, false, 0); | |
| place_items(mi_magazines, 60, 14, 9, 17, 9, false, 0); | |
| place_items(mi_manuals, 30, 14, 9, 17, 9, false, 0); | |
| place_items(mi_dresser, 50, 16, 4, 16, 4, false, 0); | |
| place_items(mi_dresser, 50, 19, 4, 19, 4, false, 0); | |
| place_items(mi_softdrugs, 60, 8, 4, 9, 7, false, 0); | |
| place_items(mi_livingroom, 50, 14, 12, 17, 15, false, 0); | |
| add_spawn(mon_zombie, rng(1, 5), 11, 12); | |
| } | |
| else | |
| { | |
| square(this, t_wall_log, 4, 2, 10, 6); | |
| square(this, t_floor, 5, 3, 9, 5); | |
| square(this, t_wall_log, 3, 9, 20, 20); | |
| square(this, t_floor, 4, 10, 19, 19); | |
| line(this, t_fence_h, 0, 0, 23, 0); | |
| line(this, t_fence_v, 0, 0, 0, 22); | |
| line(this, t_fence_v, 23, 0, 23, 22); | |
| line(this, t_fence_h, 0, 23, 23, 23); | |
| line(this, t_fencegate_c, 11, 23, 12, 23); | |
| line(this, t_locker, 5, 3, 9, 3); | |
| line(this, t_counter, 6, 3, 8, 3); | |
| ter(4, 4) = t_window_boarded; | |
| ter(10, 4) = t_window_boarded; | |
| ter(7, 6) = t_door_c; | |
| ter(9, 9) = t_door_c; | |
| line(this, t_window_domestic, 13, 9, 14, 9); | |
| square(this, t_rock, 5, 10, 7, 11); | |
| line(this, t_rock_floor, 5, 12, 7, 12); | |
| ter(6, 11) = t_woodstove; | |
| line(this, t_dresser, 16, 10, 19, 10); | |
| square(this, t_bed, 17, 10, 18, 11); | |
| line(this, t_window_domestic, 3, 14, 3, 15); | |
| line(this, t_sofa, 5, 16, 7, 16); | |
| square(this, t_chair, 10, 14, 13, 15); | |
| square(this, t_table, 11, 14, 12, 15); | |
| line(this, t_window_domestic, 20, 14, 20, 15); | |
| line(this, t_window_domestic, 7, 20, 8, 20); | |
| line(this, t_window_domestic, 16, 20, 17, 20); | |
| ter(12, 20) = t_door_c; | |
| place_items(mi_livingroom, 60, 4, 13, 8, 18, false, 0); | |
| place_items(mi_dining, 60, 11, 14, 12, 15, false, 0); | |
| place_items(mi_camping, 70, 19, 16, 19, 19, false, 0); | |
| place_items(mi_dresser, 70, 16, 10, 16, 10, false, 0); | |
| place_items(mi_dresser, 70, 19, 10, 19, 10, false, 0); | |
| place_items(mi_tools, 70, 5, 3, 9, 3, false, 0); | |
| add_spawn(mon_zombie, rng(1, 5), 7, 4); | |
| } | |
| } | |
| break; | |
| case ot_farm: | |
| { | |
| square(this, t_grass, 0, 0, 23, 23); //basic lot | |
| square(this, t_floor, 0, 0, 14, 9); //house floor #1 | |
| square(this, t_wall_wood, 16, 0, 23, 9); //Barn exterior #2 | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 13; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| line(this, t_wall_h, 0, 0, 14, 0); // House north wall #4 | |
| line(this, t_wall_h, 0, 9, 14, 9); // House south wall #5 | |
| line(this, t_wall_h, 1, 5, 8, 5); // House interior wall 1 horizontal #6 | |
| line(this, t_wall_h, 10, 4, 13, 4); // House interior wall 2 horizontal #7 | |
| line(this, t_wall_v, 0, 1, 0, 8); // House west wall #8 | |
| line(this, t_wall_v, 14, 1, 14, 8);// House east wall #9 | |
| line(this, t_wall_v, 9, 4, 9, 5);// House interior wall 3 vertical #10 | |
| line(this, t_wall_v, 10, 1, 10, 3);// House interior wall 4 Vertical #11 | |
| square(this, t_dirtfloor, 17, 1, 22, 8); // Barn Floor #None | |
| ter(5, 0) = t_window_domestic; // Begin placing items left-right, top-down | |
| ter(12, 0) = t_window_domestic; //House window | |
| ter(19, 0) = t_door_c; //Barn door N1 | |
| ter(20, 0) = t_door_c; //Barn door N2 | |
| ter(1, 1) = t_dresser; //Bedroom dresser 1 | |
| square(this, t_bed, 2, 1, 3, 2); //Big old bed in bedroom | |
| ter(4, 1) = t_dresser; //Bedroom dresser 2 | |
| ter(11, 1) = t_toilet; //Toilet in bathroom | |
| ter(12, 1) = t_sink; //Sink in bathroom | |
| ter(17, 1) = t_locker; //Locker in barn | |
| ter(18, 1) = t_locker; //Locker in barn | |
| ter(10, 2) = t_door_c; //bedroom to bathroom door | |
| ter(13, 2) = t_bathtub; //Bathtub | |
| ter(0, 3) = t_window_domestic; //West bedroom window | |
| ter(18, 3) = t_column; //Barn pillar 1 | |
| ter(21, 3) = t_column; //Barn pillar 2 | |
| ter(7, 4) = t_chair; //Chair in bedroom | |
| ter(8, 4) = t_desk; //Desk in bedroom | |
| ter(12, 4) = t_door_c; //Kitchen to bathroom door | |
| ter(5, 5) = t_door_c; //Living room to bedroom door | |
| ter(13, 5) = t_cupboard; //Bleck so many cupboards | |
| ter(2, 6) = t_armchair; //Armchair in living room | |
| ter(13, 6) = t_cupboard; //cupboard.... | |
| ter(18, 6) = t_column; //Barn pillar 3 | |
| ter(21, 6) = t_column; //Barn pillar 4 | |
| ter(13, 7) = t_oven; //oven | |
| ter(22, 7) = t_dirtmound; //oven | |
| line(this, t_cupboard, 8, 8, 13, 8); //Row of cupboards | |
| ter(10, 8) = t_fridge; //Refridgerator | |
| ter(12, 8) = t_sink; //Kitchen sink | |
| line(this, t_dirtmound, 21, 8, 22, 8); //Dirt corner of barn | |
| ter(2, 9) = t_window_domestic; //House window living room | |
| ter(7, 9) = t_door_c; //House entrance | |
| ter(12, 9) = t_window_domestic; //House window kitchen | |
| ter(19, 9) = t_door_c; //Barn door S1 | |
| ter(20, 9) = t_door_c; //Barn door S2 | |
| line(this, t_shrub, 1, 10, 3, 10); //Bushes 1 | |
| line(this, t_shrub, 11, 10, 13, 10); //Bushes 2 | |
| place_items(mi_fridge, 65, 10, 8, 10, 8, false, 0); | |
| place_items(mi_kitchen, 70, 10, 5, 12, 7, false, 0); | |
| place_items(mi_livingroom, 65, 1, 6, 6, 8, false, 0); | |
| place_items(mi_dresser, 80, 1, 1, 1, 1, false, 0); | |
| place_items(mi_dresser, 80, 4, 1, 4, 1, false, 0); | |
| place_items(mi_bedroom, 65, 5, 1, 9, 3, false, 0); | |
| place_items(mi_softdrugs, 70, 11, 2, 12, 3, false, 0); | |
| place_items(mi_bigtools, 50, 17, 1, 22, 8, true, 0); | |
| place_items(mi_homeguns, 20, 17, 1, 22, 8, true, 0); | |
| if (one_in(2)) | |
| { | |
| add_spawn(mon_zombie, rng(1, 6), 20, 4); | |
| } | |
| else | |
| { | |
| add_spawn(mon_zombie, rng(1, 6), 6, 3); | |
| } | |
| rotate(2); | |
| } | |
| break; | |
| case ot_farm_field: | |
| if (t_east == ot_farm) | |
| { | |
| square(this, grass_or_dirt(), 0, 0, SEEX * 2, SEEY * 2); | |
| square(this, t_wall_wood, 3, 3, 20, 20); | |
| square(this, t_dirtfloor, 4, 4, 19, 19); | |
| line(this, t_door_metal_locked, 8, 20, 15, 20); | |
| ter(16, 19) = t_barndoor; | |
| ter(16, 21) = t_barndoor; | |
| line(this, t_door_metal_locked, 8, 3, 15, 3); | |
| ter(16, 2) = t_barndoor; | |
| ter(16, 4) = t_barndoor; | |
| square(this, t_hay, 4, 4, 6, 6); | |
| line(this, t_fence_h, 4, 8, 6, 8); | |
| line(this, t_fence_v, 6, 9, 6, 14); | |
| line(this, t_fence_h, 4, 15, 6, 15); | |
| line(this, t_fencegate_c, 6, 11, 6, 12); | |
| line(this, t_fence_h, 17, 8, 19, 8); | |
| line(this, t_fence_v, 17, 9, 17, 14); | |
| line(this, t_fence_h, 17, 15, 19, 15); | |
| line(this, t_fencegate_c, 17, 11, 17, 12); | |
| line(this, t_locker, 4, 19, 7, 19); | |
| ter(7, 7) = t_column; | |
| ter(16, 7) = t_column; | |
| ter(7, 16) = t_column; | |
| ter(16, 16) = t_column; | |
| ter(5, 3) = t_window_boarded; | |
| ter(18, 3) = t_window_boarded; | |
| line(this, t_window_boarded, 3, 5, 3, 6); | |
| line(this, t_window_boarded, 3, 11, 3, 12); | |
| line(this, t_window_boarded, 3, 17, 3, 18); | |
| line(this, t_window_boarded, 20, 5, 20, 6); | |
| line(this, t_window_boarded, 20, 11, 20, 12); | |
| line(this, t_window_boarded, 20, 17, 20, 18); | |
| ter(5, 20) = t_window_boarded; | |
| ter(18, 20) = t_window_boarded; | |
| place_items(mi_bigtools, 60, 4, 4, 7, 19, true, 0); | |
| place_items(mi_bigtools, 60, 16, 5, 19, 19, true, 0); | |
| place_items(mi_mechanics, 40, 8, 4, 15, 19, true, 0); | |
| place_items(mi_home_hw, 50, 4, 19, 7, 19, true, 0); | |
| place_items(mi_tools, 50, 4, 19, 7, 19, true, 0); | |
| if (one_in(10)) | |
| { | |
| add_spawn(mon_zombie, rng(3, 6), 12, 12); | |
| } | |
| } | |
| else | |
| { | |
| square(this, t_grass, 0, 0, 23, 23); // basic lot | |
| square(this, t_fence_barbed, 1, 1, 22, 22); | |
| square(this, t_dirt, 2, 2, 21, 21); | |
| ter(1, 1) = t_fence_post; | |
| ter(22, 1) = t_fence_post; | |
| ter(1, 22) = t_fence_post; | |
| ter(22, 22) = t_fence_post; | |
| line(this, t_dirtmound, 3, 3, 20, 3); //Crop rows | |
| line(this, t_dirtmound, 3, 5, 20, 5); | |
| line(this, t_dirtmound, 3, 7, 20, 7); | |
| line(this, t_dirtmound, 3, 9, 20, 9); | |
| line(this, t_dirtmound, 3, 11, 20, 11); | |
| line(this, t_dirtmound, 3, 13, 20, 13); | |
| line(this, t_dirtmound, 3, 15, 20, 15); | |
| line(this, t_dirtmound, 3, 17, 20, 17); | |
| line(this, t_dirtmound, 3, 19, 20, 19); | |
| place_items(mi_hydro, 70, 3, 3, 20, 3, true, turn); //Spawn crops | |
| place_items(mi_hydro, 70, 3, 5, 20, 5, true, turn); | |
| place_items(mi_hydro, 70, 3, 7, 20, 7, true, turn); | |
| place_items(mi_hydro, 70, 3, 9, 20, 9, true, turn); | |
| place_items(mi_hydro, 70, 3, 11, 20, 11, true, turn); | |
| place_items(mi_hydro, 70, 3, 13, 20, 13, true, turn); | |
| place_items(mi_hydro, 70, 3, 15, 20, 15, true, turn); | |
| place_items(mi_hydro, 70, 3, 17, 20, 17, true, turn); | |
| place_items(mi_hydro, 70, 3, 19, 20, 19, true, turn); | |
| } | |
| break; | |
| case ot_police_north: | |
| case ot_police_east: | |
| case ot_police_south: | |
| case ot_police_west: | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if ((j == 7 && i != 17 && i != 18) || | |
| (j == 12 && i != 0 && i != 17 && i != 18 && i != SEEX * 2 - 1) || | |
| (j == 14 && ((i > 0 && i < 6) || i == 9 || i == 13 || i == 17)) || | |
| (j == 15 && i > 17 && i < SEEX * 2 - 1) || | |
| (j == 17 && i > 0 && i < 17) || | |
| (j == 20)) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else if (((i == 0 || i == SEEX * 2 - 1) && j > 7 && j < 20) || | |
| ((i == 5 || i == 10 || i == 16 || i == 19) && j > 7 && j < 12) || | |
| ((i == 5 || i == 9 || i == 13) && j > 14 && j < 17) || | |
| (i == 17 && j > 14 && j < 20)) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else if (j == 14 && i > 5 && i < 17 && i % 2 == 0) | |
| { | |
| ter(i, j) = t_bars; | |
| } | |
| else if ((i > 1 && i < 4 && j > 8 && j < 11) || | |
| (j == 17 && i > 17 && i < 21)) | |
| { | |
| ter(i, j) = t_counter; | |
| } | |
| else if ((i == 20 && j > 7 && j < 12) || (j == 8 && i > 19 && i < 23) || | |
| (j == 15 && i > 0 && i < 5)) | |
| { | |
| ter(i, j) = t_locker; | |
| } | |
| else if (j < 7) | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| else if (j > 20) | |
| { | |
| ter(i, j) = t_sidewalk; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| } | |
| } | |
| ter(17, 7) = t_door_locked; | |
| ter(18, 7) = t_door_locked; | |
| ter(rng(1, 4), 12) = t_door_c; | |
| ter(rng(6, 9), 12) = t_door_c; | |
| ter(rng(11, 15), 12) = t_door_c; | |
| ter(21, 12) = t_door_metal_locked; | |
| tmpcomp = add_computer(22, 13, "PolCom OS v1.47", 3); | |
| tmpcomp->add_option("Open Supply Room", COMPACT_OPEN, 3); | |
| tmpcomp->add_failure(COMPFAIL_SHUTDOWN); | |
| tmpcomp->add_failure(COMPFAIL_ALARM); | |
| tmpcomp->add_failure(COMPFAIL_MANHACKS); | |
| ter(7, 14) = t_door_c; | |
| ter(11, 14) = t_door_c; | |
| ter(15, 14) = t_door_c; | |
| ter(rng(20, 22), 15) = t_door_c; | |
| ter(2, 17) = t_door_metal_locked; | |
| tmpcomp = add_computer(22, 13, "PolCom OS v1.47", 3); | |
| tmpcomp->add_option("Open Evidence Locker", COMPACT_OPEN, 3); | |
| tmpcomp->add_failure(COMPFAIL_SHUTDOWN); | |
| tmpcomp->add_failure(COMPFAIL_ALARM); | |
| tmpcomp->add_failure(COMPFAIL_MANHACKS); | |
| ter(17, 18) = t_door_c; | |
| for (int i = 18; i < SEEX * 2 - 1; i++) | |
| { | |
| ter(i, 20) = t_window; | |
| } | |
| if (one_in(3)) | |
| { | |
| for (int j = 16; j < 20; j++) | |
| { | |
| ter(SEEX * 2 - 1, j) = t_window; | |
| } | |
| } | |
| rn = rng(18, 21); | |
| if (one_in(4)) | |
| { | |
| ter(rn , 20) = t_door_c; | |
| ter(rn + 1, 20) = t_door_c; | |
| } | |
| else | |
| { | |
| ter(rn , 20) = t_door_locked; | |
| ter(rn + 1, 20) = t_door_locked; | |
| } | |
| rn = rng(1, 5); | |
| ter(rn, 20) = t_window; | |
| ter(rn + 1, 20) = t_window; | |
| rn = rng(10, 14); | |
| ter(rn, 20) = t_window; | |
| ter(rn + 1, 20) = t_window; | |
| if (one_in(2)) | |
| { | |
| for (int i = 6; i < 10; i++) | |
| { | |
| ter(i, 8) = t_counter; | |
| } | |
| } | |
| if (one_in(3)) | |
| { | |
| for (int j = 8; j < 12; j++) | |
| { | |
| ter(6, j) = t_counter; | |
| } | |
| } | |
| if (one_in(3)) | |
| { | |
| for (int j = 8; j < 12; j++) | |
| { | |
| ter(9, j) = t_counter; | |
| } | |
| } | |
| place_items(mi_kitchen, 40, 6, 8, 9, 11, false, 0); | |
| place_items(mi_cop_weapons, 70, 20, 8, 22, 8, false, 0); | |
| place_items(mi_cop_weapons, 70, 20, 8, 20, 11, false, 0); | |
| place_items(mi_cop_evidence, 60, 1, 15, 4, 15, false, 0); | |
| if (terrain_type == ot_police_west) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_police_north) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_police_east) | |
| { | |
| rotate(3); | |
| } | |
| } | |
| break; | |
| case ot_bank_north: | |
| case ot_bank_east: | |
| case ot_bank_south: | |
| case ot_bank_west: | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| square(this, t_floor, 1, 1, 22, 22); | |
| line(this, t_wall_h, 1, 1, 22, 1); | |
| line(this, t_wall_h, 2, 6, 19, 6); | |
| line(this, t_wall_h, 2, 13, 18, 13); | |
| line(this, t_wall_h, 1, 22, 22, 22); | |
| line(this, t_wall_h, 9, 9, 18, 9); | |
| line(this, t_wall_v, 1, 2, 1, 21); | |
| line(this, t_wall_v, 22, 2, 22, 21); | |
| line(this, t_wall_v, 19, 9, 19, 21); | |
| line(this, t_wall_v, 13, 14, 13, 16); | |
| line(this, t_wall_v, 13, 19, 13, 21); | |
| line(this, t_wall_v, 8, 7, 8, 12); | |
| line(this, t_wall_metal_h, 3, 14, 11, 14); | |
| line(this, t_wall_metal_h, 3, 21, 11, 21); | |
| line(this, t_wall_metal_v, 2, 14, 2, 21); | |
| line(this, t_wall_metal_v, 12, 14, 12, 16); | |
| line(this, t_wall_metal_v, 12, 19, 12, 21); | |
| line(this, t_counter, 2, 4, 14, 4); | |
| ter(13, 17) = t_door_metal_locked; | |
| ter(13, 18) = t_door_metal_locked; | |
| tmpcomp = add_computer(14, 16, "First United Bank", 3); | |
| tmpcomp->add_option("Open Vault", COMPACT_OPEN, 3); | |
| tmpcomp->add_failure(COMPFAIL_SHUTDOWN); | |
| tmpcomp->add_failure(COMPFAIL_ALARM); | |
| // Front wall--glass or windows? | |
| if (!one_in(4)) | |
| { | |
| line(this, t_wall_glass_h_alarm, 2, 1, 21, 1); | |
| if (one_in(2)) | |
| { | |
| line(this, t_wall_glass_v_alarm, 1, 2, 1, 5); // Side wall for teller room | |
| } | |
| } | |
| else | |
| { | |
| if (one_in(4)) | |
| { | |
| line(this, t_wall_glass_v_alarm, 1, 2, 1, 5); // Side wall for teller room | |
| } | |
| rn = rng(3, 7); | |
| ter(rn , 1) = t_window_alarm; | |
| ter(rn + 1, 1) = t_window_alarm; | |
| rn = rng(13, 18); | |
| ter(rn , 1) = t_window_alarm; | |
| ter(rn + 1, 1) = t_window_alarm; | |
| } | |
| // Doors for offices | |
| ter(8, rng(7, 8)) = t_door_c; | |
| ter(rng(10, 17), 9) = t_door_c; | |
| ter(19, rng(15, 20)) = t_door_c; | |
| // Side and back windows | |
| ter(1, rng(7, 12)) = t_window_alarm; | |
| ter(1, rng(7, 12)) = t_window_alarm; | |
| ter(rng(14, 18), 22) = t_window_alarm; | |
| if (one_in(2)) | |
| { | |
| ter(rng(14, 18), 22) = t_window_alarm; | |
| } | |
| if (one_in(10)) | |
| { | |
| line(this, t_wall_glass_v, 22, 2, 22, 21); // Right side is glass wall! | |
| } | |
| else | |
| { | |
| rn = rng(7, 12); | |
| ter(22, rn) = t_window_alarm; | |
| ter(22, rn + 1) = t_window_alarm; | |
| rn = rng(13, 19); | |
| ter(22, rn) = t_window_alarm; | |
| ter(22, rn + 1) = t_window_alarm; | |
| } | |
| // Finally, place the front doors. | |
| if (one_in(4)) // 1 in 4 are unlocked | |
| { | |
| ter(10, 1) = t_door_c; | |
| ter(11, 1) = t_door_c; | |
| } | |
| else if (one_in(4)) // 1 in 4 locked ones are un-alarmed | |
| { | |
| ter(10, 1) = t_door_locked; | |
| ter(11, 1) = t_door_locked; | |
| } | |
| else | |
| { | |
| ter(10, 1) = t_door_locked_alarm; | |
| ter(11, 1) = t_door_locked_alarm; | |
| } | |
| place_items(mi_office, 60, 2, 7, 7, 12, false, 0); | |
| place_items(mi_office, 60, 9, 10, 18, 12, false, 0); | |
| place_items(mi_office, 70, 14, 14, 18, 21, false, 0); | |
| place_items(mi_vault, 45, 3, 15, 11, 20, false, 0); | |
| if (terrain_type == ot_bank_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_bank_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_bank_west) | |
| { | |
| rotate(3); | |
| } | |
| } | |
| break; | |
| case ot_bar_north: | |
| case ot_bar_east: | |
| case ot_bar_south: | |
| case ot_bar_west: | |
| { | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_pavement; | |
| } | |
| } | |
| square(this, t_floor, 2, 2, 21, 15); | |
| square(this, t_floor, 18, 17, 21, 18); | |
| // Main walls | |
| line(this, t_wall_h, 2, 1, 21, 1); | |
| line(this, t_wall_h, 2, 16, 21, 16); | |
| line(this, t_wall_h, 18, 19, 21, 19); | |
| line(this, t_wall_v, 1, 1, 1, 16); | |
| line(this, t_wall_v, 22, 1, 22, 19); | |
| line(this, t_wall_v, 17, 18, 17, 19); | |
| // Main bar counter | |
| line(this, t_counter, 19, 3, 19, 10); | |
| line(this, t_counter, 20, 3, 21, 3); | |
| ter(20, 10) = t_counter; | |
| // Back room counter | |
| line(this, t_counter, 18, 18, 21, 18); | |
| // Tables | |
| square(this, t_table, 4, 3, 5, 4); | |
| square(this, t_table, 9, 3, 10, 4); | |
| square(this, t_table, 14, 3, 15, 4); | |
| square(this, t_table, 4, 8, 5, 9); | |
| square(this, t_table, 9, 8, 10, 9); | |
| square(this, t_table, 14, 8, 15, 9); | |
| // Pool tables | |
| square(this, t_pool_table, 4, 13, 8, 14); | |
| place_items(mi_pool_table, 50, 4, 13, 8, 14, false, 0); | |
| square(this, t_pool_table, 13, 13, 17, 14); | |
| place_items(mi_pool_table, 50, 13, 13, 17, 14, false, 0); | |
| // 1 in 4 chance to have glass walls in front | |
| if (one_in(4)) | |
| { | |
| line(this, t_wall_glass_h, 3, 1, 5, 1); | |
| line(this, t_wall_glass_h, 7, 1, 9, 1); | |
| line(this, t_wall_glass_h, 14, 1, 16, 1); | |
| line(this, t_wall_glass_h, 18, 1, 20, 1); | |
| line(this, t_wall_glass_v, 1, 3, 1, 5); | |
| line(this, t_wall_glass_v, 1, 7, 1, 9); | |
| line(this, t_wall_glass_v, 1, 11, 1, 13); | |
| } | |
| else | |
| { | |
| ter(3, 1) = t_window; | |
| ter(5, 1) = t_window; | |
| ter(7, 1) = t_window; | |
| ter(16, 1) = t_window; | |
| ter(18, 1) = t_window; | |
| ter(20, 1) = t_window; | |
| ter(1, 6) = t_window; | |
| ter(1, 11) = t_window; | |
| } | |
| // Fridges and closets | |
| ter(21, 4) = t_fridge; | |
| line(this, t_rack, 21, 5, 21, 8); | |
| ter(21, 17) = t_fridge; // Back room fridge | |
| // Door placement | |
| ter(11, 1) = t_door_c; | |
| ter(12, 1) = t_door_c; | |
| ter(20, 16) = t_door_locked; | |
| ter(17, 17) = t_door_locked; | |
| // Item placement | |
| place_items(mi_snacks, 30, 19, 3, 19, 10, false, 0); | |
| place_items(mi_snacks, 50, 18, 18, 21, 18, false, 0); | |
| place_items(mi_fridgesnacks, 60, 21, 4, 21, 4, false, 0); | |
| place_items(mi_fridgesnacks, 60, 21, 17, 21, 17, false, 0); | |
| place_items(mi_alcohol, 70, 21, 5, 21, 8, false, 0); | |
| place_items(mi_trash, 15, 2, 17, 16, 19, true, 0); | |
| if (terrain_type == ot_bar_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_bar_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_bar_west) | |
| { | |
| rotate(3); | |
| } | |
| } | |
| break; | |
| case ot_pawn_north: | |
| case ot_pawn_east: | |
| case ot_pawn_south: | |
| case ot_pawn_west: | |
| // Init to plain grass/dirt | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| tw = rng(0, 10); | |
| bw = SEEY * 2 - rng(1, 2) - rng(0, 1) * rng(0, 1); | |
| lw = rng(0, 4); | |
| rw = SEEX * 2 - rng(1, 5); | |
| if (tw >= 6) // Big enough for its own parking lot | |
| { | |
| square(this, t_pavement, 0, 0, SEEX * 2 - 1, tw - 1); | |
| for (int i = rng(0, 1); i < SEEX * 2; i += 4) | |
| { | |
| line(this, t_pavement_y, i, 1, i, tw - 1); | |
| } | |
| } | |
| // Floor and walls | |
| square(this, t_floor, lw, tw, rw, bw); | |
| line(this, t_wall_h, lw, tw, rw, tw); | |
| line(this, t_wall_h, lw, bw, rw, bw); | |
| line(this, t_wall_v, lw, tw + 1, lw, bw - 1); | |
| line(this, t_wall_v, rw, tw + 1, rw, bw - 1); | |
| // Doors and windows--almost certainly alarmed | |
| if (one_in(15)) | |
| { | |
| line(this, t_window, lw + 2, tw, lw + 5, tw); | |
| line(this, t_window, rw - 5, tw, rw - 2, tw); | |
| line(this, t_door_locked, SEEX, tw, SEEX + 1, tw); | |
| } | |
| else | |
| { | |
| line(this, t_window_alarm, lw + 2, tw, lw + 5, tw); | |
| line(this, t_window_alarm, rw - 5, tw, rw - 2, tw); | |
| line(this, t_door_locked_alarm, SEEX, tw, SEEX + 1, tw); | |
| } | |
| // Some display racks by the left and right walls | |
| line(this, t_rack, lw + 1, tw + 1, lw + 1, bw - 1); | |
| place_items(mi_pawn, 86, lw + 1, tw + 1, lw + 1, bw - 1, false, 0); | |
| line(this, t_rack, rw - 1, tw + 1, rw - 1, bw - 1); | |
| place_items(mi_pawn, 86, rw - 1, tw + 1, rw - 1, bw - 1, false, 0); | |
| // Some display counters | |
| line(this, t_counter, lw + 4, tw + 2, lw + 4, bw - 3); | |
| place_items(mi_pawn, 80, lw + 4, tw + 2, lw + 4, bw - 3, false, 0); | |
| line(this, t_counter, rw - 4, tw + 2, rw - 4, bw - 3); | |
| place_items(mi_pawn, 80, rw - 4, tw + 2, rw - 4, bw - 3, false, 0); | |
| // More display counters, if there's room for them | |
| if (rw - lw >= 18 && one_in(rw - lw - 17)) | |
| { | |
| for (int j = tw + rng(3, 5); j <= bw - 3; j += 3) | |
| { | |
| line(this, t_counter, lw + 6, j, rw - 6, j); | |
| place_items(mi_pawn, 75, lw + 6, j, rw - 6, j, false, 0); | |
| } | |
| } | |
| // Finally, place an office sometimes | |
| if (!one_in(5)) | |
| { | |
| if (one_in(2)) // Office on the left side | |
| { | |
| int office_top = bw - rng(3, 5), office_right = lw + rng(4, 7); | |
| // Clear out any items in that area! And reset to floor. | |
| for (int i = lw + 1; i <= office_right; i++) | |
| { | |
| for (int j = office_top; j <= bw - 1; j++) | |
| { | |
| i_clear(i, j); | |
| ter(i, j) = t_floor; | |
| } | |
| } | |
| line(this, t_wall_h, lw + 1, office_top, office_right, office_top); | |
| line(this, t_wall_v, office_right, office_top + 1, office_right, bw - 1); | |
| ter(office_right, rng(office_top + 1, bw - 1)) = t_door_locked; | |
| if (one_in(4)) // Back door | |
| { | |
| ter(rng(lw + 1, office_right - 1), bw) = t_door_locked_alarm; | |
| } | |
| // Finally, add some stuff in there | |
| place_items(mi_office, 70, lw + 1, office_top + 1, office_right - 1, bw - 1, | |
| false, 0); | |
| place_items(mi_homeguns, 50, lw + 1, office_top + 1, office_right - 1, | |
| bw - 1, false, 0); | |
| place_items(mi_harddrugs, 20, lw + 1, office_top + 1, office_right - 1, | |
| bw - 1, false, 0); | |
| } | |
| else // Office on the right side | |
| { | |
| int office_top = bw - rng(3, 5), office_left = rw - rng(4, 7); | |
| for (int i = office_left; i <= rw - 1; i++) | |
| { | |
| for (int j = office_top; j <= bw - 1; j++) | |
| { | |
| i_clear(i, j); | |
| ter(i, j) = t_floor; | |
| } | |
| } | |
| line(this, t_wall_h, office_left, office_top, rw - 1, office_top); | |
| line(this, t_wall_v, office_left, office_top + 1, office_left, bw - 1); | |
| ter(office_left, rng(office_top + 1, bw - 1)) = t_door_locked; | |
| if (one_in(4)) // Back door | |
| { | |
| ter(rng(office_left + 1, rw - 1), bw) = t_door_locked_alarm; | |
| } | |
| place_items(mi_office, 70, office_left + 1, office_top + 1, rw - 1, bw - 1, | |
| false, 0); | |
| place_items(mi_homeguns, 50, office_left + 1, office_top + 1, rw - 1, | |
| bw - 1, false, 0); | |
| place_items(mi_harddrugs, 20, office_left + 1, office_top + 1, rw - 1, | |
| bw - 1, false, 0); | |
| } | |
| } | |
| if (terrain_type == ot_pawn_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_pawn_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_pawn_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_mil_surplus_north: | |
| case ot_mil_surplus_east: | |
| case ot_mil_surplus_south: | |
| case ot_mil_surplus_west: | |
| // Init to plain grass/dirt | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| } | |
| lw = rng(0, 2); | |
| rw = SEEX * 2 - rng(1, 3); | |
| tw = rng(0, 4); | |
| bw = SEEY * 2 - rng(3, 8); | |
| square(this, t_floor, lw, tw, rw, bw); | |
| line(this, t_wall_h, lw, tw, rw, tw); | |
| line(this, t_wall_h, lw, bw, rw, bw); | |
| line(this, t_wall_v, lw, tw + 1, lw, bw - 1); | |
| line(this, t_wall_v, rw, tw + 1, rw, bw - 1); | |
| rn = rng(4, 7); | |
| line(this, t_window, lw + 2, tw, lw + rn, tw); | |
| line(this, t_window, rw - rn, tw, rw - 2, tw); | |
| line(this, t_door_c, SEEX, tw, SEEX + 1, tw); | |
| if (one_in(2)) // counter on left | |
| { | |
| line(this, t_counter, lw + 2, tw + 1, lw + 2, tw + rng(3, 4)); | |
| } | |
| else // counter on right | |
| { | |
| line(this, t_counter, rw - 2, tw + 1, rw - 2, tw + rng(3, 4)); | |
| } | |
| for (int i = lw + 1; i <= SEEX; i += 2) | |
| { | |
| line(this, t_rack, i, tw + 5, i, bw - 2); | |
| items_location loc; | |
| if (one_in(3)) | |
| { | |
| loc = mi_mil_armor; | |
| } | |
| else if (one_in(3)) | |
| { | |
| loc = mi_mil_surplus; | |
| } | |
| else | |
| { | |
| loc = mi_mil_food_nodrugs; | |
| } | |
| place_items(loc, 70, i, tw + 5, i, bw - 2, false, 0); | |
| } | |
| for (int i = rw - 1; i >= SEEX + 1; i -= 2) | |
| { | |
| line(this, t_rack, i, tw + 5, i, bw - 2); | |
| items_location loc; | |
| if (one_in(3)) | |
| { | |
| loc = mi_mil_armor; | |
| } | |
| else if (one_in(3)) | |
| { | |
| loc = mi_mil_surplus; | |
| } | |
| else | |
| { | |
| loc = mi_mil_food_nodrugs; | |
| } | |
| place_items(loc, 70, i, tw + 5, i, bw - 2, false, 0); | |
| } | |
| if (terrain_type == ot_mil_surplus_east) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_mil_surplus_south) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_mil_surplus_west) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_megastore_entrance: | |
| { | |
| square(this, t_floor, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1); | |
| // Construct facing north; below, we'll rotate to face road | |
| line(this, t_wall_glass_h, 0, 0, SEEX * 2 - 1, 0); | |
| ter(SEEX, 0) = t_door_glass_c; | |
| ter(SEEX + 1, 0) = t_door_glass_c; | |
| // Long checkout lanes | |
| for (int x = 2; x <= 18; x += 4) | |
| { | |
| line(this, t_counter, x, 4, x, 14); | |
| line(this, t_rack, x + 3, 4, x + 3, 14); | |
| place_items(mi_snacks, 80, x + 3, 4, x + 3, 14, false, 0); | |
| place_items(mi_magazines, 70, x + 3, 4, x + 3, 14, false, 0); | |
| } | |
| for (int i = 0; i < 10; i++) | |
| { | |
| int x = rng(0, SEEX * 2 - 1), y = rng(0, SEEY * 2 - 1); | |
| if (ter(x, y) == t_floor) | |
| { | |
| add_spawn(mon_zombie, 1, x, y); | |
| } | |
| } | |
| // Finally, figure out where the road is; contruct our entrance facing that. | |
| std::vector<direction> faces_road; | |
| if (t_east >= ot_road_null && t_east <= ot_bridge_ew) | |
| { | |
| rotate(1); | |
| } | |
| if (t_south >= ot_road_null && t_south <= ot_bridge_ew) | |
| { | |
| rotate(2); | |
| } | |
| if (t_west >= ot_road_null && t_west <= ot_bridge_ew) | |
| { | |
| rotate(3); | |
| } | |
| } | |
| break; | |
| case ot_megastore: | |
| square(this, t_floor, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1); | |
| // Randomly pick contents | |
| switch (rng(1, 5)) | |
| { | |
| case 1: // Groceries | |
| { | |
| bool fridge = false; | |
| for (int x = rng(2, 3); x < SEEX * 2 - 1; x += 3) | |
| { | |
| for (int y = 2; y <= SEEY; y += SEEY - 2) | |
| { | |
| if (one_in(3)) | |
| { | |
| fridge = !fridge; | |
| } | |
| if (fridge) | |
| { | |
| line(this, t_glass_fridge, x, y, x, y + SEEY - 4); | |
| if (one_in(3)) | |
| { | |
| place_items(mi_fridgesnacks, 80, x, y, x, y + SEEY - 4, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_fridge, 70, x, y, x, y + SEEY - 4, false, 0); | |
| } | |
| } | |
| else | |
| { | |
| line(this, t_rack, x, y, x, y + SEEY - 4); | |
| if (one_in(3)) | |
| { | |
| place_items(mi_cannedfood, 78, x, y, x, y + SEEY - 4, false, 0); | |
| } | |
| else if (one_in(2)) | |
| { | |
| place_items(mi_pasta, 82, x, y, x, y + SEEY - 4, false, 0); | |
| } | |
| else if (one_in(2)) | |
| { | |
| place_items(mi_produce, 65, x, y, x, y + SEEY - 4, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_snacks, 72, x, y, x, y + SEEY - 4, false, 0); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| case 2: // Hardware | |
| for (int x = 2; x <= 22; x += 4) | |
| { | |
| line(this, t_rack, x, 4, x, SEEY * 2 - 5); | |
| if (one_in(3)) | |
| { | |
| place_items(mi_tools, 70, x, 4, x, SEEY * 2 - 5, false, 0); | |
| } | |
| else if (one_in(2)) | |
| { | |
| place_items(mi_bigtools, 70, x, 4, x, SEEY * 2 - 5, false, 0); | |
| } | |
| else if (one_in(3)) | |
| { | |
| place_items(mi_hardware, 70, x, 4, x, SEEY * 2 - 5, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_mischw, 70, x, 4, x, SEEY * 2 - 5, false, 0); | |
| } | |
| } | |
| break; | |
| case 3: // Clothing | |
| for (int x = 2; x < SEEX * 2; x += 6) | |
| { | |
| for (int y = 3; y <= 9; y += 6) | |
| { | |
| square(this, t_rack, x, y, x + 1, y + 1); | |
| if (one_in(2)) | |
| { | |
| place_items(mi_shirts, 75, x, y, x + 1, y + 1, false, 0); | |
| } | |
| else if (one_in(2)) | |
| { | |
| place_items(mi_pants, 72, x, y, x + 1, y + 1, false, 0); | |
| } | |
| else if (one_in(2)) | |
| { | |
| place_items(mi_jackets, 65, x, y, x + 1, y + 1, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_winter, 62, x, y, x + 1, y + 1, false, 0); | |
| } | |
| } | |
| } | |
| for (int y = 13; y <= SEEY * 2 - 2; y += 3) | |
| { | |
| line(this, t_rack, 2, y, SEEX * 2 - 3, y); | |
| if (one_in(3)) | |
| { | |
| place_items(mi_shirts, 75, 2, y, SEEX * 2 - 3, y, false, 0); | |
| } | |
| else if (one_in(2)) | |
| { | |
| place_items(mi_shoes, 75, 2, y, SEEX * 2 - 3, y, false, 0); | |
| } | |
| else if (one_in(2)) | |
| { | |
| place_items(mi_bags, 75, 2, y, SEEX * 2 - 3, y, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_allclothes, 75, 2, y, SEEX * 2 - 3, y, false, 0); | |
| } | |
| } | |
| break; | |
| case 4: // Cleaning and soft drugs and novels and junk | |
| for (int x = rng(2, 3); x < SEEX * 2 - 1; x += 3) | |
| { | |
| for (int y = 2; y <= SEEY; y += SEEY - 2) | |
| { | |
| line(this, t_rack, x, y, x, y + SEEY - 4); | |
| if (one_in(3)) | |
| { | |
| place_items(mi_cleaning, 78, x, y, x, y + SEEY - 4, false, 0); | |
| } | |
| else if (one_in(2)) | |
| { | |
| place_items(mi_softdrugs, 72, x, y, x, y + SEEY - 4, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_novels, 84, x, y, x, y + SEEY - 4, false, 0); | |
| } | |
| } | |
| } | |
| break; | |
| case 5: // Sporting goods | |
| for (int x = rng(2, 3); x < SEEX * 2 - 1; x += 3) | |
| { | |
| for (int y = 2; y <= SEEY; y += SEEY - 2) | |
| { | |
| line(this, t_rack, x, y, x, y + SEEY - 4); | |
| if (one_in(2)) | |
| { | |
| place_items(mi_sports, 72, x, y, x, y + SEEY - 4, false, 0); | |
| } | |
| else if (one_in(10)) | |
| { | |
| place_items(mi_rifles, 20, x, y, x, y + SEEY - 4, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_camping, 68, x, y, x, y + SEEY - 4, false, 0); | |
| } | |
| } | |
| } | |
| break; | |
| } | |
| // Add some spawns | |
| for (int i = 0; i < 15; i++) | |
| { | |
| int x = rng(0, SEEX * 2 - 1), y = rng(0, SEEY * 2 - 1); | |
| if (ter(x, y) == t_floor) | |
| { | |
| add_spawn(mon_zombie, 1, x, y); | |
| } | |
| } | |
| // Rotate randomly... | |
| rotate(rng(0, 3)); | |
| // ... then place walls as needed. | |
| if (t_north != ot_megastore_entrance && t_north != ot_megastore) | |
| { | |
| line(this, t_wall_h, 0, 0, SEEX * 2 - 1, 0); | |
| } | |
| if (t_east != ot_megastore_entrance && t_east != ot_megastore) | |
| { | |
| line(this, t_wall_v, SEEX * 2 - 1, 0, SEEX * 2 - 1, SEEY * 2 - 1); | |
| } | |
| if (t_south != ot_megastore_entrance && t_south != ot_megastore) | |
| { | |
| line(this, t_wall_h, 0, SEEY * 2 - 1, SEEX * 2 - 1, SEEY * 2 - 1); | |
| } | |
| if (t_west != ot_megastore_entrance && t_west != ot_megastore) | |
| { | |
| line(this, t_wall_v, 0, 0, 0, SEEY * 2 - 1); | |
| } | |
| break; | |
| case ot_hospital_entrance: | |
| square(this, t_pavement, 0, 0, SEEX * 2 - 1, 5); | |
| square(this, t_floor, 0, 6, SEEX * 2 - 1, SEEY * 2 - 1); | |
| // Ambulance parking place | |
| line(this, t_pavement_y, 5, 1, 22, 1); | |
| line(this, t_pavement_y, 5, 2, 5, 5); | |
| line(this, t_pavement_y, 22, 2, 22, 5); | |
| // Top wall | |
| line(this, t_wall_h, 0, 6, 6, 6); | |
| line(this, t_door_glass_c, 3, 6, 4, 6); | |
| line(this, t_wall_glass_h, 7, 6, 19, 6); | |
| line(this, t_wall_h, 20, 6, SEEX * 2 - 1, 6); | |
| // Left wall | |
| line(this, t_wall_v, 0, 0, 0, SEEY * 2 - 1); | |
| line(this, t_floor, 0, 11, 0, 12); | |
| // Waiting area | |
| line(this, t_bench, 8, 7, 11, 7); | |
| line(this, t_bench, 13, 7, 17, 7); | |
| line(this, t_bench, 20, 7, 22, 7); | |
| line(this, t_bench, 22, 8, 22, 10); | |
| place_items(mi_magazines, 70, 8, 7, 22, 10, false, 0); | |
| // Reception and examination rooms | |
| line(this, t_counter, 8, 13, 9, 13); | |
| line(this, t_wall_h, 10, 13, SEEX * 2 - 1, 13); | |
| line(this, t_door_c, 15, 13, 16, 13); | |
| line(this, t_wall_h, 8, 17, 13, 17); | |
| line(this, t_wall_h, 18, 17, 22, 17); | |
| line(this, t_wall_h, 8, 20, 13, 20); | |
| line(this, t_wall_h, 18, 20, 22, 20); | |
| line(this, t_wall_v, 7, 13, 7, 22); | |
| line(this, t_wall_v, 14, 15, 14, 20); | |
| line(this, t_wall_v, 17, 14, 17, 22); | |
| line(this, t_bed, 8, 19, 9, 19); | |
| line(this, t_bed, 21, 19, 22, 19); | |
| line(this, t_bed, 21, 22, 22, 22); | |
| line(this, t_rack, 18, 14, 22, 14); | |
| place_items(mi_harddrugs, 80, 18, 14, 22, 14, false, 0); | |
| line(this, t_rack, 8, 21, 8, 22); | |
| place_items(mi_softdrugs, 70, 8, 21, 8, 22, false, 0); | |
| ter(14, rng(18, 19)) = t_door_c; | |
| ter(17, rng(15, 16)) = t_door_locked; // Hard drugs room is locked | |
| ter(17, rng(18, 19)) = t_door_c; | |
| ter(17, rng(21, 22)) = t_door_c; | |
| // ER and bottom wall | |
| line(this, t_wall_h, 0, 16, 6, 16); | |
| line(this, t_door_c, 3, 16, 4, 16); | |
| square(this, t_bed, 3, 19, 4, 20); | |
| line(this, t_counter, 1, 22, 6, 22); | |
| place_items(mi_surgery, 78, 1, 22, 6, 22, false, 0); | |
| line(this, t_wall_h, 1, 23, 22, 23); | |
| line(this, t_floor, 11, 23, 12, 23); | |
| // Right side wall (needed sometimes!) | |
| line(this, t_wall_v, 23, 0, 23, 10); | |
| line(this, t_wall_v, 23, 13, 23, 23); | |
| /* | |
| // Generate bodies / zombies | |
| rn = rng(10, 15); | |
| for (int i = 0; i < rn; i++) { | |
| item body; | |
| body.make_corpse(g->itypes[itm_corpse], g->mtypes[mon_null], g->turn); | |
| int zx = rng(0, SEEX * 2 - 1), zy = rng(0, SEEY * 2 - 1); | |
| if (ter(zx, zy) == t_bed || one_in(3)) | |
| add_item(zx, zy, body); | |
| else if (move_cost(zx, zy) > 0) { | |
| mon_id zom = mon_zombie; | |
| if (one_in(6)) | |
| zom = mon_zombie_spitter; | |
| else if (!one_in(3)) | |
| zom = mon_boomer; | |
| add_spawn(zom, 1, zx, zy); | |
| } | |
| } | |
| */ | |
| // Rotate to face the road | |
| if (t_east >= ot_road_null && t_east <= ot_bridge_ew) | |
| { | |
| rotate(1); | |
| } | |
| if (t_south >= ot_road_null && t_south <= ot_bridge_ew) | |
| { | |
| rotate(2); | |
| } | |
| if (t_west >= ot_road_null && t_west <= ot_bridge_ew) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_hospital: | |
| square(this, t_floor, 0, 0, 23, 23); | |
| // We always have walls on the left and bottom | |
| line(this, t_wall_v, 0, 0, 0, 22); | |
| line(this, t_wall_h, 0, 23, 23, 23); | |
| // These walls contain doors if they lead to more hospital | |
| if (t_west == ot_hospital_entrance || t_west == ot_hospital) | |
| { | |
| line(this, t_door_c, 0, 11, 0, 12); | |
| } | |
| if (t_south == ot_hospital_entrance || t_south == ot_hospital) | |
| { | |
| line(this, t_door_c, 11, 23, 12, 23); | |
| } | |
| if ((t_north == ot_hospital_entrance || t_north == ot_hospital) && | |
| (t_east == ot_hospital_entrance || t_east == ot_hospital) && | |
| (t_south == ot_hospital_entrance || t_south == ot_hospital) && | |
| (t_west == ot_hospital_entrance || t_west == ot_hospital)) | |
| { | |
| // We're in the center; center is always blood lab | |
| // Large lab | |
| line(this, t_wall_h, 1, 2, 21, 2); | |
| line(this, t_wall_h, 1, 10, 21, 10); | |
| line(this, t_wall_v, 21, 3, 21, 9); | |
| line(this, t_counter, 2, 3, 2, 9); | |
| place_items(mi_hospital_lab, 70, 2, 3, 2, 9, false, 0); | |
| square(this, t_counter, 5, 4, 6, 8); | |
| place_items(mi_hospital_lab, 74, 5, 4, 6, 8, false, 0); | |
| square(this, t_counter, 10, 4, 11, 8); | |
| place_items(mi_hospital_lab, 74, 10, 4, 11, 8, false, 0); | |
| square(this, t_counter, 15, 4, 16, 8); | |
| place_items(mi_hospital_lab, 74, 15, 4, 16, 8, false, 0); | |
| ter(rng(3, 18), 2) = t_door_c; | |
| ter(rng(3, 18), 10) = t_door_c; | |
| if (one_in(4)) // Door on the right side | |
| { | |
| ter(21, rng(4, 8)) = t_door_c; | |
| } | |
| else // Counter on the right side | |
| { | |
| line(this, t_counter, 20, 3, 20, 9); | |
| place_items(mi_hospital_lab, 70, 20, 3, 20, 9, false, 0); | |
| } | |
| // Blood testing facility | |
| line(this, t_wall_h, 1, 13, 10, 13); | |
| line(this, t_wall_v, 10, 14, 10, 22); | |
| rn = rng(1, 3); | |
| if (rn == 1 || rn == 3) | |
| { | |
| ter(rng(3, 8), 13) = t_door_c; | |
| } | |
| if (rn == 2 || rn == 3) | |
| { | |
| ter(10, rng(15, 21)) = t_door_c; | |
| } | |
| line(this, t_counter, 2, 14, 2, 22); | |
| place_items(mi_hospital_lab, 60, 2, 14, 2, 22, false, 0); | |
| square(this, t_counter, 4, 17, 6, 19); | |
| ter(4, 18) = t_centrifuge; | |
| line(this, t_floor, 5, 18, 6, rng(17, 19)); // Clear path to console | |
| tmpcomp = add_computer(5, 18, "Centrifuge", 0); | |
| tmpcomp->add_option("Analyze blood", COMPACT_BLOOD_ANAL, 4); | |
| tmpcomp->add_failure(COMPFAIL_DESTROY_BLOOD); | |
| // Sample storage | |
| line(this, t_wall_h, 13, 13, 23, 13); | |
| line(this, t_wall_v, 13, 14, 13, 23); | |
| rn = rng(1, 3); | |
| if (rn == 1 || rn == 3) | |
| { | |
| ter(rng(14, 22), 13) = t_door_c; | |
| } | |
| if (rn == 2 || rn == 3) | |
| { | |
| ter(13, rng(14, 21)) = t_door_c; | |
| } | |
| square(this, t_rack, 16, 16, 21, 17); | |
| place_items(mi_hospital_samples, 68, 16, 16, 21, 17, false, 0); | |
| square(this, t_rack, 16, 19, 21, 20); | |
| place_items(mi_hospital_samples, 68, 16, 19, 21, 20, false, 0); | |
| line(this, t_rack, 14, 22, 23, 22); | |
| place_items(mi_hospital_samples, 62, 14, 22, 23, 22, false, 0); | |
| } | |
| else // We're NOT in the center; a random hospital type! | |
| { | |
| switch (rng(1, 4)) // What type? | |
| { | |
| case 1: // Dorms | |
| // Upper left rooms | |
| line(this, t_wall_h, 1, 5, 9, 5); | |
| for (int i = 1; i <= 7; i += 3) | |
| { | |
| line(this, t_bed, i, 1, i, 2); | |
| line(this, t_wall_v, i + 2, 0, i + 2, 4); | |
| ter(rng(i, i + 1), 5) = t_door_c; | |
| } | |
| // Upper right rooms | |
| line(this, t_wall_h, 14, 5, 23, 5); | |
| line(this, t_wall_v, 14, 0, 14, 4); | |
| line(this, t_bed, 15, 1, 15, 2); | |
| ter(rng(15, 16), 5) = t_door_c; | |
| line(this, t_wall_v, 17, 0, 17, 4); | |
| line(this, t_bed, 18, 1, 18, 2); | |
| ter(rng(18, 19), 5) = t_door_c; | |
| line(this, t_wall_v, 20, 0, 20, 4); | |
| line(this, t_bed, 21, 1, 21, 2); | |
| ter(rng(21, 22), 5) = t_door_c; | |
| // Waiting area | |
| for (int i = 1; i <= 9; i += 4) | |
| { | |
| line(this, t_bench, i, 7, i, 10); | |
| } | |
| line(this, t_table, 3, 8, 3, 9); | |
| place_items(mi_magazines, 50, 3, 8, 3, 9, false, 0); | |
| line(this, t_table, 7, 8, 7, 9); | |
| place_items(mi_magazines, 50, 7, 8, 7, 9, false, 0); | |
| // Middle right rooms | |
| line(this, t_wall_v, 14, 7, 14, 10); | |
| line(this, t_wall_h, 15, 7, 23, 7); | |
| line(this, t_wall_h, 15, 10, 23, 10); | |
| line(this, t_wall_v, 19, 8, 19, 9); | |
| line(this, t_bed, 18, 8, 18, 9); | |
| line(this, t_bed, 20, 8, 20, 9); | |
| if (one_in(3)) // Doors to north | |
| { | |
| ter(rng(15, 16), 7) = t_door_c; | |
| ter(rng(21, 22), 7) = t_door_c; | |
| } | |
| else // Doors to south | |
| { | |
| ter(rng(15, 16), 10) = t_door_c; | |
| ter(rng(21, 22), 10) = t_door_c; | |
| } | |
| line(this, t_wall_v, 14, 13, 14, 16); | |
| line(this, t_wall_h, 15, 13, 23, 13); | |
| line(this, t_wall_h, 15, 16, 23, 16); | |
| line(this, t_wall_v, 19, 14, 19, 15); | |
| line(this, t_bed, 18, 14, 18, 15); | |
| line(this, t_bed, 20, 14, 20, 15); | |
| if (one_in(3)) // Doors to south | |
| { | |
| ter(rng(15, 16), 16) = t_door_c; | |
| ter(rng(21, 22), 16) = t_door_c; | |
| } | |
| else // Doors to north | |
| { | |
| ter(rng(15, 16), 13) = t_door_c; | |
| ter(rng(21, 22), 13) = t_door_c; | |
| } | |
| // Lower left rooms | |
| line(this, t_wall_v, 5, 13, 5, 22); | |
| line(this, t_wall_h, 1, 13, 4, 13); | |
| line(this, t_bed, 1, 14, 1, 15); | |
| line(this, t_wall_h, 1, 17, 4, 17); | |
| line(this, t_bed, 1, 18, 1, 19); | |
| line(this, t_wall_h, 1, 20, 4, 20); | |
| line(this, t_bed, 1, 21, 1, 22); | |
| ter(5, rng(14, 16)) = t_door_c; | |
| ter(5, rng(18, 19)) = t_door_c; | |
| ter(5, rng(21, 22)) = t_door_c; | |
| line(this, t_wall_h, 7, 13, 10, 13); | |
| line(this, t_wall_v, 7, 14, 7, 22); | |
| line(this, t_wall_v, 10, 14, 10, 22); | |
| line(this, t_wall_h, 8, 18, 9, 18); | |
| line(this, t_bed, 8, 17, 9, 17); | |
| line(this, t_bed, 8, 22, 9, 22); | |
| if (one_in(3)) // Doors to west | |
| { | |
| ter(7, rng(14, 16)) = t_door_c; | |
| ter(7, rng(19, 21)) = t_door_c; | |
| } | |
| else // Doors to east | |
| { | |
| ter(10, rng(14, 16)) = t_door_c; | |
| ter(10, rng(19, 21)) = t_door_c; | |
| } | |
| // Lower-right rooms | |
| line(this, t_wall_h, 14, 18, 23, 18); | |
| for (int i = 14; i <= 20; i += 3) | |
| { | |
| line(this, t_wall_v, i, 19, i, 22); | |
| line(this, t_bed, i + 1, 21, i + 1, 22); | |
| ter(rng(i + 1, i + 2), 18) = t_door_c; | |
| } | |
| break; | |
| case 2: // Offices and cafeteria | |
| // Offices to north | |
| line(this, t_wall_v, 10, 0, 10, 8); | |
| line(this, t_wall_v, 13, 0, 13, 8); | |
| line(this, t_wall_h, 1, 5, 9, 5); | |
| line(this, t_wall_h, 14, 5, 23, 5); | |
| line(this, t_wall_h, 1, 9, 23, 9); | |
| line(this, t_door_c, 11, 9, 12, 9); | |
| line(this, t_table, 3, 3, 7, 3); | |
| line(this, t_table, 16, 3, 20, 3); | |
| line(this, t_table, 3, 8, 7, 8); | |
| line(this, t_table, 16, 8, 20, 8); | |
| ter(10, rng(2, 3)) = t_door_c; | |
| ter(13, rng(2, 3)) = t_door_c; | |
| ter(10, rng(6, 7)) = t_door_c; | |
| ter(13, rng(6, 7)) = t_door_c; | |
| place_items(mi_office, 70, 1, 1, 9, 3, false, 0); | |
| place_items(mi_office, 70, 14, 1, 22, 3, false, 0); | |
| place_items(mi_office, 70, 1, 5, 9, 8, false, 0); | |
| place_items(mi_office, 70, 14, 5, 22, 8, false, 0); | |
| // Cafeteria to south | |
| line(this, t_wall_h, 1, 14, 8, 14); | |
| line(this, t_wall_h, 15, 14, 23, 14); | |
| for (int i = 16; i <= 19; i += 3) | |
| { | |
| for (int j = 17; j <= 20; j += 3) | |
| { | |
| square(this, t_table, i, j, i + 1, j + 1); | |
| place_items(mi_snacks, 60, i, j, i + 1, j + 1, false, 0); | |
| place_items(mi_produce, 65, i, j, i + 1, j + 1, false, 0); | |
| } | |
| } | |
| for (int i = 3; i <= 6; i += 3) | |
| { | |
| for (int j = 17; j <= 20; j += 3) | |
| { | |
| square(this, t_table, i, j, i + 1, j + 1); | |
| place_items(mi_snacks, 60, i, j, i + 1, j + 1, false, 0); | |
| place_items(mi_produce, 65, i, j, i + 1, j + 1, false, 0); | |
| } | |
| } | |
| break; | |
| case 3: // Operating rooms | |
| // First, walls and doors; divide it into four big operating rooms | |
| line(this, t_wall_v, 10, 0, 10, 9); | |
| line(this, t_door_c, 10, 4, 10, 5); | |
| line(this, t_wall_v, 13, 0, 13, 9); | |
| line(this, t_door_c, 13, 4, 13, 5); | |
| line(this, t_wall_v, 10, 14, 10, 22); | |
| line(this, t_door_c, 10, 18, 10, 19); | |
| line(this, t_wall_v, 13, 14, 13, 22); | |
| line(this, t_door_c, 13, 18, 13, 19); | |
| // Horizontal walls/doors | |
| line(this, t_wall_h, 1, 10, 10, 10); | |
| line(this, t_door_c, 5, 10, 6, 10); | |
| line(this, t_wall_h, 13, 10, 23, 10); | |
| line(this, t_door_c, 18, 10, 19, 10); | |
| line(this, t_wall_h, 1, 13, 10, 13); | |
| line(this, t_door_c, 5, 13, 6, 13); | |
| line(this, t_wall_h, 13, 13, 23, 13); | |
| line(this, t_door_c, 18, 13, 19, 13); | |
| // Next, the contents of each operating room | |
| line(this, t_counter, 1, 0, 1, 9); | |
| place_items(mi_surgery, 70, 1, 1, 1, 9, false, 0); | |
| square(this, t_bed, 5, 4, 6, 5); | |
| line(this, t_counter, 1, 14, 1, 22); | |
| place_items(mi_surgery, 70, 1, 14, 1, 22, false, 0); | |
| square(this, t_bed, 5, 18, 6, 19); | |
| line(this, t_counter, 14, 6, 14, 9); | |
| place_items(mi_surgery, 60, 14, 6, 14, 9, false, 0); | |
| line(this, t_counter, 15, 9, 17, 9); | |
| place_items(mi_surgery, 60, 15, 9, 17, 9, false, 0); | |
| square(this, t_bed, 18, 4, 19, 5); | |
| line(this, t_counter, 14, 14, 14, 17); | |
| place_items(mi_surgery, 60, 14, 14, 14, 17, false, 0); | |
| line(this, t_counter, 15, 14, 17, 14); | |
| place_items(mi_surgery, 60, 15, 14, 17, 14, false, 0); | |
| square(this, t_bed, 18, 18, 19, 19); | |
| // computer to begin healing broken bones, | |
| tmpcomp = add_computer(16, 16, "Mr. Stem Cell", 3); | |
| tmpcomp->add_option("Stem Cell Treatment", COMPACT_STEMCELL_TREATMENT, 3); | |
| tmpcomp->add_failure(COMPFAIL_ALARM); | |
| break; | |
| case 4: // Storage | |
| // Soft drug storage | |
| line(this, t_wall_h, 3, 2, 12, 2); | |
| line(this, t_wall_h, 3, 10, 12, 10); | |
| line(this, t_wall_v, 3, 3, 3, 9); | |
| ter(3, 6) = t_door_c; | |
| line(this, t_rack, 4, 3, 11, 3); | |
| place_items(mi_softdrugs, 90, 4, 3, 11, 3, false, 0); | |
| line(this, t_rack, 4, 9, 11, 9); | |
| place_items(mi_softdrugs, 90, 4, 9, 11, 9, false, 0); | |
| line(this, t_rack, 6, 5, 10, 5); | |
| place_items(mi_softdrugs, 80, 6, 5, 10, 5, false, 0); | |
| line(this, t_rack, 6, 7, 10, 7); | |
| place_items(mi_softdrugs, 80, 6, 7, 10, 7, false, 0); | |
| // Hard drug storage | |
| line(this, t_wall_v, 13, 0, 13, 19); | |
| ter(13, 6) = t_door_locked; | |
| line(this, t_rack, 14, 0, 14, 4); | |
| place_items(mi_harddrugs, 78, 14, 1, 14, 4, false, 0); | |
| line(this, t_rack, 17, 0, 17, 7); | |
| place_items(mi_harddrugs, 85, 17, 0, 17, 7, false, 0); | |
| line(this, t_rack, 20, 0, 20, 7); | |
| place_items(mi_harddrugs, 85, 20, 0, 20, 7, false, 0); | |
| line(this, t_wall_h, 20, 10, 23, 10); | |
| line(this, t_rack, 16, 10, 19, 10); | |
| place_items(mi_harddrugs, 78, 16, 10, 19, 10, false, 0); | |
| line(this, t_rack, 16, 12, 19, 12); | |
| place_items(mi_harddrugs, 78, 16, 12, 19, 12, false, 0); | |
| line(this, t_wall_h, 14, 14, 19, 14); | |
| ter(rng(14, 15), 14) = t_door_locked; | |
| ter(rng(16, 18), 14) = t_bars; | |
| line(this, t_wall_v, 20, 11, 20, 19); | |
| line(this, t_wall_h, 13, 20, 20, 20); | |
| line(this, t_door_c, 16, 20, 17, 20); | |
| // Laundry room | |
| line(this, t_wall_h, 1, 13, 10, 13); | |
| ter(rng(3, 8), 13) = t_door_c; | |
| line(this, t_wall_v, 10, 14, 10, 22); | |
| ter(10, rng(16, 20)) = t_door_c; | |
| line(this, t_counter, 1, 14, 1, 22); | |
| place_items(mi_allclothes, 70, 1, 14, 1, 22, false, 0); | |
| for (int j = 15; j <= 21; j += 3) | |
| { | |
| line(this, t_rack, 4, j, 7, j); | |
| if (one_in(2)) | |
| { | |
| place_items(mi_cleaning, 92, 4, j, 7, j, false, 0); | |
| } | |
| else if (one_in(5)) | |
| { | |
| place_items(mi_cannedfood, 75, 4, j, 7, j, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_allclothes, 50, 4, j, 7, j, false, 0); | |
| } | |
| } | |
| break; | |
| } | |
| // We have walls to the north and east if they're not hospitals | |
| if (t_east != ot_hospital_entrance && t_east != ot_hospital) | |
| { | |
| line(this, t_wall_v, 23, 0, 23, 23); | |
| } | |
| if (t_north != ot_hospital_entrance && t_north != ot_hospital) | |
| { | |
| line(this, t_wall_h, 0, 0, 23, 0); | |
| } | |
| } | |
| // Generate bodies / zombies | |
| rn = rng(15, 20); | |
| for (int i = 0; i < rn; i++) | |
| { | |
| item body; | |
| body.make_corpse(g->itypes[itm_corpse], g->mtypes[mon_null], g->turn); | |
| int zx = rng(0, SEEX * 2 - 1), zy = rng(0, SEEY * 2 - 1); | |
| if (ter(zx, zy) == t_bed || one_in(3)) | |
| { | |
| add_item(zx, zy, body); | |
| } | |
| else if (move_cost(zx, zy) > 0) | |
| { | |
| mon_id zom = mon_zombie; | |
| if (one_in(6)) | |
| { | |
| zom = mon_zombie_spitter; | |
| } | |
| else if (!one_in(3)) | |
| { | |
| zom = mon_boomer; | |
| } | |
| add_spawn(zom, 1, zx, zy); | |
| } | |
| } | |
| break; | |
| case ot_mansion_entrance: | |
| { | |
| // Left wall | |
| line(this, t_wall_v, 0, 0, 0, SEEY * 2 - 2); | |
| line(this, t_door_c, 0, SEEY - 1, 0, SEEY); | |
| // Front wall | |
| line(this, t_wall_h, 1, 10, SEEX * 2 - 1, 10); | |
| line(this, t_door_locked, SEEX - 1, 10, SEEX, 10); | |
| int winx1 = rng(2, 4); | |
| int winx2 = rng(4, 6); | |
| line(this, t_window, winx1, 10, winx2, 10); | |
| line(this, t_window, SEEX * 2 - 1 - winx1, 10, SEEX * 2 - 1 - winx2, 10); | |
| winx1 = rng(7, 10); | |
| winx2 = rng(10, 11); | |
| line(this, t_window, winx1, 10, winx2, 10); | |
| line(this, t_window, SEEX * 2 - 1 - winx1, 10, SEEX * 2 - 1 - winx2, 10); | |
| line(this, t_door_c, SEEX - 1, 10, SEEX, 10); | |
| // Bottom wall | |
| line(this, t_wall_h, 0, SEEY * 2 - 1, SEEX * 2 - 1, SEEY * 2 - 1); | |
| line(this, t_door_c, SEEX - 1, SEEY * 2 - 1, SEEX, SEEY * 2 - 1); | |
| build_mansion_room(this, room_mansion_courtyard, 1, 0, SEEX * 2 - 1, 9); | |
| square(this, t_floor, 1, 11, SEEX * 2 - 1, SEEY * 2 - 2); | |
| build_mansion_room(this, room_mansion_entry, 1, 11, SEEX * 2 - 1, SEEY * 2 - 2); | |
| // Rotate to face the road | |
| if (t_east >= ot_road_null && t_east <= ot_bridge_ew) | |
| { | |
| rotate(1); | |
| } | |
| if (t_south >= ot_road_null && t_south <= ot_bridge_ew) | |
| { | |
| rotate(2); | |
| } | |
| if (t_west >= ot_road_null && t_west <= ot_bridge_ew) | |
| { | |
| rotate(3); | |
| } | |
| } | |
| break; | |
| case ot_mansion: | |
| // Start with floors all over | |
| square(this, t_floor, 1, 0, SEEX * 2 - 1, SEEY * 2 - 2); | |
| // We always have a left and bottom wall | |
| line(this, t_wall_v, 0, 0, 0, SEEY * 2 - 2); | |
| line(this, t_wall_h, 0, SEEY * 2 - 1, SEEX * 2 - 1, SEEY * 2 - 1); | |
| // tw and rw are the boundaries of the rooms inside... | |
| tw = 0; | |
| rw = SEEX * 2 - 1; | |
| // ...if we need outside walls, adjust tw & rw and build them | |
| // We build windows below. | |
| if (t_north != ot_mansion_entrance && t_north != ot_mansion) | |
| { | |
| tw = 1; | |
| line(this, t_wall_h, 0, 0, SEEX * 2 - 1, 0); | |
| } | |
| if (t_east != ot_mansion_entrance && t_east != ot_mansion) | |
| { | |
| rw = SEEX * 2 - 2; | |
| line(this, t_wall_v, SEEX * 2 - 1, 0, SEEX * 2 - 1, SEEX * 2 - 1); | |
| } | |
| // Now pick a random layout | |
| switch (rng(1, 4)) | |
| { | |
| case 1: // Just one. big. room. | |
| mansion_room(this, 1, tw, rw, SEEY * 2 - 2); | |
| if (t_west == ot_mansion_entrance || t_west == ot_mansion) | |
| { | |
| line(this, t_door_c, 0, SEEY - 1, 0, SEEY); | |
| } | |
| if (t_south == ot_mansion_entrance || t_south == ot_mansion) | |
| { | |
| line(this, t_door_c, SEEX - 1, SEEY * 2 - 1, SEEX, SEEY * 2 - 1); | |
| } | |
| break; | |
| case 2: // Wide hallway, two rooms. | |
| if (one_in(2)) // vertical hallway | |
| { | |
| line(this, t_wall_v, 9, tw, 9, SEEY * 2 - 2); | |
| line(this, t_wall_v, 14, tw, 14, SEEY * 2 - 2); | |
| line(this, t_floor, SEEX - 1, SEEY * 2 - 1, SEEX, SEEY * 2 - 1); | |
| line(this, t_door_c, 0, SEEY - 1, 0, SEEY); | |
| mansion_room(this, 1, tw, 8, SEEY * 2 - 2); | |
| mansion_room(this, 15, tw, rw, SEEY * 2 - 2); | |
| ter(9, rng(tw + 2, SEEX * 2 - 4)) = t_door_c; | |
| ter(14, rng(tw + 2, SEEX * 2 - 4)) = t_door_c; | |
| } | |
| else // horizontal hallway | |
| { | |
| line(this, t_wall_h, 1, 9, rw, 9); | |
| line(this, t_wall_h, 1, 14, rw, 14); | |
| line(this, t_door_c, SEEX - 1, SEEY * 2 - 1, SEEX, SEEY * 2 - 1); | |
| line(this, t_floor, 0, SEEY - 1, 0, SEEY); | |
| mansion_room(this, 1, tw, rw, 8); | |
| mansion_room(this, 1, 15, rw, SEEY * 2 - 2); | |
| ter(rng(3, rw - 2), 9) = t_door_c; | |
| ter(rng(3, rw - 2), 14) = t_door_c; | |
| } | |
| if (t_west == ot_mansion_entrance || t_west == ot_mansion) | |
| { | |
| line(this, t_door_c, 0, SEEY - 1, 0, SEEY); | |
| } | |
| if (t_south == ot_mansion_entrance || t_south == ot_mansion) | |
| { | |
| line(this, t_floor, SEEX - 1, SEEY * 2 - 1, SEEX, SEEY * 2 - 1); | |
| } | |
| break; | |
| case 3: // Four corners rooms | |
| line(this, t_wall_v, 10, tw, 10, 9); | |
| line(this, t_wall_v, 13, tw, 13, 9); | |
| line(this, t_wall_v, 10, 14, 10, SEEY * 2 - 2); | |
| line(this, t_wall_v, 13, 14, 13, SEEY * 2 - 2); | |
| line(this, t_wall_h, 1, 10, 10, 10); | |
| line(this, t_wall_h, 1, 13, 10, 13); | |
| line(this, t_wall_h, 13, 10, rw, 10); | |
| line(this, t_wall_h, 13, 13, rw, 13); | |
| // Doors | |
| if (one_in(2)) | |
| { | |
| ter(10, rng(tw + 1, 8)) = t_door_c; | |
| } | |
| else | |
| { | |
| ter(rng(2, 8), 10) = t_door_c; | |
| } | |
| if (one_in(2)) | |
| { | |
| ter(13, rng(tw + 1, 8)) = t_door_c; | |
| } | |
| else | |
| { | |
| ter(rng(15, rw - 1), 10) = t_door_c; | |
| } | |
| if (one_in(2)) | |
| { | |
| ter(10, rng(15, SEEY * 2 - 3)) = t_door_c; | |
| } | |
| else | |
| { | |
| ter(rng(2, 8), 13) = t_door_c; | |
| } | |
| if (one_in(2)) | |
| { | |
| ter(13, rng(15, SEEY * 2 - 3)) = t_door_c; | |
| } | |
| else | |
| { | |
| ter(rng(15, rw - 1), 13) = t_door_c; | |
| } | |
| mansion_room(this, 1, tw, 9, 9); | |
| mansion_room(this, 14, tw, rw, 9); | |
| mansion_room(this, 1, 14, 9, SEEY * 2 - 2); | |
| mansion_room(this, 14, 14, rw, SEEY * 2 - 2); | |
| if (t_west == ot_mansion_entrance || t_west == ot_mansion) | |
| { | |
| line(this, t_floor, 0, SEEY - 1, 0, SEEY); | |
| } | |
| if (t_south == ot_mansion_entrance || t_south == ot_mansion) | |
| { | |
| line(this, t_floor, SEEX - 1, SEEY * 2 - 1, SEEX, SEEY * 2 - 1); | |
| } | |
| break; | |
| case 4: // One large room in lower-left | |
| mw = rng(4, 10); | |
| cw = rng(13, 19); | |
| x = rng(5, 10); | |
| y = rng(13, 18); | |
| line(this, t_wall_h, 1, mw, cw, mw); | |
| ter(rng(x + 1, cw - 1), mw) = t_door_c; | |
| line(this, t_wall_v, cw, mw + 1, cw, SEEY * 2 - 2); | |
| ter(cw, rng(y + 2, SEEY * 2 - 3)) = t_door_c; | |
| mansion_room(this, 1, mw + 1, cw - 1, SEEY * 2 - 2); | |
| // And a couple small rooms in the UL LR corners | |
| line(this, t_wall_v, x, tw, x, mw - 1); | |
| mansion_room(this, 1, tw, x - 1, mw - 1); | |
| if (one_in(2)) | |
| { | |
| ter(rng(2, x - 2), mw) = t_door_c; | |
| } | |
| else | |
| { | |
| ter(x, rng(tw + 2, mw - 2)) = t_door_c; | |
| } | |
| line(this, t_wall_h, cw + 1, y, rw, y); | |
| mansion_room(this, cw + 1, y, rw, SEEY * 2 - 2); | |
| if (one_in(2)) | |
| { | |
| ter(rng(cw + 2, rw - 1), y) = t_door_c; | |
| } | |
| else | |
| { | |
| ter(cw, rng(y + 2, SEEY * 2 - 3)) = t_door_c; | |
| } | |
| if (t_west == ot_mansion_entrance || t_west == ot_mansion) | |
| { | |
| line(this, t_floor, 0, SEEY - 1, 0, SEEY); | |
| } | |
| if (t_south == ot_mansion_entrance || t_south == ot_mansion) | |
| { | |
| line(this, t_floor, SEEX - 1, SEEY * 2 - 1, SEEX, SEEY * 2 - 1); | |
| } | |
| break; | |
| } // switch (rng(1, 4)) | |
| // Finally, place windows on outside-facing walls if necessary | |
| if (t_west != ot_mansion_entrance && t_west != ot_mansion) | |
| { | |
| int consecutive = 0; | |
| for (int i = 1; i < SEEY; i++) | |
| { | |
| if (move_cost(1, i) != 0 && move_cost(1, SEEY * 2 - 1 - i) != 0) | |
| { | |
| if (consecutive == 3) | |
| { | |
| consecutive = 0; // No really long windows | |
| } | |
| else | |
| { | |
| consecutive++; | |
| ter(0, i) = t_window; | |
| ter(0, SEEY * 2 - 1 - i) = t_window; | |
| } | |
| } | |
| else | |
| { | |
| consecutive = 0; | |
| } | |
| } | |
| } | |
| if (t_south != ot_mansion_entrance && t_south != ot_mansion) | |
| { | |
| int consecutive = 0; | |
| for (int i = 1; i < SEEX; i++) | |
| { | |
| if (move_cost(i, SEEY * 2 - 2) != 0 && | |
| move_cost(SEEX * 2 - 1 - i, SEEY * 2 - 2) != 0) | |
| { | |
| if (consecutive == 3) | |
| { | |
| consecutive = 0; // No really long windows | |
| } | |
| else | |
| { | |
| consecutive++; | |
| ter(i, SEEY * 2 - 1) = t_window; | |
| ter(SEEX * 2 - 1 - i, SEEY * 2 - 1) = t_window; | |
| } | |
| } | |
| else | |
| { | |
| consecutive = 0; | |
| } | |
| } | |
| } | |
| if (t_east != ot_mansion_entrance && t_east != ot_mansion) | |
| { | |
| int consecutive = 0; | |
| for (int i = 1; i < SEEY; i++) | |
| { | |
| if (move_cost(SEEX * 2 - 2, i) != 0 && | |
| move_cost(SEEX * 2 - 2, SEEY * 2 - 1 - i) != 0) | |
| { | |
| if (consecutive == 3) | |
| { | |
| consecutive = 0; // No really long windows | |
| } | |
| else | |
| { | |
| consecutive++; | |
| ter(SEEX * 2 - 1, i) = t_window; | |
| ter(SEEX * 2 - 1, SEEY * 2 - 1 - i) = t_window; | |
| } | |
| } | |
| else | |
| { | |
| consecutive = 0; | |
| } | |
| } | |
| } | |
| if (t_north != ot_mansion_entrance && t_north != ot_mansion) | |
| { | |
| int consecutive = 0; | |
| for (int i = 1; i < SEEX; i++) | |
| { | |
| if (move_cost(i, 1) != 0 && move_cost(SEEX * 2 - 1 - i, 1) != 0) | |
| { | |
| if (consecutive == 3) | |
| { | |
| consecutive = 0; // No really long windows | |
| } | |
| else | |
| { | |
| consecutive++; | |
| ter(i, 0) = t_window; | |
| ter(SEEX * 2 - 1 - i, 0) = t_window; | |
| } | |
| } | |
| else | |
| { | |
| consecutive = 0; | |
| } | |
| } | |
| } | |
| break; | |
| case ot_fema_entrance: | |
| { | |
| square(this, t_dirt, 0, 0, 23, 23); | |
| // Left wall | |
| line(this, t_chainfence_v, 0, 0, 0, SEEY * 2 - 2); | |
| line(this, t_fence_barbed, 1, 4, 9, 12); | |
| line(this, t_fence_barbed, 1, 5, 8, 12); | |
| line(this, t_fence_barbed, 23, 4, 15, 12); | |
| line(this, t_fence_barbed, 23, 5, 16, 12); | |
| square(this, t_wall_wood, 2, 13, 9, 21); | |
| square(this, t_floor, 3, 14, 8, 20); | |
| line(this, t_reinforced_glass_h, 5, 13, 6, 13); | |
| line(this, t_reinforced_glass_h, 5, 21, 6, 21); | |
| line(this, t_reinforced_glass_v, 9, 15, 9, 18); | |
| line(this, t_door_c, 9, 16, 9, 17); | |
| line(this, t_locker, 3, 16, 3, 18); | |
| line(this, t_chair, 5, 16, 5, 18); | |
| line(this, t_desk, 6, 16, 6, 18); | |
| line(this, t_chair, 7, 16, 7, 18); | |
| place_items(mi_office, 80, 3, 16, 3, 18, false, 0); | |
| place_items(mi_office, 80, 6, 16, 6, 18, false, 0); | |
| add_spawn(mon_zombie_soldier, rng(1, 6), 4, 17); | |
| // Rotate to face the road | |
| if (t_east >= ot_road_null && t_east <= ot_bridge_ew) | |
| { | |
| rotate(1); | |
| } | |
| if (t_south >= ot_road_null && t_south <= ot_bridge_ew) | |
| { | |
| rotate(2); | |
| } | |
| if (t_west >= ot_road_null && t_west <= ot_bridge_ew) | |
| { | |
| rotate(3); | |
| } | |
| } | |
| break; | |
| case ot_fema: | |
| { | |
| square(this, t_dirt, 0, 0, 23, 23); | |
| line(this, t_chainfence_v, 0, 0, 0, 23); | |
| line(this, t_chainfence_h, 0, 23, 23, 23); | |
| if (t_north != ot_fema_entrance && t_north != ot_fema) | |
| { | |
| line(this, t_chainfence_h, 0, 0, 23, 0); | |
| } | |
| if (t_east != ot_fema_entrance && t_east != ot_fema) | |
| { | |
| line(this, t_chainfence_v, 23, 0, 23, 23); | |
| } | |
| if (t_south == ot_fema) | |
| { | |
| line(this, t_dirt, 0, 23, 23, 23); | |
| } | |
| if (t_west == ot_fema) | |
| { | |
| line(this, t_dirt, 0, 0, 0, 23); | |
| } | |
| if (t_west == ot_fema && t_east == ot_fema && t_south != ot_fema) //lab bottom side | |
| { | |
| square(this, t_dirt, 1, 1, 22, 22); | |
| square(this, t_floor, 4, 4, 19, 19); | |
| line(this, t_concrete_h, 4, 4, 19, 4); | |
| line(this, t_concrete_h, 4, 19, 19, 19); | |
| line(this, t_concrete_v, 4, 5, 4, 18); | |
| line(this, t_concrete_v, 19, 5, 19, 18); | |
| line(this, t_door_metal_c, 11, 4, 12, 4); | |
| line(this, t_glass_fridge, 6, 5, 9, 5); | |
| line(this, t_glass_fridge, 14, 5, 17, 5); | |
| square(this, t_grate, 6, 8, 8, 9); | |
| line(this, t_table, 7, 8, 7, 9); | |
| square(this, t_grate, 6, 12, 8, 13); | |
| line(this, t_table, 7, 12, 7, 13); | |
| square(this, t_grate, 6, 16, 8, 17); | |
| line(this, t_table, 7, 16, 7, 17); | |
| line(this, t_counter, 10, 8, 10, 17); | |
| square(this, t_chair, 14, 8, 17, 10); | |
| square(this, t_console_broken, 15, 8, 16, 10); | |
| line(this, t_desk, 15, 11, 16, 11); | |
| line(this, t_chair, 15, 12, 16, 12); | |
| line(this, t_reinforced_glass_h, 13, 14, 18, 14); | |
| line(this, t_reinforced_glass_v, 13, 14, 13, 18); | |
| ter(15, 14) = t_door_metal_locked; | |
| place_items(mi_dissection, 90, 10, 8, 10, 17, false, 0); | |
| place_items(mi_hospital_lab, 70, 5, 5, 18, 18, false, 0); | |
| place_items(mi_harddrugs, 50, 6, 5, 9, 5, false, 0); | |
| place_items(mi_harddrugs, 50, 14, 5, 17, 5, false, 0); | |
| place_items(mi_hospital_samples, 50, 6, 5, 9, 5, false, 0); | |
| place_items(mi_hospital_samples, 50, 14, 5, 17, 5, false, 0); | |
| add_spawn(mon_zombie_scientist, rng(1, 6), 11, 12); | |
| if (one_in(2)) | |
| { | |
| add_spawn(mon_zombie_brute, 1, 16, 17); | |
| } | |
| } | |
| else if (t_west == ot_fema_entrance) | |
| { | |
| square(this, t_dirt, 1, 1, 22, 22); | |
| square(this, t_canvas_wall, 4, 4, 19, 19); //Supply tent | |
| square(this, t_fema_groundsheet, 5, 5, 18, 18); | |
| line(this, t_canvas_door, 11, 4, 12, 4); | |
| line(this, t_canvas_door, 11, 19, 12, 19); | |
| square(this, t_crate_c, 5, 6, 7, 7); | |
| square(this, t_crate_c, 5, 11, 7, 12); | |
| square(this, t_crate_c, 5, 16, 7, 17); | |
| line(this, t_chainfence_h, 9, 6, 14, 6); | |
| line(this, t_chainfence_h, 9, 17, 14, 17); | |
| ter(9, 5) = t_chaingate_c; | |
| ter(14, 18) = t_chaingate_c; | |
| ter(14, 5) = t_chainfence_h; | |
| ter(9, 18) = t_chainfence_h; | |
| ter(12, 17) = t_counter; | |
| ter(11, 6) = t_counter; | |
| line(this, t_chair, 10, 10, 13, 10); | |
| square(this, t_desk, 10, 11, 13, 12); | |
| line(this, t_chair, 10, 13, 13, 13); | |
| line(this, t_chainfence_h, 15, 8, 18, 8); | |
| line(this, t_chainfence_h, 15, 15, 18, 15); | |
| line(this, t_chainfence_v, 15, 9, 15, 14); | |
| line(this, t_chaingate_c, 15, 11, 15, 12); | |
| line(this, t_locker, 18, 9, 18, 14); | |
| place_items(mi_allclothes, 90, 5, 6, 7, 7, false, 0); | |
| place_items(mi_softdrugs, 90, 5, 11, 7, 12, false, 0); | |
| place_items(mi_hardware, 90, 5, 16, 7, 17, false, 0); | |
| place_items(mi_mil_rifles, 90, 18, 9, 18, 14, false, 0); | |
| place_items(mi_office, 80, 10, 11, 13, 12, false, 0); | |
| add_spawn(mon_zombie_soldier, rng(1, 6), 12, 14); | |
| } | |
| else | |
| { | |
| switch (rng(1, 5)) | |
| { | |
| case 1: | |
| case 2: | |
| case 3: | |
| square(this, t_dirt, 1, 1, 22, 22); | |
| square(this, t_canvas_wall, 4, 4, 19, 19); //Lodging | |
| square(this, t_fema_groundsheet, 5, 5, 18, 18); | |
| line(this, t_canvas_door, 11, 4, 12, 4); | |
| line(this, t_canvas_door, 11, 19, 12, 19); | |
| line(this, t_makeshift_bed, 6, 6, 6, 17); | |
| line(this, t_makeshift_bed, 8, 6, 8, 17); | |
| line(this, t_makeshift_bed, 10, 6, 10, 17); | |
| line(this, t_makeshift_bed, 13, 6, 13, 17); | |
| line(this, t_makeshift_bed, 15, 6, 15, 17); | |
| line(this, t_makeshift_bed, 17, 6, 17, 17); | |
| line(this, t_fema_groundsheet, 6, 8, 17, 8); | |
| line(this, t_fema_groundsheet, 6, 8, 17, 8); | |
| square(this, t_fema_groundsheet, 6, 11, 17, 12); | |
| line(this, t_fema_groundsheet, 6, 15, 17, 15); | |
| line(this, t_crate_o, 6, 7, 17, 7); | |
| line(this, t_crate_o, 6, 10, 17, 10); | |
| line(this, t_crate_o, 6, 14, 17, 14); | |
| line(this, t_crate_o, 6, 17, 17, 17); | |
| line(this, t_fema_groundsheet, 7, 5, 7, 18); | |
| line(this, t_fema_groundsheet, 9, 5, 9, 18); | |
| square(this, t_fema_groundsheet, 11, 5, 12, 18); | |
| line(this, t_fema_groundsheet, 14, 5, 14, 18); | |
| line(this, t_fema_groundsheet, 16, 5, 16, 18); | |
| place_items(mi_livingroom, 80, 5, 5, 18, 18, false, 0); | |
| add_spawn(mon_zombie, rng(1, 5), 11, 12); | |
| break; | |
| case 4: | |
| square(this, t_dirt, 1, 1, 22, 22); | |
| square(this, t_canvas_wall, 4, 4, 19, 19); //Mess hall/tent | |
| square(this, t_fema_groundsheet, 5, 5, 18, 18); | |
| line(this, t_canvas_door, 11, 4, 12, 4); | |
| line(this, t_canvas_door, 11, 19, 12, 19); | |
| line(this, t_crate_c, 5, 5, 5, 6); | |
| square(this, t_counter, 6, 6, 10, 8); | |
| square(this, t_rock_floor, 6, 5, 9, 7); | |
| ter(7, 6) = t_woodstove; | |
| line(this, t_bench, 13, 6, 17, 6); | |
| line(this, t_table, 13, 7, 17, 7); | |
| line(this, t_bench, 13, 8, 17, 8); | |
| line(this, t_bench, 13, 11, 17, 11); | |
| line(this, t_table, 13, 12, 17, 12); | |
| line(this, t_bench, 13, 13, 17, 13); | |
| line(this, t_bench, 13, 15, 17, 15); | |
| line(this, t_table, 13, 16, 17, 16); | |
| line(this, t_bench, 13, 17, 17, 17); | |
| line(this, t_bench, 6, 11, 10, 11); | |
| line(this, t_table, 6, 12, 10, 12); | |
| line(this, t_bench, 6, 13, 10, 13); | |
| line(this, t_bench, 6, 15, 10, 15); | |
| line(this, t_table, 6, 16, 10, 16); | |
| line(this, t_bench, 6, 17, 10, 17); | |
| place_items(mi_mil_food_nodrugs, 80, 5, 5, 5, 6, false, 0); | |
| place_items(mi_snacks, 80, 5, 5, 18, 18, false, 0); | |
| place_items(mi_kitchen, 70, 6, 5, 10, 8, false, 0); | |
| place_items(mi_dining, 80, 13, 7, 17, 7, false, 0); | |
| place_items(mi_dining, 80, 13, 12, 17, 12, false, 0); | |
| place_items(mi_dining, 80, 13, 16, 17, 16, false, 0); | |
| place_items(mi_dining, 80, 6, 12, 10, 12, false, 0); | |
| place_items(mi_dining, 80, 6, 16, 10, 16, false, 0); | |
| add_spawn(mon_zombie, rng(1, 5), 11, 12); | |
| break; | |
| case 5: | |
| square(this, t_dirtfloor, 1, 1, 22, 22); | |
| square(this, t_fence_barbed, 4, 4, 19, 19); | |
| square(this, t_dirt, 5, 5, 18, 18); | |
| square(this, t_pit_corpsed, 6, 6, 17, 17); | |
| add_spawn(mon_zombie, rng(5, 20), 11, 12); | |
| break; | |
| } | |
| } | |
| } | |
| break; | |
| case ot_spider_pit_under: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if ((i >= 3 && i <= SEEX * 2 - 4 && j >= 3 && j <= SEEY * 2 - 4) || | |
| one_in(4)) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| if (!one_in(3)) | |
| { | |
| add_field(NULL, x, y, fd_web, rng(1, 3)); | |
| } | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| } | |
| } | |
| ter(rng(3, SEEX * 2 - 4), rng(3, SEEY * 2 - 4)) = t_slope_up; | |
| place_items(mi_spider, 85, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, false, 0); | |
| add_spawn(mon_spider_trapdoor, 1, rng(3, SEEX * 2 - 5), rng(3, SEEY * 2 - 4)); | |
| break; | |
| case ot_anthill: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i < 8 || j < 8 || i > SEEX * 2 - 9 || j > SEEY * 2 - 9) | |
| { | |
| ter(i, j) = grass_or_dirt(); | |
| } | |
| else if ((i == 11 || i == 12) && (j == 11 || j == 12)) | |
| { | |
| ter(i, j) = t_slope_down; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_dirtmound; | |
| } | |
| } | |
| } | |
| break; | |
| case ot_rock: | |
| if (t_north == ot_cavern || t_north == ot_slimepit || | |
| t_north == ot_slimepit_down) | |
| { | |
| n_fac = 6; | |
| } | |
| else | |
| { | |
| n_fac = 0; | |
| } | |
| if (t_east == ot_cavern || t_east == ot_slimepit || | |
| t_east == ot_slimepit_down) | |
| { | |
| e_fac = 6; | |
| } | |
| else | |
| { | |
| e_fac = 0; | |
| } | |
| if (t_south == ot_cavern || t_south == ot_slimepit || | |
| t_south == ot_slimepit_down) | |
| { | |
| s_fac = 6; | |
| } | |
| else | |
| { | |
| s_fac = 0; | |
| } | |
| if (t_west == ot_cavern || t_west == ot_slimepit || | |
| t_west == ot_slimepit_down) | |
| { | |
| w_fac = 6; | |
| } | |
| else | |
| { | |
| w_fac = 0; | |
| } | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (rng(0, n_fac) > j || rng(0, e_fac) > SEEX * 2 - 1 - i || | |
| rng(0, w_fac) > i || rng(0, s_fac) > SEEY * 2 - 1 - j) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| } | |
| } | |
| break; | |
| case ot_rift: | |
| if (t_north != ot_rift && t_north != ot_hellmouth) | |
| { | |
| if (connects_to(t_north, 2)) | |
| { | |
| n_fac = rng(-6, -2); | |
| } | |
| else | |
| { | |
| n_fac = rng(2, 6); | |
| } | |
| } | |
| if (t_east != ot_rift && t_east != ot_hellmouth) | |
| { | |
| if (connects_to(t_east, 3)) | |
| { | |
| e_fac = rng(-6, -2); | |
| } | |
| else | |
| { | |
| e_fac = rng(2, 6); | |
| } | |
| } | |
| if (t_south != ot_rift && t_south != ot_hellmouth) | |
| { | |
| if (connects_to(t_south, 0)) | |
| { | |
| s_fac = rng(-6, -2); | |
| } | |
| else | |
| { | |
| s_fac = rng(2, 6); | |
| } | |
| } | |
| if (t_west != ot_rift && t_west != ot_hellmouth) | |
| { | |
| if (connects_to(t_west, 1)) | |
| { | |
| w_fac = rng(-6, -2); | |
| } | |
| else | |
| { | |
| w_fac = rng(2, 6); | |
| } | |
| } | |
| // Negative *_fac values indicate rock floor connection, otherwise solid rock | |
| // Of course, if we connect to a rift, *_fac = 0, and thus lava extends all the | |
| // way. | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if ((n_fac < 0 && j < n_fac * -1) || (s_fac < 0 && j >= SEEY * 2 - s_fac) || | |
| (w_fac < 0 && i < w_fac * -1) || (e_fac < 0 && i >= SEEX * 2 - e_fac)) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| else if (j < n_fac || j >= SEEY * 2 - s_fac || | |
| i < w_fac || i >= SEEX * 2 - e_fac) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_lava; | |
| } | |
| } | |
| } | |
| break; | |
| case ot_hellmouth: | |
| if (t_north != ot_rift && t_north != ot_hellmouth) | |
| { | |
| n_fac = 6; | |
| } | |
| if (t_east != ot_rift && t_east != ot_hellmouth) | |
| { | |
| e_fac = 6; | |
| } | |
| if (t_south != ot_rift && t_south != ot_hellmouth) | |
| { | |
| s_fac = 6; | |
| } | |
| if (t_west != ot_rift && t_west != ot_hellmouth) | |
| { | |
| w_fac = 6; | |
| } | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (j < n_fac || j >= SEEY * 2 - s_fac || i < w_fac || i >= SEEX * 2 - e_fac || | |
| (i >= 6 && i < SEEX * 2 - 6 && j >= 6 && j < SEEY * 2 - 6)) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_lava; | |
| } | |
| if (i >= SEEX - 1 && i <= SEEX && j >= SEEY - 1 && j <= SEEY) | |
| { | |
| ter(i, j) = t_slope_down; | |
| } | |
| } | |
| } | |
| switch (rng(0, 4)) // Randomly chosen "altar" design | |
| { | |
| case 0: | |
| for (int i = 7; i <= 16; i += 3) | |
| { | |
| ter(i, 6) = t_rock; | |
| ter(i, 17) = t_rock; | |
| ter(6, i) = t_rock; | |
| ter(17, i) = t_rock; | |
| if (i > 7 && i < 16) | |
| { | |
| ter(i, 10) = t_rock; | |
| ter(i, 13) = t_rock; | |
| } | |
| else | |
| { | |
| ter(i - 1, 6) = t_rock; | |
| ter(i - 1, 10) = t_rock; | |
| ter(i - 1, 13) = t_rock; | |
| ter(i - 1, 17) = t_rock; | |
| } | |
| } | |
| break; | |
| case 1: | |
| for (int i = 6; i < 11; i++) | |
| { | |
| ter(i, i) = t_lava; | |
| ter(SEEX * 2 - 1 - i, i) = t_lava; | |
| ter(i, SEEY * 2 - 1 - i) = t_lava; | |
| ter(SEEX * 2 - 1 - i, SEEY * 2 - 1 - i) = t_lava; | |
| if (i < 10) | |
| { | |
| ter(i + 1, i) = t_lava; | |
| ter(SEEX * 2 - i, i) = t_lava; | |
| ter(i + 1, SEEY * 2 - 1 - i) = t_lava; | |
| ter(SEEX * 2 - i, SEEY * 2 - 1 - i) = t_lava; | |
| ter(i, i + 1) = t_lava; | |
| ter(SEEX * 2 - 1 - i, i + 1) = t_lava; | |
| ter(i, SEEY * 2 - i) = t_lava; | |
| ter(SEEX * 2 - 1 - i, SEEY * 2 - i) = t_lava; | |
| } | |
| if (i < 9) | |
| { | |
| ter(i + 2, i) = t_rock; | |
| ter(SEEX * 2 - i + 1, i) = t_rock; | |
| ter(i + 2, SEEY * 2 - 1 - i) = t_rock; | |
| ter(SEEX * 2 - i + 1, SEEY * 2 - 1 - i) = t_rock; | |
| ter(i, i + 2) = t_rock; | |
| ter(SEEX * 2 - 1 - i, i + 2) = t_rock; | |
| ter(i, SEEY * 2 - i + 1) = t_rock; | |
| ter(SEEX * 2 - 1 - i, SEEY * 2 - i + 1) = t_rock; | |
| } | |
| } | |
| break; | |
| case 2: | |
| for (int i = 7; i < 17; i++) | |
| { | |
| ter(i, 6) = t_rock; | |
| ter(6, i) = t_rock; | |
| ter(i, 17) = t_rock; | |
| ter(17, i) = t_rock; | |
| if (i != 7 && i != 16 && i != 11 && i != 12) | |
| { | |
| ter(i, 8) = t_rock; | |
| ter(8, i) = t_rock; | |
| ter(i, 15) = t_rock; | |
| ter(15, i) = t_rock; | |
| } | |
| if (i == 11 || i == 12) | |
| { | |
| ter(i, 10) = t_rock; | |
| ter(10, i) = t_rock; | |
| ter(i, 13) = t_rock; | |
| ter(13, i) = t_rock; | |
| } | |
| } | |
| break; | |
| case 3: | |
| for (int i = 6; i < 11; i++) | |
| { | |
| for (int j = 6; j < 11; j++) | |
| { | |
| ter(i, j) = t_lava; | |
| ter(SEEX * 2 - 1 - i, j) = t_lava; | |
| ter(i, SEEY * 2 - 1 - j) = t_lava; | |
| ter(SEEX * 2 - 1 - i, SEEY * 2 - 1 - j) = t_lava; | |
| } | |
| } | |
| break; | |
| } | |
| break; | |
| case ot_slimepit: | |
| case ot_slimepit_down: | |
| n_fac = (t_north == ot_slimepit || t_north == ot_slimepit_down ? 1 : 0); | |
| e_fac = (t_east == ot_slimepit || t_east == ot_slimepit_down ? 1 : 0); | |
| s_fac = (t_south == ot_slimepit || t_south == ot_slimepit_down ? 1 : 0); | |
| w_fac = (t_west == ot_slimepit || t_west == ot_slimepit_down ? 1 : 0); | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (!one_in(10) && (j < n_fac * SEEX || i < w_fac * SEEX || | |
| j > SEEY * 2 - s_fac * SEEY || i > SEEX * 2 - e_fac * SEEX)) | |
| { | |
| ter(i, j) = (!one_in(10) ? t_slime : t_rock_floor); | |
| } | |
| else if (rng(0, SEEX) > abs(i - SEEX) && rng(0, SEEY) > abs(j - SEEY)) | |
| { | |
| ter(i, j) = t_slime; | |
| } | |
| else if (t_above == ot_null) | |
| { | |
| ter(i, j) = t_dirt; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (terrain_type == ot_slimepit_down) | |
| { | |
| ter(rng(3, SEEX * 2 - 4), rng(3, SEEY * 2 - 4)) = t_slope_down; | |
| } | |
| if (t_above == ot_slimepit_down) | |
| { | |
| switch (rng(1, 4)) | |
| { | |
| case 1: | |
| ter(rng(0, 2), rng(0, 2)) = t_slope_up; | |
| case 2: | |
| ter(rng(0, 2), SEEY * 2 - rng(1, 3)) = t_slope_up; | |
| case 3: | |
| ter(SEEX * 2 - rng(1, 3), rng(0, 2)) = t_slope_up; | |
| case 4: | |
| ter(SEEX * 2 - rng(1, 3), SEEY * 2 - rng(1, 3)) = t_slope_up; | |
| } | |
| } | |
| add_spawn(mon_blob, 8, SEEX, SEEY); | |
| place_items(mi_sewer, 40, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| break; | |
| case ot_triffid_grove: | |
| square(this, t_dirt, 0, 0, 23, 23); | |
| for (int rad = 5; rad < SEEX - 2; rad += rng(2, 3)) | |
| { | |
| square(this, t_tree, rad, rad, 23 - rad, 23 - rad); | |
| square(this, t_dirt, rad + 1, rad + 1, 22 - rad, 22 - rad); | |
| if (one_in(2)) // Vertical side opening | |
| { | |
| int x = (one_in(2) ? rad : 23 - rad), y = rng(rad + 1, 22 - rad); | |
| ter(x, y) = t_dirt; | |
| } | |
| else // Horizontal side opening | |
| { | |
| int x = rng(rad + 1, 22 - rad), y = (one_in(2) ? rad : 23 - rad); | |
| ter(x, y) = t_dirt; | |
| } | |
| add_spawn((one_in(3) ? mon_biollante : mon_triffid), 1, rad + 1, rad + 1); | |
| add_spawn((one_in(3) ? mon_biollante : mon_triffid), 1, 22 - rad, rad + 1); | |
| add_spawn((one_in(3) ? mon_biollante : mon_triffid), 1, rad + 1, 22 - rad); | |
| add_spawn((one_in(3) ? mon_biollante : mon_triffid), 1, 22 - rad, 22 - rad); | |
| } | |
| square(this, t_slope_down, SEEX - 1, SEEY - 1, SEEX, SEEY); | |
| break; | |
| case ot_triffid_roots: | |
| { | |
| square(this, t_root_wall, 0, 0, 23, 23); | |
| int node = 0; | |
| int step = 0; | |
| bool node_built[16]; | |
| bool done = false; | |
| for (int i = 0; i < 16; i++) | |
| { | |
| node_built[i] = false; | |
| } | |
| do | |
| { | |
| node_built[node] = true; | |
| step++; | |
| int nodex = 1 + 6 * (node % 4), nodey = 1 + 6 * int(node / 4); | |
| // Clear a 4x4 dirt square | |
| square(this, t_dirt, nodex, nodey, nodex + 3, nodey + 3); | |
| // Spawn a monster in there | |
| if (step > 2) // First couple of chambers are safe | |
| { | |
| int monrng = rng(1, 20); | |
| int spawnx = nodex + rng(0, 3), spawny = nodey + rng(0, 3); | |
| if (monrng <= 5) | |
| { | |
| add_spawn(mon_triffid, rng(1, 4), spawnx, spawny); | |
| } | |
| else if (monrng <= 13) | |
| { | |
| add_spawn(mon_creeper_hub, 1, spawnx, spawny); | |
| } | |
| else if (monrng <= 19) | |
| { | |
| add_spawn(mon_biollante, 1, spawnx, spawny); | |
| } | |
| else | |
| { | |
| for (int webx = nodex; webx <= nodex + 3; webx++) | |
| { | |
| for (int weby = nodey; weby <= nodey + 3; weby++) | |
| { | |
| add_field(g, webx, weby, fd_web, rng(1, 3)); | |
| } | |
| } | |
| add_spawn(mon_spider_web, 1, spawnx, spawny); | |
| } | |
| } | |
| // TODO: Non-monster hazards? | |
| // Next, pick a cell to move to | |
| std::vector<direction> move; | |
| if (node % 4 > 0 && !node_built[node - 1]) | |
| { | |
| move.push_back(WEST); | |
| } | |
| if (node % 4 < 3 && !node_built[node + 1]) | |
| { | |
| move.push_back(EAST); | |
| } | |
| if (int(node / 4) > 0 && !node_built[node - 4]) | |
| { | |
| move.push_back(NORTH); | |
| } | |
| if (int(node / 4) < 3 && !node_built[node + 4]) | |
| { | |
| move.push_back(SOUTH); | |
| } | |
| if (move.empty()) // Nowhere to go! | |
| { | |
| square(this, t_slope_down, nodex + 1, nodey + 1, nodex + 2, nodey + 2); | |
| done = true; | |
| } | |
| else | |
| { | |
| int index = rng(0, move.size() - 1); | |
| switch (move[index]) | |
| { | |
| case NORTH: | |
| square(this, t_dirt, nodex + 1, nodey - 2, nodex + 2, nodey - 1); | |
| node -= 4; | |
| break; | |
| case EAST: | |
| square(this, t_dirt, nodex + 4, nodey + 1, nodex + 5, nodey + 2); | |
| node++; | |
| break; | |
| case SOUTH: | |
| square(this, t_dirt, nodex + 1, nodey + 4, nodex + 2, nodey + 5); | |
| node += 4; | |
| break; | |
| case WEST: | |
| square(this, t_dirt, nodex - 2, nodey + 1, nodex - 1, nodey + 2); | |
| node--; | |
| break; | |
| } | |
| } | |
| } | |
| while (!done); | |
| square(this, t_slope_up, 2, 2, 3, 3); | |
| rotate(rng(0, 3)); | |
| } | |
| break; | |
| case ot_triffid_finale: | |
| { | |
| square(this, t_root_wall, 0, 0, 23, 23); | |
| square(this, t_dirt, 1, 1, 4, 4); | |
| square(this, t_dirt, 19, 19, 22, 22); | |
| // Drunken walk until we reach the heart (lower right, [19, 19]) | |
| // Chance increases by 1 each turn, and gives the % chance of forcing a move | |
| // to the right or down. | |
| int chance = 0; | |
| int x = 4, y = 4; | |
| do | |
| { | |
| ter(x, y) = t_dirt; | |
| if (chance >= 10 && one_in(10)) // Add a spawn | |
| { | |
| if (one_in(2)) | |
| { | |
| add_spawn(mon_biollante, 1, x, y); | |
| } | |
| else if (!one_in(4)) | |
| { | |
| add_spawn(mon_creeper_hub, 1, x, y); | |
| } | |
| else | |
| { | |
| add_spawn(mon_triffid, 1, x, y); | |
| } | |
| } | |
| if (rng(0, 99) < chance) // Force movement down or to the right | |
| { | |
| if (x >= 19) | |
| { | |
| y++; | |
| } | |
| else if (y >= 19) | |
| { | |
| x++; | |
| } | |
| else | |
| { | |
| if (one_in(2)) | |
| { | |
| x++; | |
| } | |
| else | |
| { | |
| y++; | |
| } | |
| } | |
| } | |
| else | |
| { | |
| chance++; // Increase chance of forced movement down/right | |
| // Weigh movement towards directions with lots of existing walls | |
| int chance_west = 0, chance_east = 0, chance_north = 0, chance_south = 0; | |
| for (int dist = 1; dist <= 5; dist++) | |
| { | |
| if (ter(x - dist, y) == t_root_wall) | |
| { | |
| chance_west++; | |
| } | |
| if (ter(x + dist, y) == t_root_wall) | |
| { | |
| chance_east++; | |
| } | |
| if (ter(x, y - dist) == t_root_wall) | |
| { | |
| chance_north++; | |
| } | |
| if (ter(x, y + dist) == t_root_wall) | |
| { | |
| chance_south++; | |
| } | |
| } | |
| int roll = rng(0, chance_west + chance_east + chance_north + chance_south); | |
| if (roll < chance_west && x > 0) | |
| { | |
| x--; | |
| } | |
| else if (roll < chance_west + chance_east && x < 23) | |
| { | |
| x++; | |
| } | |
| else if (roll < chance_west + chance_east + chance_north && y > 0) | |
| { | |
| y--; | |
| } | |
| else if (y < 23) | |
| { | |
| y++; | |
| } | |
| } // Done with drunken walk | |
| } | |
| while (x < 19 || y < 19); | |
| square(this, t_slope_up, 1, 1, 2, 2); | |
| add_spawn(mon_triffid_heart, 1, 21, 21); | |
| } | |
| break; | |
| case ot_basement: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i == 0 || j == 0 || i == SEEX * 2 - 1 || j == SEEY * 2 - 1) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| switch (rng(0, 4)) // TODO: More types! | |
| { | |
| case 0: // Junk! | |
| ter(SEEX - 1, SEEY * 2 - 2) = t_stairs_up; | |
| ter(SEEX , SEEY * 2 - 2) = t_stairs_up; | |
| place_items(mi_bedroom, 60, 1, 1, SEEX * 2 - 2, SEEY * 2 - 2, false, 0); | |
| place_items(mi_home_hw, 80, 1, 1, SEEX * 2 - 2, SEEY * 2 - 2, false, 0); | |
| place_items(mi_homeguns, 10, 1, 1, SEEX * 2 - 2, SEEY * 2 - 2, false, 0); | |
| break; | |
| case 1: // Weapons cache | |
| for (int i = 2; i < SEEX * 2 - 2; i++) | |
| { | |
| ter(i, 1) = t_rack; | |
| ter(i, 5) = t_rack; | |
| ter(i, 9) = t_rack; | |
| } | |
| place_items(mi_allguns, 80, 2, 1, SEEX * 2 - 3, 1, false, 0); | |
| place_items(mi_ammo, 94, 2, 5, SEEX * 2 - 3, 5, false, 0); | |
| place_items(mi_weapons, 88, 2, 9, SEEX * 2 - 3, 9, false, 0); | |
| ter(SEEX - 1, SEEY * 2 - 2) = t_stairs_up; | |
| ter(SEEX , SEEY * 2 - 2) = t_stairs_up; | |
| break; | |
| case 2: // Survival Bunker | |
| ter(1, 1) = t_bed; | |
| ter(1, 2) = t_bed; | |
| ter(SEEX * 2 - 2, 1) = t_bed; | |
| ter(SEEX * 2 - 2, 2) = t_bed; | |
| for (int i = 1; i < SEEY; i++) | |
| { | |
| ter(SEEX - 1, i) = t_rack; | |
| ter(SEEX , i) = t_rack; | |
| } | |
| place_items(mi_softdrugs, 86, SEEX - 1, 1, SEEX, 2, false, 0); | |
| place_items(mi_cannedfood, 92, SEEX - 1, 3, SEEX, 6, false, 0); | |
| place_items(mi_homeguns, 72, SEEX - 1, 7, SEEX, 7, false, 0); | |
| place_items(mi_survival_tools, 83, SEEX - 1, 8, SEEX, 10, false, 0); | |
| place_items(mi_manuals, 60, SEEX - 1, 11, SEEX, 11, false, 0); | |
| ter(SEEX - 1, SEEY * 2 - 2) = t_stairs_up; | |
| ter(SEEX , SEEY * 2 - 2) = t_stairs_up; | |
| break; | |
| case 3: // Chem lab | |
| for (int i = 1; i < SEEY + 4; i++) | |
| { | |
| ter(1 , i) = t_counter; | |
| ter(SEEX * 2 - 2, i) = t_counter; | |
| } | |
| place_items(mi_chemistry, 90, 1, 1, 1, SEEY + 3, false, 0); | |
| if (one_in(3)) | |
| { | |
| place_items(mi_chemistry, 90, SEEX * 2 - 2, 1, SEEX * 2 - 2, SEEY + 3, false, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_electronics, 90, SEEX * 2 - 2, 1, SEEX * 2 - 2, SEEY + 3, false, 0); | |
| } | |
| ter(SEEX - 1, SEEY * 2 - 2) = t_stairs_up; | |
| ter(SEEX , SEEY * 2 - 2) = t_stairs_up; | |
| break; | |
| case 4: // Weed grow | |
| line(this, t_counter, 1, 1, 1, SEEY * 2 - 2); | |
| line(this, t_counter, SEEX * 2 - 2, 1, SEEX * 2 - 2, SEEY * 2 - 2); | |
| ter(SEEX - 1, SEEY * 2 - 2) = t_stairs_up; | |
| ter(SEEX , SEEY * 2 - 2) = t_stairs_up; | |
| line(this, t_rock, SEEX - 2, SEEY * 2 - 4, SEEX - 2, SEEY * 2 - 2); | |
| line(this, t_rock, SEEX + 1, SEEY * 2 - 4, SEEX + 1, SEEY * 2 - 2); | |
| line(this, t_door_locked, SEEX - 1, SEEY * 2 - 4, SEEX, SEEY * 2 - 4); | |
| for (int i = 3; i < SEEX * 2 - 3; i += 5) | |
| { | |
| for (int j = 3; j < 16; j += 5) | |
| { | |
| square(this, t_dirt, i, j, i + 2, j + 2); | |
| int num_weed = rng(0, 3) * rng(0, 1); | |
| for (int n = 0; n < num_weed; n++) | |
| { | |
| int x = rng(i, i + 2), y = rng(j, j + 2); | |
| add_item(x, y, (*itypes)[itm_weed], 0); | |
| } | |
| } | |
| } | |
| break; | |
| } | |
| break; | |
| // TODO: Maybe subway systems could have broken down trains in them? | |
| case ot_subway_station: | |
| if (t_north >= ot_subway_ns && t_north <= ot_subway_nesw && | |
| connects_to(t_north, 2)) | |
| { | |
| n_fac = 1; | |
| } | |
| if (t_east >= ot_subway_ns && t_east <= ot_subway_nesw && | |
| connects_to(t_east, 3)) | |
| { | |
| e_fac = 1; | |
| } | |
| if (t_south >= ot_subway_ns && t_south <= ot_subway_nesw && | |
| connects_to(t_south, 0)) | |
| { | |
| s_fac = 1; | |
| } | |
| if (t_west >= ot_subway_ns && t_west <= ot_subway_nesw && | |
| connects_to(t_west, 1)) | |
| { | |
| w_fac = 1; | |
| } | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if ((i < 4 && (w_fac == 0 || j < 4 || j > SEEY * 2 - 5)) || | |
| (j < 4 && (n_fac == 0 || i < 4 || i > SEEX * 2 - 5)) || | |
| (i > SEEX * 2 - 5 && (e_fac == 0 || j < 4 || j > SEEY * 2 - 5)) || | |
| (j > SEEY * 2 - 5 && (s_fac == 0 || i < 4 || i > SEEX * 2 - 5))) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| ter(2, 2) = t_stairs_up; | |
| ter(SEEX * 2 - 3, 2) = t_stairs_up; | |
| ter(2, SEEY * 2 - 3) = t_stairs_up; | |
| ter(SEEX * 2 - 3, SEEY * 2 - 3) = t_stairs_up; | |
| if (ter(2, SEEY) == t_floor) | |
| { | |
| ter(2, SEEY) = t_stairs_up; | |
| } | |
| if (ter(SEEX * 2 - 3, SEEY) == t_floor) | |
| { | |
| ter(SEEX * 2 - 3, SEEY) = t_stairs_up; | |
| } | |
| if (ter(SEEX, 2) == t_floor) | |
| { | |
| ter(SEEX, 2) = t_stairs_up; | |
| } | |
| if (ter(SEEX, SEEY * 2 - 3) == t_floor) | |
| { | |
| ter(SEEX, SEEY * 2 - 3) = t_stairs_up; | |
| } | |
| break; | |
| case ot_subway_ns: | |
| case ot_subway_ew: | |
| if (terrain_type == ot_subway_ns) | |
| { | |
| w_fac = (t_west == ot_cavern ? 0 : 4); | |
| e_fac = (t_east == ot_cavern ? SEEX * 2 : SEEX * 2 - 5); | |
| } | |
| else | |
| { | |
| w_fac = (t_north == ot_cavern ? 0 : 4); | |
| e_fac = (t_south == ot_cavern ? SEEX * 2 : SEEX * 2 - 5); | |
| } | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i < w_fac || i > e_fac) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| else if (one_in(90)) | |
| { | |
| ter(i, j) = t_rubble; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (t_above >= ot_sub_station_north && t_above <= ot_sub_station_west) | |
| { | |
| ter(SEEX * 2 - 5, rng(SEEY - 5, SEEY + 4)) = t_stairs_up; | |
| } | |
| place_items(mi_subway, 30, 4, 0, SEEX * 2 - 5, SEEY * 2 - 1, true, 0); | |
| if (terrain_type == ot_subway_ew) | |
| { | |
| rotate(1); | |
| } | |
| break; | |
| case ot_subway_ne: | |
| case ot_subway_es: | |
| case ot_subway_sw: | |
| case ot_subway_wn: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if ((i >= SEEX * 2 - 4 && j < 4) || i < 4 || j >= SEEY * 2 - 4) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| else if (one_in(30)) | |
| { | |
| ter(i, j) = t_rubble; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (t_above >= ot_sub_station_north && t_above <= ot_sub_station_west) | |
| { | |
| ter(SEEX * 2 - 5, rng(SEEY - 5, SEEY + 4)) = t_stairs_up; | |
| } | |
| place_items(mi_subway, 30, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| if (terrain_type == ot_subway_es) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_subway_sw) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_subway_wn) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_subway_nes: | |
| case ot_subway_new: | |
| case ot_subway_nsw: | |
| case ot_subway_esw: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i < 4 || (i >= SEEX * 2 - 4 && (j < 4 || j >= SEEY * 2 - 4))) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| else if (one_in(30)) | |
| { | |
| ter(i, j) = t_rubble; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (t_above >= ot_sub_station_north && t_above <= ot_sub_station_west) | |
| { | |
| ter(4, rng(SEEY - 5, SEEY + 4)) = t_stairs_up; | |
| } | |
| place_items(mi_subway, 35, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| if (terrain_type == ot_subway_esw) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_subway_nsw) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_subway_new) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_subway_nesw: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if ((i < 4 || i >= SEEX * 2 - 4) && | |
| (j < 4 || j >= SEEY * 2 - 4)) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| else if (one_in(30)) | |
| { | |
| ter(i, j) = t_rubble; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (t_above >= ot_sub_station_north && t_above <= ot_sub_station_west) | |
| { | |
| ter(4 + rng(0, 1) * (SEEX * 2 - 9), 4 + rng(0, 1) * (SEEY * 2 - 9)) = t_stairs_up; | |
| } | |
| place_items(mi_subway, 40, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| break; | |
| case ot_sewer_ns: | |
| case ot_sewer_ew: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i < SEEX - 2 || i > SEEX + 1) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_sewage; | |
| } | |
| } | |
| } | |
| place_items(mi_sewer, 10, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| if (terrain_type == ot_sewer_ew) | |
| { | |
| rotate(1); | |
| } | |
| break; | |
| case ot_sewer_ne: | |
| case ot_sewer_es: | |
| case ot_sewer_sw: | |
| case ot_sewer_wn: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if ((i > SEEX + 1 && j < SEEY - 2) || i < SEEX - 2 || j > SEEY + 1) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_sewage; | |
| } | |
| } | |
| } | |
| place_items(mi_sewer, 18, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| if (terrain_type == ot_sewer_es) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_sewer_sw) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_sewer_wn) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_sewer_nes: | |
| case ot_sewer_new: | |
| case ot_sewer_nsw: | |
| case ot_sewer_esw: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i < SEEX - 2 || (i > SEEX + 1 && (j < SEEY - 2 || j > SEEY + 1))) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_sewage; | |
| } | |
| } | |
| } | |
| place_items(mi_sewer, 23, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| if (terrain_type == ot_sewer_esw) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_sewer_nsw) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_sewer_new) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_sewer_nesw: | |
| rn = rng(0, 3); | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if ((i < SEEX - 2 || i > SEEX + 1) && (j < SEEY - 2 || j > SEEY + 1)) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_sewage; | |
| } | |
| if (rn == 0 && (trig_dist(i, j, SEEX - 1, SEEY - 1) <= 6 || | |
| trig_dist(i, j, SEEX - 1, SEEY) <= 6 || | |
| trig_dist(i, j, SEEX, SEEY - 1) <= 6 || | |
| trig_dist(i, j, SEEX, SEEY) <= 6)) | |
| { | |
| ter(i, j) = t_sewage; | |
| } | |
| if (rn == 0 && (i == SEEX - 1 || i == SEEX) && (j == SEEY - 1 || j == SEEY)) | |
| { | |
| ter(i, j) = t_grate; | |
| } | |
| } | |
| } | |
| place_items(mi_sewer, 28, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| break; | |
| case ot_ants_ns: | |
| case ot_ants_ew: | |
| x = SEEX; | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| } | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| for (int i = x - 2; i <= x + 3; i++) | |
| { | |
| if (i >= 1 && i < SEEX * 2 - 1) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| x += rng(-1, 1); | |
| while (abs(SEEX - x) > SEEX * 2 - j - 1) | |
| { | |
| if (x < SEEX) | |
| { | |
| x++; | |
| } | |
| if (x > SEEX) | |
| { | |
| x--; | |
| } | |
| } | |
| } | |
| if (terrain_type == ot_ants_ew) | |
| { | |
| rotate(1); | |
| } | |
| break; | |
| case ot_ants_ne: | |
| case ot_ants_es: | |
| case ot_ants_sw: | |
| case ot_ants_wn: | |
| x = SEEX; | |
| y = 1; | |
| rn = 0; | |
| // First, set it all to rock | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| } | |
| for (int i = SEEX - 2; i <= SEEX + 3; i++) | |
| { | |
| ter(i, 0) = t_rock_floor; | |
| ter(i, 1) = t_rock_floor; | |
| ter(i, 2) = t_rock_floor; | |
| ter(SEEX * 2 - 1, i) = t_rock_floor; | |
| ter(SEEX * 2 - 2, i) = t_rock_floor; | |
| ter(SEEX * 2 - 3, i) = t_rock_floor; | |
| } | |
| do | |
| { | |
| for (int i = x - 2; i <= x + 3; i++) | |
| { | |
| for (int j = y - 2; j <= y + 3; j++) | |
| { | |
| if (i > 0 && i < SEEX * 2 - 1 && j > 0 && j < SEEY * 2 - 1) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (rn < SEEX) | |
| { | |
| x += rng(-1, 1); | |
| y++; | |
| } | |
| else | |
| { | |
| x++; | |
| if (!one_in(x - SEEX)) | |
| { | |
| y += rng(-1, 1); | |
| } | |
| else if (y < SEEY) | |
| { | |
| y++; | |
| } | |
| else if (y > SEEY) | |
| { | |
| y--; | |
| } | |
| } | |
| rn++; | |
| } | |
| while (x < SEEX * 2 - 1 || y != SEEY); | |
| for (int i = x - 2; i <= x + 3; i++) | |
| { | |
| for (int j = y - 2; j <= y + 3; j++) | |
| { | |
| if (i > 0 && i < SEEX * 2 - 1 && j > 0 && j < SEEY * 2 - 1) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (terrain_type == ot_ants_es) | |
| { | |
| rotate(1); | |
| } | |
| if (terrain_type == ot_ants_sw) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_ants_wn) | |
| { | |
| rotate(3); | |
| } | |
| break; | |
| case ot_ants_nes: | |
| case ot_ants_new: | |
| case ot_ants_nsw: | |
| case ot_ants_esw: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| } | |
| x = SEEX; | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| for (int i = x - 2; i <= x + 3; i++) | |
| { | |
| if (i >= 1 && i < SEEX * 2 - 1) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| x += rng(-1, 1); | |
| while (abs(SEEX - x) > SEEY * 2 - j - 1) | |
| { | |
| if (x < SEEX) | |
| { | |
| x++; | |
| } | |
| if (x > SEEX) | |
| { | |
| x--; | |
| } | |
| } | |
| } | |
| y = SEEY; | |
| for (int i = SEEX; i < SEEX * 2; i++) | |
| { | |
| for (int j = y - 2; j <= y + 3; j++) | |
| { | |
| if (j >= 1 && j < SEEY * 2 - 1) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| y += rng(-1, 1); | |
| while (abs(SEEY - y) > SEEX * 2 - 1 - i) | |
| { | |
| if (y < SEEY) | |
| { | |
| y++; | |
| } | |
| if (y > SEEY) | |
| { | |
| y--; | |
| } | |
| } | |
| } | |
| if (terrain_type == ot_ants_new) | |
| { | |
| rotate(3); | |
| } | |
| if (terrain_type == ot_ants_nsw) | |
| { | |
| rotate(2); | |
| } | |
| if (terrain_type == ot_ants_esw) | |
| { | |
| rotate(1); | |
| } | |
| break; | |
| case ot_ants_nesw: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| } | |
| x = SEEX; | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| for (int i = x - 2; i <= x + 3; i++) | |
| { | |
| if (i >= 1 && i < SEEX * 2 - 1) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| x += rng(-1, 1); | |
| while (abs(SEEX - x) > SEEY * 2 - j - 1) | |
| { | |
| if (x < SEEX) | |
| { | |
| x++; | |
| } | |
| if (x > SEEX) | |
| { | |
| x--; | |
| } | |
| } | |
| } | |
| y = SEEY; | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = y - 2; j <= y + 3; j++) | |
| { | |
| if (j >= 1 && j < SEEY * 2 - 1) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| y += rng(-1, 1); | |
| while (abs(SEEY - y) > SEEX * 2 - i - 1) | |
| { | |
| if (y < SEEY) | |
| { | |
| y++; | |
| } | |
| if (y > SEEY) | |
| { | |
| y--; | |
| } | |
| } | |
| } | |
| break; | |
| case ot_ants_food: | |
| case ot_ants_larvae: | |
| case ot_ants_queen: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (i < SEEX - 4 || i > SEEX + 5 || j < SEEY - 4 || j > SEEY + 5) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| rn = rng(10, 20); | |
| for (int n = 0; n < rn; n++) | |
| { | |
| cw = rng(1, 8); | |
| do | |
| { | |
| x = rng(1 + cw, SEEX * 2 - 2 - cw); | |
| y = rng(1 + cw, SEEY * 2 - 2 - cw); | |
| } | |
| while (ter(x, y) == t_rock); | |
| for (int i = x - cw; i <= x + cw; i++) | |
| { | |
| for (int j = y - cw; j <= y + cw; j++) | |
| { | |
| if (trig_dist(x, y, i, j) <= cw) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| } | |
| if (connects_to(t_north, 2)) | |
| { | |
| for (int i = SEEX - 2; i <= SEEX + 3; i++) | |
| { | |
| for (int j = 0; j <= SEEY; j++) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (connects_to(t_east, 3)) | |
| { | |
| for (int i = SEEX; i <= SEEX * 2 - 1; i++) | |
| { | |
| for (int j = SEEY - 2; j <= SEEY + 3; j++) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (connects_to(t_south, 0)) | |
| { | |
| for (int i = SEEX - 2; i <= SEEX + 3; i++) | |
| { | |
| for (int j = SEEY; j <= SEEY * 2 - 1; j++) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (connects_to(t_west, 1)) | |
| { | |
| for (int i = 0; i <= SEEX; i++) | |
| { | |
| for (int j = SEEY - 2; j <= SEEY + 3; j++) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (terrain_type == ot_ants_food) | |
| { | |
| place_items(mi_ant_food, 92, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| } | |
| else | |
| { | |
| place_items(mi_ant_egg, 98, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| } | |
| if (terrain_type == ot_ants_queen) | |
| { | |
| add_spawn(mon_ant_queen, 1, SEEX, SEEY); | |
| } | |
| else if (terrain_type == ot_ants_larvae) | |
| { | |
| add_spawn(mon_ant_larva, 10, SEEX, SEEY); | |
| } | |
| break; | |
| case ot_tutorial: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if (j == 0 || j == SEEY * 2 - 1) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else if (i == 0 || i == SEEX * 2 - 1) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else if (j == SEEY) | |
| { | |
| if (i % 4 == 2) | |
| { | |
| ter(i, j) = t_door_c; | |
| } | |
| else if (i % 5 == 3) | |
| { | |
| ter(i, j) = t_window; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| } | |
| else | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| } | |
| } | |
| ter(7, SEEY * 2 - 4) = t_rack; | |
| ter(SEEX * 2 - 2, SEEY * 2 - 4) = t_gas_pump; | |
| if (t_above != ot_null) | |
| { | |
| ter(SEEX - 2, SEEY + 2) = t_stairs_up; | |
| ter(2, 2) = t_water_sh; | |
| ter(2, 3) = t_water_sh; | |
| ter(3, 2) = t_water_sh; | |
| ter(3, 3) = t_water_sh; | |
| } | |
| else | |
| { | |
| add_item(5, SEEY + 1, (*itypes)[itm_helmet_bike], 0); | |
| add_item(4, SEEY + 1, (*itypes)[itm_backpack], 0); | |
| add_item(3, SEEY + 1, (*itypes)[itm_pants_cargo], 0); | |
| add_item(7, SEEY * 2 - 4, (*itypes)[itm_machete], 0); | |
| add_item(7, SEEY * 2 - 4, (*itypes)[itm_9mm], 0); | |
| add_item(7, SEEY * 2 - 4, (*itypes)[itm_9mmP], 0); | |
| add_item(7, SEEY * 2 - 4, (*itypes)[itm_uzi], 0); | |
| add_item(SEEX * 2 - 2, SEEY + 5, (*itypes)[itm_bubblewrap], 0); | |
| add_item(SEEX * 2 - 2, SEEY + 6, (*itypes)[itm_grenade], 0); | |
| add_item(SEEX * 2 - 3, SEEY + 6, (*itypes)[itm_flashlight], 0); | |
| add_item(SEEX * 2 - 2, SEEY + 7, (*itypes)[itm_cig], 0); | |
| add_item(SEEX * 2 - 2, SEEY + 7, (*itypes)[itm_codeine], 0); | |
| add_item(SEEX * 2 - 3, SEEY + 7, (*itypes)[itm_water], 0); | |
| ter(SEEX - 2, SEEY + 2) = t_stairs_down; | |
| } | |
| break; | |
| case ot_cavern: | |
| n_fac = (t_north == ot_cavern || t_north == ot_subway_ns || | |
| t_north == ot_subway_ew ? 0 : 3); | |
| e_fac = (t_east == ot_cavern || t_east == ot_subway_ns || | |
| t_east == ot_subway_ew ? SEEX * 2 - 1 : SEEX * 2 - 4); | |
| s_fac = (t_south == ot_cavern || t_south == ot_subway_ns || | |
| t_south == ot_subway_ew ? SEEY * 2 - 1 : SEEY * 2 - 4); | |
| w_fac = (t_west == ot_cavern || t_west == ot_subway_ns || | |
| t_west == ot_subway_ew ? 0 : 3); | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| if ((j < n_fac || j > s_fac || i < w_fac || i > e_fac) && | |
| (!one_in(3) || j == 0 || j == SEEY * 2 - 1 || i == 0 || i == SEEX * 2 - 1)) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| else | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| rn = rng(0, 2) * rng(0, 3) + rng(0, 1); // Number of pillars | |
| for (int n = 0; n < rn; n++) | |
| { | |
| int px = rng(5, SEEX * 2 - 6); | |
| int py = rng(5, SEEY * 2 - 6); | |
| for (int i = px - 1; i <= px + 1; i++) | |
| { | |
| for (int j = py - 1; j <= py + 1; j++) | |
| { | |
| ter(i, j) = t_rock; | |
| } | |
| } | |
| } | |
| if (connects_to(t_north, 2)) | |
| { | |
| for (int i = SEEX - 2; i <= SEEX + 3; i++) | |
| { | |
| for (int j = 0; j <= SEEY; j++) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (connects_to(t_east, 3)) | |
| { | |
| for (int i = SEEX; i <= SEEX * 2 - 1; i++) | |
| { | |
| for (int j = SEEY - 2; j <= SEEY + 3; j++) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (connects_to(t_south, 0)) | |
| { | |
| for (int i = SEEX - 2; i <= SEEX + 3; i++) | |
| { | |
| for (int j = SEEY; j <= SEEY * 2 - 1; j++) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| if (connects_to(t_west, 1)) | |
| { | |
| for (int i = 0; i <= SEEX; i++) | |
| { | |
| for (int j = SEEY - 2; j <= SEEY + 3; j++) | |
| { | |
| ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| } | |
| place_items(mi_cavern, 60, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, false, 0); | |
| if (one_in(6)) // Miner remains | |
| { | |
| int x, y; | |
| do | |
| { | |
| x = rng(0, SEEX * 2 - 1); | |
| y = rng(0, SEEY * 2 - 1); | |
| } | |
| while (move_cost(x, y) == 0); | |
| if (!one_in(3)) | |
| { | |
| add_item(x, y, (*itypes)[itm_jackhammer], 0); | |
| } | |
| if (one_in(3)) | |
| { | |
| add_item(x, y, (*itypes)[itm_mask_dust], 0); | |
| } | |
| if (one_in(2)) | |
| { | |
| add_item(x, y, (*itypes)[itm_hat_hard], 0); | |
| } | |
| while (!one_in(3)) | |
| { | |
| add_item(x, y, (*itypes)[rng(itm_can_beans, itm_can_tuna)], 0); | |
| } | |
| } | |
| break; | |
| default: | |
| debugmsg("Error: tried to generate map for omtype %d, \"%s\"", terrain_type, | |
| oterlist[terrain_type].name.c_str()); | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_floor; | |
| } | |
| } | |
| break; | |
| } | |
| // Now, fix sewers and subways so that they interconnect. | |
| if (terrain_type >= ot_subway_ns && terrain_type <= ot_subway_nesw) | |
| { | |
| if (t_north >= ot_sewer_ns && t_north <= ot_sewer_nesw && | |
| !connects_to(terrain_type, 0)) | |
| { | |
| if (connects_to(t_north, 2)) | |
| { | |
| for (int i = SEEX - 2; i < SEEX + 2; i++) | |
| { | |
| for (int j = 0; j < SEEY; j++) | |
| { | |
| ter(i, j) = t_sewage; | |
| } | |
| } | |
| } | |
| else | |
| { | |
| for (int j = 0; j < 3; j++) | |
| { | |
| ter(SEEX, j) = t_rock_floor; | |
| ter(SEEX - 1, j) = t_rock_floor; | |
| } | |
| ter(SEEX, 3) = t_door_metal_c; | |
| ter(SEEX - 1, 3) = t_door_metal_c; | |
| } | |
| } | |
| if (t_east >= ot_sewer_ns && t_east <= ot_sewer_nesw && | |
| !connects_to(terrain_type, 1)) | |
| { | |
| if (connects_to(t_east, 3)) | |
| { | |
| for (int i = SEEX; i < SEEX * 2; i++) | |
| { | |
| for (int j = SEEY - 2; j < SEEY + 2; j++) | |
| { | |
| ter(i, j) = t_sewage; | |
| } | |
| } | |
| } | |
| else | |
| { | |
| for (int i = SEEX * 2 - 3; i < SEEX * 2; i++) | |
| { | |
| ter(i, SEEY) = t_rock_floor; | |
| ter(i, SEEY - 1) = t_rock_floor; | |
| } | |
| ter(SEEX * 2 - 4, SEEY) = t_door_metal_c; | |
| ter(SEEX * 2 - 4, SEEY - 1) = t_door_metal_c; | |
| } | |
| } | |
| if (t_south >= ot_sewer_ns && t_south <= ot_sewer_nesw && | |
| !connects_to(terrain_type, 2)) | |
| { | |
| if (connects_to(t_south, 0)) | |
| { | |
| for (int i = SEEX - 2; i < SEEX + 2; i++) | |
| { | |
| for (int j = SEEY; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = t_sewage; | |
| } | |
| } | |
| } | |
| else | |
| { | |
| for (int j = SEEY * 2 - 3; j < SEEY * 2; j++) | |
| { | |
| ter(SEEX, j) = t_rock_floor; | |
| ter(SEEX - 1, j) = t_rock_floor; | |
| } | |
| ter(SEEX, SEEY * 2 - 4) = t_door_metal_c; | |
| ter(SEEX - 1, SEEY * 2 - 4) = t_door_metal_c; | |
| } | |
| } | |
| if (t_west >= ot_sewer_ns && t_west <= ot_sewer_nesw && | |
| !connects_to(terrain_type, 3)) | |
| { | |
| if (connects_to(t_west, 1)) | |
| { | |
| for (int i = 0; i < SEEX; i++) | |
| { | |
| for (int j = SEEY - 2; j < SEEY + 2; j++) | |
| { | |
| ter(i, j) = t_sewage; | |
| } | |
| } | |
| } | |
| else | |
| { | |
| for (int i = 0; i < 3; i++) | |
| { | |
| ter(i, SEEY) = t_rock_floor; | |
| ter(i, SEEY - 1) = t_rock_floor; | |
| } | |
| ter(3, SEEY) = t_door_metal_c; | |
| ter(3, SEEY - 1) = t_door_metal_c; | |
| } | |
| } | |
| } | |
| else if (terrain_type >= ot_sewer_ns && terrain_type <= ot_sewer_nesw) | |
| { | |
| if (t_above == ot_road_nesw_manhole) | |
| { | |
| ter(rng(SEEX - 2, SEEX + 1), rng(SEEY - 2, SEEY + 1)) = t_ladder_up; | |
| } | |
| if (t_north >= ot_subway_ns && t_north <= ot_subway_nesw && | |
| !connects_to(terrain_type, 0)) | |
| { | |
| for (int j = 0; j < SEEY - 3; j++) | |
| { | |
| ter(SEEX, j) = t_rock_floor; | |
| ter(SEEX - 1, j) = t_rock_floor; | |
| } | |
| ter(SEEX, SEEY - 3) = t_door_metal_c; | |
| ter(SEEX - 1, SEEY - 3) = t_door_metal_c; | |
| } | |
| if (t_east >= ot_subway_ns && t_east <= ot_subway_nesw && | |
| !connects_to(terrain_type, 1)) | |
| { | |
| for (int i = SEEX + 3; i < SEEX * 2; i++) | |
| { | |
| ter(i, SEEY) = t_rock_floor; | |
| ter(i, SEEY - 1) = t_rock_floor; | |
| } | |
| ter(SEEX + 2, SEEY) = t_door_metal_c; | |
| ter(SEEX + 2, SEEY - 1) = t_door_metal_c; | |
| } | |
| if (t_south >= ot_subway_ns && t_south <= ot_subway_nesw && | |
| !connects_to(terrain_type, 2)) | |
| { | |
| for (int j = SEEY + 3; j < SEEY * 2; j++) | |
| { | |
| ter(SEEX, j) = t_rock_floor; | |
| ter(SEEX - 1, j) = t_rock_floor; | |
| } | |
| ter(SEEX, SEEY + 2) = t_door_metal_c; | |
| ter(SEEX - 1, SEEY + 2) = t_door_metal_c; | |
| } | |
| if (t_west >= ot_subway_ns && t_west <= ot_subway_nesw && | |
| !connects_to(terrain_type, 3)) | |
| { | |
| for (int i = 0; i < SEEX - 3; i++) | |
| { | |
| ter(i, SEEY) = t_rock_floor; | |
| ter(i, SEEY - 1) = t_rock_floor; | |
| } | |
| ter(SEEX - 3, SEEY) = t_door_metal_c; | |
| ter(SEEX - 3, SEEY - 1) = t_door_metal_c; | |
| } | |
| } | |
| else if (terrain_type >= ot_ants_ns && terrain_type <= ot_ants_queen) | |
| { | |
| if (t_above == ot_anthill) | |
| { | |
| bool done = false; | |
| do | |
| { | |
| int x = rng(0, SEEX * 2 - 1), y = rng(0, SEEY * 2 - 1); | |
| if (ter(x, y) == t_rock_floor) | |
| { | |
| done = true; | |
| ter(x, y) = t_slope_up; | |
| } | |
| } | |
| while (!done); | |
| } | |
| } | |
| } | |
| void map::post_process(game* g, unsigned zones) | |
| { | |
| std::string junk; | |
| if (zones & mfb(OMZONE_CITY)) | |
| { | |
| if (!one_in(10)) // 90% chance of smashing stuff up | |
| { | |
| for (int x = 0; x < 24; x++) | |
| { | |
| for (int y = 0; y < 24; y++) | |
| { | |
| bash(x, y, 20, junk); | |
| } | |
| } | |
| } | |
| if (one_in(10)) // 10% chance of corpses | |
| { | |
| int num_corpses = rng(1, 8); | |
| for (int i = 0; i < num_corpses; i++) | |
| { | |
| int x = rng(0, 23), y = rng(0, 23); | |
| if (move_cost(x, y) > 0) | |
| { | |
| add_corpse(g, this, x, y); | |
| } | |
| } | |
| } | |
| } // OMZONE_CITY | |
| if (zones & mfb(OMZONE_BOMBED)) | |
| { | |
| while (one_in(4)) | |
| { | |
| point center(rng(4, 19), rng(4, 19)); | |
| int radius = rng(1, 4); | |
| for (int x = center.x - radius; x <= center.x + radius; x++) | |
| { | |
| for (int y = center.y - radius; y <= center.y + radius; y++) | |
| { | |
| if (rl_dist(x, y, center.x, center.y) <= rng(1, radius)) | |
| { | |
| destroy(g, x, y, false); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| void map::place_spawns(game* g, moncat_id monster_type, int chance, int x1, int y1, | |
| int x2, int y2, int min, int max) | |
| { | |
| if (one_in(chance)) | |
| { | |
| const std::vector<mon_id> group = g->moncats[monster_type]; | |
| int num = rng(min, max); | |
| int total_freq = 0; | |
| for (int i = 0; i < group.size(); i++) | |
| if (g->mtypes[group[i]]->frequency > 0) | |
| { | |
| total_freq += g->mtypes[group[i]]->frequency; | |
| } | |
| if (total_freq == 0) | |
| { | |
| return; | |
| } | |
| for (int i = 0; i < num; i++) | |
| { | |
| int tries = 10; | |
| int x = 0; | |
| int y = 0; | |
| // Pick a spot for the spawn | |
| do | |
| { | |
| x = rng(x1, x2); | |
| y = rng(y1, y2); | |
| tries--; | |
| } | |
| while (move_cost(x, y) == 0 && tries); | |
| // Pick a monster type | |
| int choice = rng(0, total_freq); | |
| int monster_index = -1; | |
| do | |
| { | |
| monster_index++; | |
| choice -= g->mtypes[group[monster_index]]->frequency; | |
| } | |
| while (choice > 0); | |
| add_spawn(group[monster_index], 1, x, y); | |
| } | |
| } | |
| } | |
| void map::place_items(items_location loc, int chance, int x1, int y1, | |
| int x2, int y2, bool ongrass, int turn) | |
| { | |
| std::vector<itype_id> eligible = (*mapitems)[loc]; | |
| if (chance >= 100 || chance <= 0) | |
| { | |
| debugmsg("map::place_items() called with an invalid chance (%d)", chance); | |
| return; | |
| } | |
| if (eligible.size() == 0) // No items here! (Why was it called?) | |
| { | |
| debugmsg("map::place_items() called for an empty items list (list #%d)", loc); | |
| return; | |
| } | |
| int item_chance = 0; // # of items | |
| for (int i = 0; i < eligible.size(); i++) | |
| { | |
| item_chance += (*itypes)[eligible[i]]->rarity; | |
| } | |
| int selection, randnum; | |
| int px, py; | |
| while (rng(0, 99) < chance) | |
| { | |
| randnum = rng(1, item_chance); | |
| selection = -1; | |
| while (randnum > 0) | |
| { | |
| selection++; | |
| if (selection >= eligible.size()) | |
| debugmsg("OOB selection (%d of %d); randnum is %d, item_chance %d", | |
| selection, eligible.size(), randnum, item_chance); | |
| randnum -= (*itypes)[eligible[selection]]->rarity; | |
| } | |
| int tries = 0; | |
| do | |
| { | |
| px = rng(x1, x2); | |
| py = rng(y1, y2); | |
| tries++; | |
| // Only place on valid terrain | |
| } | |
| while (((terlist[ter(px, py)].movecost == 0 && | |
| !(terlist[ter(px, py)].flags & mfb(place_item))) || | |
| (!ongrass && (ter(px, py) == t_dirt || ter(px, py) == t_grass))) && | |
| tries < 20); | |
| if (tries < 20) | |
| { | |
| add_item(px, py, (*itypes)[eligible[selection]], turn); | |
| // Guns in the home and behind counters are generated with their ammo | |
| // TODO: Make this less of a hack | |
| if ((*itypes)[eligible[selection]]->is_gun() && | |
| (loc == mi_homeguns || loc == mi_behindcounter)) | |
| { | |
| it_gun* tmpgun = dynamic_cast<it_gun*>((*itypes)[eligible[selection]]); | |
| add_item(px, py, (*itypes)[default_ammo(tmpgun->ammo)], turn); | |
| } | |
| } | |
| } | |
| } | |
| void map::put_items_from(items_location loc, int num, int x, int y, int turn) | |
| { | |
| std::vector<itype_id> eligible = (*mapitems)[loc]; | |
| int item_chance = 0; // # of items | |
| for (int i = 0; i < eligible.size(); i++) | |
| { | |
| item_chance += (*itypes)[eligible[i]]->rarity; | |
| } | |
| for (int i = 0; i < num; i++) | |
| { | |
| int selection, randnum; | |
| randnum = rng(1, item_chance); | |
| selection = -1; | |
| while (randnum > 0) | |
| { | |
| selection++; | |
| if (selection >= eligible.size()) | |
| debugmsg("OOB selection (%d of %d); randnum is %d, item_chance %d", | |
| selection, eligible.size(), randnum, item_chance); | |
| randnum -= (*itypes)[eligible[selection]]->rarity; | |
| } | |
| add_item(x, y, (*itypes)[eligible[selection]], turn); | |
| } | |
| } | |
| void map::add_spawn(mon_id type, int count, int x, int y, bool friendly, | |
| int faction_id, int mission_id, std::string name) | |
| { | |
| if (x < 0 || x >= SEEX * my_MAPSIZE || y < 0 || y >= SEEY * my_MAPSIZE) | |
| { | |
| debugmsg("Bad add_spawn(%d, %d, %d, %d)", type, count, x, y); | |
| return; | |
| } | |
| int nonant = int(x / SEEX) + int(y / SEEY) * my_MAPSIZE; | |
| if (!grid[nonant]) | |
| { | |
| debugmsg("centadodecamonant doesn't exist in grid; within add_spawn(%d, %d, %d, %d)", | |
| type, count, x, y); | |
| return; | |
| } | |
| x %= SEEX; | |
| y %= SEEY; | |
| spawn_point tmp(type, count, x, y, faction_id, mission_id, friendly, name); | |
| grid[nonant]->spawns.push_back(tmp); | |
| } | |
| void map::add_spawn(monster* mon) | |
| { | |
| int spawnx, spawny; | |
| std::string spawnname = (mon->unique_name == "" ? "NONE" : mon->unique_name); | |
| if (mon->spawnmapx != -1) | |
| { | |
| spawnx = mon->spawnposx; | |
| spawny = mon->spawnposy; | |
| } | |
| else | |
| { | |
| spawnx = mon->posx; | |
| spawny = mon->posy; | |
| } | |
| while (spawnx < 0) | |
| { | |
| spawnx += SEEX; | |
| } | |
| while (spawny < 0) | |
| { | |
| spawny += SEEY; | |
| } | |
| spawnx %= SEEX; | |
| spawny %= SEEY; | |
| add_spawn(mon_id(mon->type->id), 1, spawnx, spawny, (mon->friendly < 0), | |
| mon->faction_id, mon->mission_id, spawnname); | |
| } | |
| vehicle* map::add_vehicle(game* g, vhtype_id type, int x, int y, int dir) | |
| { | |
| if (x < 0 || x >= SEEX * my_MAPSIZE || y < 0 || y >= SEEY * my_MAPSIZE) | |
| { | |
| debugmsg("Bad add_vehicle t=%d d=%d x=%d y=%d", type, dir, x, y); | |
| return 0; | |
| } | |
| // debugmsg("add_vehicle t=%d d=%d x=%d y=%d", type, dir, x, y); | |
| int smx = x / SEEX; | |
| int smy = y / SEEY; | |
| int nonant = smx + smy * my_MAPSIZE; | |
| x %= SEEX; | |
| y %= SEEY; | |
| // debugmsg("n=%d x=%d y=%d MAPSIZE=%d ^2=%d", nonant, x, y, MAPSIZE, MAPSIZE*MAPSIZE); | |
| vehicle* veh = new vehicle(g, type); | |
| veh->posx = x; | |
| veh->posy = y; | |
| veh->smx = smx; | |
| veh->smy = smy; | |
| veh->face.init(dir); | |
| veh->turn_dir = dir; | |
| veh->precalc_mounts(0, dir); | |
| grid[nonant]->vehicles.push_back(veh); | |
| vehicle_list.insert(veh); | |
| update_vehicle_cache(veh, true); | |
| //debugmsg ("grid[%d]->vehicles.size=%d veh.parts.size=%d", nonant, grid[nonant]->vehicles.size(),veh.parts.size()); | |
| return veh; | |
| } | |
| computer* map::add_computer(int x, int y, std::string name, int security) | |
| { | |
| ter(x, y) = t_console; // TODO: Turn this off? | |
| int nonant = int(x / SEEX) + int(y / SEEY) * my_MAPSIZE; | |
| grid[nonant]->comp = computer(name, security); | |
| return &(grid[nonant]->comp); | |
| } | |
| void map::rotate(int turns) | |
| { | |
| ter_id rotated [SEEX * 2][SEEY * 2]; | |
| trap_id traprot [SEEX * 2][SEEY * 2]; | |
| std::vector<item> itrot[SEEX * 2][SEEY * 2]; | |
| std::vector<spawn_point> sprot[MAPSIZE * MAPSIZE]; | |
| computer tmpcomp; | |
| std::vector<vehicle*> tmpveh; | |
| switch (turns) | |
| { | |
| case 1: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| rotated[i][j] = ter(j, SEEX * 2 - 1 - i); | |
| itrot [i][j] = i_at(j, SEEX * 2 - 1 - i); | |
| traprot[i][j] = tr_at(j, SEEX * 2 - 1 - i); | |
| i_clear(j, SEEX * 2 - 1 - i); | |
| } | |
| } | |
| // Now, spawn points | |
| for (int sx = 0; sx < 2; sx++) | |
| { | |
| for (int sy = 0; sy < 2; sy++) | |
| { | |
| int gridfrom = sx + sy * my_MAPSIZE; | |
| int gridto = sx * my_MAPSIZE + 1 - sy; | |
| for (int j = 0; j < grid[gridfrom]->spawns.size(); j++) | |
| { | |
| spawn_point tmp = grid[gridfrom]->spawns[j]; | |
| int tmpy = tmp.posy; | |
| tmp.posy = tmp.posx; | |
| tmp.posx = SEEY - 1 - tmpy; | |
| sprot[gridto].push_back(tmp); | |
| } | |
| } | |
| } | |
| // Finally, computers | |
| tmpcomp = grid[0]->comp; | |
| grid[0]->comp = grid[my_MAPSIZE]->comp; | |
| grid[my_MAPSIZE]->comp = grid[my_MAPSIZE + 1]->comp; | |
| grid[my_MAPSIZE + 1]->comp = grid[1]->comp; | |
| grid[1]->comp = tmpcomp; | |
| // ...and vehicles | |
| tmpveh = grid[0]->vehicles; | |
| grid[0]->vehicles = grid[my_MAPSIZE]->vehicles; | |
| grid[my_MAPSIZE]->vehicles = grid[my_MAPSIZE + 1]->vehicles; | |
| grid[my_MAPSIZE + 1]->vehicles = grid[1]->vehicles; | |
| grid[1]->vehicles = tmpveh; | |
| break; | |
| case 2: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| rotated[i][j] = ter(SEEX * 2 - 1 - i, SEEY * 2 - 1 - j); | |
| itrot [i][j] = i_at(SEEX * 2 - 1 - i, SEEY * 2 - 1 - j); | |
| traprot[i][j] = tr_at(SEEX * 2 - 1 - i, SEEY * 2 - 1 - j); | |
| i_clear(SEEX * 2 - 1 - i, SEEY * 2 - 1 - j); | |
| } | |
| } | |
| // Now, spawn points | |
| for (int sx = 0; sx < 2; sx++) | |
| { | |
| for (int sy = 0; sy < 2; sy++) | |
| { | |
| int gridfrom = sx + sy * my_MAPSIZE; | |
| int gridto = (1 - sy) * my_MAPSIZE + 1 - sx; | |
| for (int j = 0; j < grid[gridfrom]->spawns.size(); j++) | |
| { | |
| spawn_point tmp = grid[gridfrom]->spawns[j]; | |
| tmp.posy = SEEY - 1 - tmp.posy; | |
| tmp.posx = SEEX - 1 - tmp.posx; | |
| sprot[gridto].push_back(tmp); | |
| } | |
| } | |
| } | |
| tmpcomp = grid[0]->comp; | |
| grid[0]->comp = grid[my_MAPSIZE + 1]->comp; | |
| grid[my_MAPSIZE + 1]->comp = tmpcomp; | |
| tmpcomp = grid[1]->comp; | |
| grid[1]->comp = grid[my_MAPSIZE]->comp; | |
| grid[my_MAPSIZE]->comp = tmpcomp; | |
| // ...and vehicles | |
| tmpveh = grid[0]->vehicles; | |
| grid[0]->vehicles = grid[my_MAPSIZE + 1]->vehicles; | |
| grid[my_MAPSIZE + 1]->vehicles = tmpveh; | |
| tmpveh = grid[1]->vehicles; | |
| grid[1]->vehicles = grid[my_MAPSIZE]->vehicles; | |
| grid[my_MAPSIZE]->vehicles = tmpveh; | |
| break; | |
| case 3: | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| rotated[i][j] = ter(SEEY * 2 - 1 - j, i); | |
| itrot [i][j] = i_at(SEEY * 2 - 1 - j, i); | |
| traprot[i][j] = tr_at(SEEY * 2 - 1 - j, i); | |
| i_clear(SEEY * 2 - 1 - j, i); | |
| } | |
| } | |
| // Now, spawn points | |
| for (int sx = 0; sx < 2; sx++) | |
| { | |
| for (int sy = 0; sy < 2; sy++) | |
| { | |
| int gridfrom = sx + sy * my_MAPSIZE; | |
| int gridto = (1 - sx) * my_MAPSIZE + sy; | |
| for (int j = 0; j < grid[gridfrom]->spawns.size(); j++) | |
| { | |
| spawn_point tmp = grid[gridfrom]->spawns[j]; | |
| int tmpy = tmp.posy; | |
| tmp.posy = SEEX - 1 - tmp.posx; | |
| tmp.posx = tmpy; | |
| sprot[gridto].push_back(tmp); | |
| } | |
| } | |
| } | |
| tmpcomp = grid[0]->comp; | |
| grid[0]->comp = grid[1]->comp; | |
| grid[1]->comp = grid[my_MAPSIZE + 1]->comp; | |
| grid[my_MAPSIZE + 1]->comp = grid[my_MAPSIZE]->comp; | |
| grid[my_MAPSIZE]->comp = tmpcomp; | |
| // ...and vehicles | |
| tmpveh = grid[0]->vehicles; | |
| grid[0]->vehicles = grid[1]->vehicles; | |
| grid[1]->vehicles = grid[my_MAPSIZE + 1]->vehicles; | |
| grid[my_MAPSIZE + 1]->vehicles = grid[my_MAPSIZE]->vehicles; | |
| grid[my_MAPSIZE]->vehicles = tmpveh; | |
| break; | |
| default: | |
| return; | |
| } | |
| // change vehicles' directions | |
| for (int i = 0; i < my_MAPSIZE * my_MAPSIZE; i++) | |
| for (int v = 0; v < grid[i]->vehicles.size(); v++) | |
| if (turns >= 1 && turns <= 3) | |
| { | |
| grid[i]->vehicles[v]->turn(turns * 90); | |
| } | |
| // Set the spawn points | |
| grid[0]->spawns = sprot[0]; | |
| grid[1]->spawns = sprot[1]; | |
| grid[my_MAPSIZE]->spawns = sprot[my_MAPSIZE]; | |
| grid[my_MAPSIZE + 1]->spawns = sprot[my_MAPSIZE + 1]; | |
| for (int i = 0; i < SEEX * 2; i++) | |
| { | |
| for (int j = 0; j < SEEY * 2; j++) | |
| { | |
| ter(i, j) = rotated[i][j]; | |
| i_at(i, j) = itrot [i][j]; | |
| tr_at(i, j) = traprot[i][j]; | |
| if (turns % 2 == 1) // Rotate things like walls 90 degrees | |
| { | |
| if (ter(i, j) == t_wall_v) | |
| { | |
| ter(i, j) = t_wall_h; | |
| } | |
| else if (ter(i, j) == t_wall_h) | |
| { | |
| ter(i, j) = t_wall_v; | |
| } | |
| else if (ter(i, j) == t_wall_metal_v) | |
| { | |
| ter(i, j) = t_wall_metal_h; | |
| } | |
| else if (ter(i, j) == t_wall_metal_h) | |
| { | |
| ter(i, j) = t_wall_metal_v; | |
| } | |
| else if (ter(i, j) == t_railing_v) | |
| { | |
| ter(i, j) = t_railing_h; | |
| } | |
| else if (ter(i, j) == t_railing_h) | |
| { | |
| ter(i, j) = t_railing_v; | |
| } | |
| else if (ter(i, j) == t_wall_glass_h) | |
| { | |
| ter(i, j) = t_wall_glass_v; | |
| } | |
| else if (ter(i, j) == t_wall_glass_v) | |
| { | |
| ter(i, j) = t_wall_glass_h; | |
| } | |
| else if (ter(i, j) == t_wall_glass_h_alarm) | |
| { | |
| ter(i, j) = t_wall_glass_v_alarm; | |
| } | |
| else if (ter(i, j) == t_wall_glass_v_alarm) | |
| { | |
| ter(i, j) = t_wall_glass_h_alarm; | |
| } | |
| else if (ter(i, j) == t_reinforced_glass_h) | |
| { | |
| ter(i, j) = t_reinforced_glass_v; | |
| } | |
| else if (ter(i, j) == t_reinforced_glass_v) | |
| { | |
| ter(i, j) = t_reinforced_glass_h; | |
| } | |
| else if (ter(i, j) == t_fence_v) | |
| { | |
| ter(i, j) = t_fence_h; | |
| } | |
| else if (ter(i, j) == t_fence_h) | |
| { | |
| ter(i, j) = t_fence_v; | |
| } | |
| else if (ter(i, j) == t_chainfence_h) | |
| { | |
| ter(i, j) = t_chainfence_v; | |
| } | |
| else if (ter(i, j) == t_chainfence_v) | |
| { | |
| ter(i, j) = t_chainfence_h; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // Hideous function, I admit... | |
| bool connects_to(oter_id there, int dir) | |
| { | |
| switch (dir) | |
| { | |
| case 2: | |
| if (there == ot_subway_ns || there == ot_subway_es || there == ot_subway_sw || | |
| there == ot_subway_nes || there == ot_subway_nsw || | |
| there == ot_subway_esw || there == ot_subway_nesw || | |
| there == ot_sewer_ns || there == ot_sewer_es || there == ot_sewer_sw || | |
| there == ot_sewer_nes || there == ot_sewer_nsw || there == ot_sewer_esw || | |
| there == ot_sewer_nesw || there == ot_ants_ns || there == ot_ants_es || | |
| there == ot_ants_sw || there == ot_ants_nes || there == ot_ants_nsw || | |
| there == ot_ants_esw || there == ot_ants_nesw) | |
| { | |
| return true; | |
| } | |
| return false; | |
| case 3: | |
| if (there == ot_subway_ew || there == ot_subway_sw || there == ot_subway_wn || | |
| there == ot_subway_new || there == ot_subway_nsw || | |
| there == ot_subway_esw || there == ot_subway_nesw || | |
| there == ot_sewer_ew || there == ot_sewer_sw || there == ot_sewer_wn || | |
| there == ot_sewer_new || there == ot_sewer_nsw || there == ot_sewer_esw || | |
| there == ot_sewer_nesw || there == ot_ants_ew || there == ot_ants_sw || | |
| there == ot_ants_wn || there == ot_ants_new || there == ot_ants_nsw || | |
| there == ot_ants_esw || there == ot_ants_nesw) | |
| { | |
| return true; | |
| } | |
| return false; | |
| case 0: | |
| if (there == ot_subway_ns || there == ot_subway_ne || there == ot_subway_wn || | |
| there == ot_subway_nes || there == ot_subway_new || | |
| there == ot_subway_nsw || there == ot_subway_nesw || | |
| there == ot_sewer_ns || there == ot_sewer_ne || there == ot_sewer_wn || | |
| there == ot_sewer_nes || there == ot_sewer_new || there == ot_sewer_nsw || | |
| there == ot_sewer_nesw || there == ot_ants_ns || there == ot_ants_ne || | |
| there == ot_ants_wn || there == ot_ants_nes || there == ot_ants_new || | |
| there == ot_ants_nsw || there == ot_ants_nesw) | |
| { | |
| return true; | |
| } | |
| return false; | |
| case 1: | |
| if (there == ot_subway_ew || there == ot_subway_ne || there == ot_subway_es || | |
| there == ot_subway_nes || there == ot_subway_new || | |
| there == ot_subway_esw || there == ot_subway_nesw || | |
| there == ot_sewer_ew || there == ot_sewer_ne || there == ot_sewer_es || | |
| there == ot_sewer_nes || there == ot_sewer_new || there == ot_sewer_esw || | |
| there == ot_sewer_nesw || there == ot_ants_ew || there == ot_ants_ne || | |
| there == ot_ants_es || there == ot_ants_nes || there == ot_ants_new || | |
| there == ot_ants_esw || there == ot_ants_nesw) | |
| { | |
| return true; | |
| } | |
| return false; | |
| default: | |
| debugmsg("Connects_to with dir of %d", dir); | |
| return false; | |
| } | |
| } | |
| void house_room(map* m, room_type type, int x1, int y1, int x2, int y2) | |
| { | |
| int pos_x1 = 0; | |
| int pos_x2 = 0; | |
| int pos_y1 = 0; | |
| int pos_y2 = 0; | |
| for (int i = x1; i <= x2; i++) | |
| { | |
| for (int j = y1; j <= y2; j++) | |
| { | |
| if (m->ter(i, j) == t_grass || m->ter(i, j) == t_dirt || | |
| m->ter(i, j) == t_floor) | |
| { | |
| if (j == y1 || j == y2) | |
| { | |
| m->ter(i, j) = t_wall_h; | |
| m->ter(i, j) = t_wall_h; | |
| } | |
| else if (i == x1 || i == x2) | |
| { | |
| m->ter(i, j) = t_wall_v; | |
| m->ter(i, j) = t_wall_v; | |
| } | |
| else | |
| { | |
| m->ter(i, j) = t_floor; | |
| } | |
| } | |
| } | |
| } | |
| for (int i = y1 + 1; i <= y2 - 1; i++) | |
| { | |
| m->ter(x1, i) = t_wall_v; | |
| m->ter(x2, i) = t_wall_v; | |
| } | |
| items_location placed = mi_none; | |
| int chance = 0, rn; | |
| switch (type) | |
| { | |
| case room_living: | |
| placed = mi_livingroom; | |
| chance = 83; | |
| //choose random wall | |
| switch (rng(1, 4)) //some bookshelves | |
| { | |
| case 1: | |
| pos_x1 = x1 + 2; | |
| pos_y1 = y1 + 1; | |
| m->ter(x1 + 2, y2 - 1) = t_desk; | |
| while (pos_x1 < x2) | |
| { | |
| pos_x1 += 1; | |
| if ((m->ter(pos_x1, pos_y1) == t_wall_h) || (m->ter(pos_x1, pos_y1) == t_wall_v)) | |
| { | |
| break; | |
| } | |
| m->ter(pos_x1, pos_y1) = t_bookcase; | |
| pos_x1 += 1; | |
| if ((m->ter(pos_x1, pos_y1) == t_wall_h) || (m->ter(pos_x1, pos_y1) == t_wall_v)) | |
| { | |
| break; | |
| } | |
| m->ter(pos_x1, pos_y1) = t_bookcase; | |
| pos_x1 += 2; | |
| } | |
| break; | |
| case 2: | |
| pos_x1 = x2 - 2; | |
| pos_y1 = y1 + 1; | |
| m->ter(x1 + 2, y2 - 1) = t_desk; | |
| while (pos_x1 > x1) | |
| { | |
| pos_x1 -= 1; | |
| if ((m->ter(pos_x1, pos_y1) == t_wall_h) || (m->ter(pos_x1, pos_y1) == t_wall_v)) | |
| { | |
| break; | |
| } | |
| m->ter(pos_x1, pos_y1) = t_bookcase; | |
| pos_x1 -= 1; | |
| if ((m->ter(pos_x1, pos_y1) == t_wall_h) || (m->ter(pos_x1, pos_y1) == t_wall_v)) | |
| { | |
| break; | |
| } | |
| m->ter(pos_x1, pos_y1) = t_bookcase; | |
| pos_x1 -= 2; | |
| } | |
| break; | |
| case 3: | |
| pos_x1 = x1 + 2; | |
| pos_y1 = y2 - 1; | |
| m->ter(x1 - 2, y2 - 1) = t_desk; | |
| while (pos_x1 < x2) | |
| { | |
| pos_x1 += 1; | |
| if ((m->ter(pos_x1, pos_y1) == t_wall_h) || (m->ter(pos_x1, pos_y1) == t_wall_v)) | |
| { | |
| break; | |
| } | |
| m->ter(pos_x1, pos_y1) = t_bookcase; | |
| pos_x1 += 1; | |
| if ((m->ter(pos_x1, pos_y1) == t_wall_h) || (m->ter(pos_x1, pos_y1) == t_wall_v)) | |
| { | |
| break; | |
| } | |
| m->ter(pos_x1, pos_y1) = t_bookcase; | |
| pos_x1 += 2; | |
| } | |
| break; | |
| case 4: | |
| pos_x1 = x2 - 2; | |
| pos_y1 = y2 - 1; | |
| m->ter(x1 + 2, y2 - 1) = t_desk; | |
| while (pos_x1 > x1) | |
| { | |
| pos_x1 -= 1; | |
| if ((m->ter(pos_x1, pos_y1) == t_wall_h) || (m->ter(pos_x1, pos_y1) == t_wall_v)) | |
| { | |
| break; | |
| } | |
| m->ter(pos_x1, pos_y1) = t_bookcase; | |
| pos_x1 -= 1; | |
| if ((m->ter(pos_x1, pos_y1) == t_wall_h) || (m->ter(pos_x1, pos_y1) == t_wall_v)) | |
| { | |
| break; | |
| } | |
| m->ter(pos_x1, pos_y1) = t_bookcase; | |
| pos_x1 -= 2; | |
| } | |
| break; | |
| m->ter(rng(x1 + 2, x2 - 2), rng(y1 + 1, y2 - 1)) = t_armchair; | |
| } | |
| break; | |
| case room_kitchen: | |
| placed = mi_kitchen; | |
| chance = 75; | |
| m->place_items(mi_cleaning, 58, x1 + 1, y1 + 1, x2 - 1, y2 - 2, false, 0); | |
| m->place_items(mi_home_hw, 40, x1 + 1, y1 + 1, x2 - 1, y2 - 2, false, 0); | |
| switch (rng(1, 4)) //fridge, sink, oven and some cupboards near them | |
| { | |
| case 1: | |
| m->ter(x1 + 2, y1 + 1) = t_fridge; | |
| m->place_items(mi_fridge, 82, x1 + 2, y1 + 1, x1 + 2, y1 + 1, false, 0); | |
| m->ter(x1 + 1, y1 + 1) = t_sink; | |
| if (x1 + 4 < x2) | |
| { | |
| m->ter(x1 + 3, y1 + 1) = t_oven; | |
| m->ter(x1 + 4, y1 + 1) = t_cupboard; | |
| } | |
| break; | |
| case 2: | |
| m->ter(x2 - 2, y1 + 1) = t_fridge; | |
| m->place_items(mi_fridge, 82, x2 - 2, y1 + 1, x2 - 2, y1 + 1, false, 0); | |
| m->ter(x2 - 1, y1 + 1) = t_sink; | |
| if (x2 - 4 > x1) | |
| { | |
| m->ter(x2 - 3, y1 + 1) = t_oven; | |
| m->ter(x2 - 4, y1 + 1) = t_cupboard; | |
| } | |
| break; | |
| case 3: | |
| m->ter(x1 + 2, y2 - 1) = t_fridge; | |
| m->place_items(mi_fridge, 82, x1 + 2, y2 - 1, x1 + 2, y2 - 1, false, 0); | |
| m->ter(x1 + 1, y2 - 1) = t_sink; | |
| if (x1 + 4 < x2) | |
| { | |
| m->ter(x1 + 3, y2 - 1) = t_oven; | |
| m->ter(x1 + 4, y2 - 1) = t_cupboard; | |
| } | |
| break; | |
| case 4: | |
| m->ter(x2 - 2, y2 - 1) = t_fridge; | |
| m->place_items(mi_fridge, 82, x2 - 2, y2 - 1, x2 - 2, y2 - 1, false, 0); | |
| m->ter(x2 - 1, y2 - 1) = t_sink; | |
| if (x2 - 4 > x1) | |
| { | |
| m->ter(x2 - 3, y2 - 1) = t_oven; | |
| m->ter(x2 - 4, y2 - 1) = t_cupboard; | |
| } | |
| break; | |
| } | |
| if (one_in(2)) //dining table in the kitchen | |
| { | |
| square(m, t_table, int((x1 + x2) / 2) - 1, int((y1 + y2) / 2) - 1, int((x1 + x2) / 2), int((y1 + y2) / 2)); | |
| } | |
| if (one_in(2)) | |
| { | |
| for (int i = 0; i <= 2; i++) | |
| { | |
| pos_x1 = rng(x1 + 2, x2 - 2); | |
| pos_y1 = rng(y1 + 1, y2 - 1); | |
| if (m->ter(pos_x1, pos_y1) == t_floor) | |
| { | |
| m->ter(pos_x1, pos_y1) = t_chair; | |
| } | |
| } | |
| } | |
| break; | |
| case room_bedroom: | |
| placed = mi_bedroom; | |
| chance = 78; | |
| if (one_in(14)) | |
| { | |
| m->place_items(mi_homeguns, 58, x1 + 1, y1 + 1, x2 - 1, y2 - 1, false, 0); | |
| } | |
| if (one_in(10)) | |
| { | |
| m->place_items(mi_home_hw, 40, x1 + 1, y1 + 1, x2 - 1, y2 - 1, false, 0); | |
| } | |
| switch (rng(1, 5)) | |
| { | |
| case 1: | |
| m->ter(x1 + 1, y1 + 2) = t_bed; | |
| m->ter(x1 + 1, y1 + 3) = t_bed; | |
| break; | |
| case 2: | |
| m->ter(x1 + 2, y2 - 1) = t_bed; | |
| m->ter(x1 + 3, y2 - 1) = t_bed; | |
| break; | |
| case 3: | |
| m->ter(x2 - 1, y2 - 3) = t_bed; | |
| m->ter(x2 - 1, y2 - 2) = t_bed; | |
| break; | |
| case 4: | |
| m->ter(x2 - 3, y1 + 1) = t_bed; | |
| m->ter(x2 - 2, y1 + 1) = t_bed; | |
| break; | |
| case 5: | |
| m->ter(int((x1 + x2) / 2) , y2 - 1) = t_bed; | |
| m->ter(int((x1 + x2) / 2) + 1, y2 - 1) = t_bed; | |
| m->ter(int((x1 + x2) / 2) , y2 - 2) = t_bed; | |
| m->ter(int((x1 + x2) / 2) + 1, y2 - 2) = t_bed; | |
| break; | |
| } | |
| switch (rng(1, 4)) | |
| { | |
| case 1: | |
| m->ter(x1 + 2, y1 + 1) = t_dresser; | |
| m->place_items(mi_dresser, 80, x1 + 2, y1 + 1, x1 + 2, y1 + 1, false, 0); | |
| break; | |
| case 2: | |
| m->ter(x2 - 2, y2 - 1) = t_dresser; | |
| m->place_items(mi_dresser, 80, x2 - 2, y2 - 1, x2 - 2, y2 - 1, false, 0); | |
| break; | |
| case 3: | |
| rn = int((x1 + x2) / 2); | |
| m->ter(rn, y1 + 1) = t_dresser; | |
| m->place_items(mi_dresser, 80, rn, y1 + 1, rn, y1 + 1, false, 0); | |
| break; | |
| case 4: | |
| rn = int((y1 + y2) / 2); | |
| m->ter(x1 + 1, rn) = t_dresser; | |
| m->place_items(mi_dresser, 80, x1 + 1, rn, x1 + 1, rn, false, 0); | |
| break; | |
| } | |
| break; | |
| case room_bathroom: | |
| m->ter(x2 - 1, y2 - 1) = t_toilet; | |
| m->place_items(mi_harddrugs, 18, x1 + 1, y1 + 1, x2 - 1, y2 - 2, false, 0); | |
| m->place_items(mi_cleaning, 48, x1 + 1, y1 + 1, x2 - 1, y2 - 2, false, 0); | |
| placed = mi_softdrugs; | |
| chance = 72; | |
| m->ter(x2 - 1, y2 - 2) = t_bathtub; | |
| if (!((m->ter(x2 - 3, y2 - 2) == t_wall_v) || (m->ter(x2 - 3, y2 - 2) == t_wall_h))) | |
| { | |
| m->ter(x2 - 3, y2 - 2) = t_sink; | |
| } | |
| break; | |
| } | |
| m->place_items(placed, chance, x1 + 1, y1 + 1, x2 - 1, y2 - 1, false, 0); | |
| } | |
| void science_room(map* m, int x1, int y1, int x2, int y2, int rotate) | |
| { | |
| int height = y2 - y1; | |
| int width = x2 - x1; | |
| if (rotate % 2 == 1) // Swamp width & height if we're a lateral room | |
| { | |
| int tmp = height; | |
| height = width; | |
| width = tmp; | |
| } | |
| for (int i = x1; i <= x2; i++) | |
| { | |
| for (int j = y1; j <= y2; j++) | |
| { | |
| m->ter(i, j) = t_rock_floor; | |
| } | |
| } | |
| int area = height * width; | |
| std::vector<room_type> valid_rooms; | |
| if (height < 5 && width < 5) | |
| { | |
| valid_rooms.push_back(room_closet); | |
| } | |
| if (height > 6 && width > 3) | |
| { | |
| valid_rooms.push_back(room_lobby); | |
| } | |
| if (height > 4 || width > 4) | |
| { | |
| valid_rooms.push_back(room_chemistry); | |
| } | |
| if ((height > 7 || width > 7) && height > 2 && width > 2) | |
| { | |
| valid_rooms.push_back(room_teleport); | |
| } | |
| if (height > 4 && width > 4) | |
| { | |
| valid_rooms.push_back(room_goo); | |
| } | |
| if (height > 7 && width > 7) | |
| { | |
| valid_rooms.push_back(room_bionics); | |
| } | |
| if (height > 7 && width > 7) | |
| { | |
| valid_rooms.push_back(room_cloning); | |
| } | |
| if (area >= 9) | |
| { | |
| valid_rooms.push_back(room_vivisect); | |
| } | |
| if (height > 5 && width > 4) | |
| { | |
| valid_rooms.push_back(room_dorm); | |
| } | |
| if (width > 8) | |
| { | |
| for (int i = 8; i < width; i += rng(1, 2)) | |
| { | |
| valid_rooms.push_back(room_split); | |
| } | |
| } | |
| room_type chosen = valid_rooms[rng(0, valid_rooms.size() - 1)]; | |
| int trapx = rng(x1 + 1, x2 - 1); | |
| int trapy = rng(y1 + 1, y2 - 1); | |
| switch (chosen) | |
| { | |
| case room_closet: | |
| m->place_items(mi_cleaning, 80, x1, y1, x2, y2, false, 0); | |
| break; | |
| case room_lobby: | |
| if (rotate % 2 == 0) // Vertical | |
| { | |
| int desk = y1 + rng(int(height / 2) - int(height / 4), int(height / 2) + 1); | |
| for (int x = x1 + int(width / 4); x < x2 - int(width / 4); x++) | |
| { | |
| m->ter(x, desk) = t_counter; | |
| } | |
| computer* tmpcomp = m->add_computer(x2 - int(width / 4), desk, | |
| "Log Console", 3); | |
| tmpcomp->add_option("View Research Logs", COMPACT_RESEARCH, 0); | |
| tmpcomp->add_option("Download Map Data", COMPACT_MAPS, 0); | |
| tmpcomp->add_failure(COMPFAIL_SHUTDOWN); | |
| tmpcomp->add_failure(COMPFAIL_ALARM); | |
| tmpcomp->add_failure(COMPFAIL_DAMAGE); | |
| m->add_spawn(mon_turret, 1, int((x1 + x2) / 2), desk); | |
| } | |
| else | |
| { | |
| int desk = x1 + rng(int(height / 2) - int(height / 4), int(height / 2) + 1); | |
| for (int y = y1 + int(width / 4); y < y2 - int(width / 4); y++) | |
| { | |
| m->ter(desk, y) = t_counter; | |
| } | |
| computer* tmpcomp = m->add_computer(desk, y2 - int(width / 4), | |
| "Log Console", 3); | |
| tmpcomp->add_option("View Research Logs", COMPACT_RESEARCH, 0); | |
| tmpcomp->add_option("Download Map Data", COMPACT_MAPS, 0); | |
| tmpcomp->add_failure(COMPFAIL_SHUTDOWN); | |
| tmpcomp->add_failure(COMPFAIL_ALARM); | |
| tmpcomp->add_failure(COMPFAIL_DAMAGE); | |
| m->add_spawn(mon_turret, 1, desk, int((y1 + y2) / 2)); | |
| } | |
| break; | |
| case room_chemistry: | |
| if (rotate % 2 == 0) // Vertical | |
| { | |
| for (int x = x1; x <= x2; x++) | |
| { | |
| if (x % 3 == 0) | |
| { | |
| for (int y = y1 + 1; y <= y2 - 1; y++) | |
| { | |
| m->ter(x, y) = t_counter; | |
| } | |
| m->place_items(mi_chemistry, 70, x, y1 + 1, x, y2 - 1, false, 0); | |
| } | |
| } | |
| } | |
| else | |
| { | |
| for (int y = y1; y <= y2; y++) | |
| { | |
| if (y % 3 == 0) | |
| { | |
| for (int x = x1 + 1; x <= x2 - 1; x++) | |
| { | |
| m->ter(x, y) = t_counter; | |
| } | |
| m->place_items(mi_chemistry, 70, x1 + 1, y, x2 - 1, y, false, 0); | |
| } | |
| } | |
| } | |
| break; | |
| case room_teleport: | |
| m->ter(int((x1 + x2) / 2) , int((y1 + y2) / 2)) = t_counter; | |
| m->ter(int((x1 + x2) / 2) + 1, int((y1 + y2) / 2)) = t_counter; | |
| m->ter(int((x1 + x2) / 2) , int((y1 + y2) / 2) + 1) = t_counter; | |
| m->ter(int((x1 + x2) / 2) + 1, int((y1 + y2) / 2) + 1) = t_counter; | |
| m->add_trap(trapx, trapy, tr_telepad); | |
| m->place_items(mi_teleport, 70, int((x1 + x2) / 2), | |
| int((y1 + y2) / 2), int((x1 + x2) / 2) + 1, | |
| int((y1 + y2) / 2) + 1, false, 0); | |
| break; | |
| case room_goo: | |
| do | |
| { | |
| m->add_trap(trapx, trapy, tr_goo); | |
| trapx = rng(x1 + 1, x2 - 1); | |
| trapy = rng(y1 + 1, y2 - 1); | |
| } | |
| while (!one_in(5)); | |
| if (rotate == 0) | |
| { | |
| m->tr_at(x1, y2) = tr_null; | |
| m->ter(x1, y2) = t_fridge; | |
| m->place_items(mi_goo, 60, x1, y2, x1, y2, false, 0); | |
| } | |
| else if (rotate == 1) | |
| { | |
| m->tr_at(x1, y1) = tr_null; | |
| m->ter(x1, y1) = t_fridge; | |
| m->place_items(mi_goo, 60, x1, y1, x1, y1, false, 0); | |
| } | |
| else if (rotate == 2) | |
| { | |
| m->tr_at(x2, y1) = tr_null; | |
| m->ter(x2, y1) = t_fridge; | |
| m->place_items(mi_goo, 60, x2, y1, x2, y1, false, 0); | |
| } | |
| else | |
| { | |
| m->tr_at(x2, y2) = tr_null; | |
| m->ter(x2, y2) = t_fridge; | |
| m->place_items(mi_goo, 60, x2, y2, x2, y2, false, 0); | |
| } | |
| break; | |
| case room_cloning: | |
| for (int x = x1 + 1; x <= x2 - 1; x++) | |
| { | |
| for (int y = y1 + 1; y <= y2 - 1; y++) | |
| { | |
| if (x % 3 == 0 && y % 3 == 0) | |
| { | |
| m->ter(x, y) = t_vat; | |
| m->place_items(mi_cloning_vat, 20, x, y, x, y, false, 0); | |
| } | |
| } | |
| } | |
| break; | |
| case room_vivisect: | |
| if (rotate == 0) | |
| { | |
| for (int x = x1; x <= x2; x++) | |
| { | |
| m->ter(x, y2 - 1) = t_counter; | |
| } | |
| m->place_items(mi_dissection, 80, x1, y2 - 1, x2, y2 - 1, false, 0); | |
| } | |
| else if (rotate == 1) | |
| { | |
| for (int y = y1; y <= y2; y++) | |
| { | |
| m->ter(x1 + 1, y) = t_counter; | |
| } | |
| m->place_items(mi_dissection, 80, x1 + 1, y1, x1 + 1, y2, false, 0); | |
| } | |
| else if (rotate == 2) | |
| { | |
| for (int x = x1; x <= x2; x++) | |
| { | |
| m->ter(x, y1 + 1) = t_counter; | |
| } | |
| m->place_items(mi_dissection, 80, x1, y1 + 1, x2, y1 + 1, false, 0); | |
| } | |
| else if (rotate == 3) | |
| { | |
| for (int y = y1; y <= y2; y++) | |
| { | |
| m->ter(x2 - 1, y) = t_counter; | |
| } | |
| m->place_items(mi_dissection, 80, x2 - 1, y1, x2 - 1, y2, false, 0); | |
| } | |
| m->add_trap(int((x1 + x2) / 2), int((y1 + y2) / 2), tr_dissector); | |
| break; | |
| case room_bionics: | |
| if (rotate % 2 == 0) | |
| { | |
| int biox = x1 + 2, bioy = int((y1 + y2) / 2); | |
| m->ter(biox , bioy - 1) = t_wall_h; | |
| m->ter(biox + 1, bioy - 1) = t_wall_h; | |
| m->ter(biox - 1, bioy - 1) = t_wall_h; | |
| m->ter(biox , bioy + 1) = t_wall_h; | |
| m->ter(biox + 1, bioy + 1) = t_wall_h; | |
| m->ter(biox - 1, bioy + 1) = t_wall_h; | |
| m->ter(biox , bioy) = t_counter; | |
| m->ter(biox + 1, bioy) = t_reinforced_glass_v; | |
| m->ter(biox - 1, bioy) = t_wall_v; | |
| m->place_items(mi_bionics_common, 70, biox, bioy, biox, bioy, false, 0); | |
| biox = x2 - 2; | |
| m->ter(biox , bioy - 1) = t_wall_h; | |
| m->ter(biox - 1, bioy - 1) = t_wall_h; | |
| m->ter(biox + 1, bioy - 1) = t_wall_h; | |
| m->ter(biox , bioy + 1) = t_wall_h; | |
| m->ter(biox - 1, bioy + 1) = t_wall_h; | |
| m->ter(biox + 1, bioy + 1) = t_wall_h; | |
| m->ter(biox , bioy) = t_counter; | |
| m->ter(biox - 1, bioy) = t_reinforced_glass_v; | |
| m->ter(biox + 1, bioy) = t_wall_v; | |
| m->place_items(mi_bionics_common, 70, biox, bioy, biox, bioy, false, 0); | |
| int compx = int((x1 + x2) / 2), compy = int((y1 + y2) / 2); | |
| m->ter(compx, compy) = t_console; | |
| computer* tmpcomp = m->add_computer(compx, compy, "Bionic access", 2); | |
| tmpcomp->add_option("Manifest", COMPACT_LIST_BIONICS, 0); | |
| tmpcomp->add_option("Open Chambers", COMPACT_RELEASE, 3); | |
| tmpcomp->add_failure(COMPFAIL_MANHACKS); | |
| tmpcomp->add_failure(COMPFAIL_SECUBOTS); | |
| } | |
| else | |
| { | |
| int bioy = y1 + 2, biox = int((x1 + x2) / 2); | |
| m->ter(biox - 1, bioy) = t_wall_v; | |
| m->ter(biox - 1, bioy + 1) = t_wall_v; | |
| m->ter(biox - 1, bioy - 1) = t_wall_v; | |
| m->ter(biox + 1, bioy) = t_wall_v; | |
| m->ter(biox + 1, bioy + 1) = t_wall_v; | |
| m->ter(biox + 1, bioy - 1) = t_wall_v; | |
| m->ter(biox , bioy) = t_counter; | |
| m->ter(biox , bioy + 1) = t_reinforced_glass_h; | |
| m->ter(biox , bioy - 1) = t_wall_h; | |
| m->place_items(mi_bionics_common, 70, biox, bioy, biox, bioy, false, 0); | |
| bioy = y2 - 2; | |
| m->ter(biox - 1, bioy) = t_wall_v; | |
| m->ter(biox - 1, bioy - 1) = t_wall_v; | |
| m->ter(biox - 1, bioy + 1) = t_wall_v; | |
| m->ter(biox + 1, bioy) = t_wall_v; | |
| m->ter(biox + 1, bioy - 1) = t_wall_v; | |
| m->ter(biox + 1, bioy + 1) = t_wall_v; | |
| m->ter(biox , bioy) = t_counter; | |
| m->ter(biox , bioy - 1) = t_reinforced_glass_h; | |
| m->ter(biox , bioy + 1) = t_wall_h; | |
| m->place_items(mi_bionics_common, 70, biox, bioy, biox, bioy, false, 0); | |
| int compx = int((x1 + x2) / 2), compy = int((y1 + y2) / 2); | |
| m->ter(compx, compy) = t_console; | |
| computer* tmpcomp = m->add_computer(compx, compy, "Bionic access", 2); | |
| tmpcomp->add_option("Manifest", COMPACT_LIST_BIONICS, 0); | |
| tmpcomp->add_option("Open Chambers", COMPACT_RELEASE, 3); | |
| tmpcomp->add_failure(COMPFAIL_MANHACKS); | |
| tmpcomp->add_failure(COMPFAIL_SECUBOTS); | |
| } | |
| break; | |
| case room_dorm: | |
| if (rotate % 2 == 0) | |
| { | |
| for (int y = y1 + 1; y <= y2 - 1; y += 3) | |
| { | |
| m->ter(x1 , y) = t_bed; | |
| m->ter(x1 + 1, y) = t_bed; | |
| m->ter(x2 , y) = t_bed; | |
| m->ter(x2 - 1, y) = t_bed; | |
| m->ter(x1, y + 1) = t_dresser; | |
| m->ter(x2, y + 1) = t_dresser; | |
| m->place_items(mi_dresser, 70, x1, y + 1, x1, y + 1, false, 0); | |
| m->place_items(mi_dresser, 70, x2, y + 1, x2, y + 1, false, 0); | |
| } | |
| } | |
| else if (rotate % 2 == 1) | |
| { | |
| for (int x = x1 + 1; x <= x2 - 1; x += 3) | |
| { | |
| m->ter(x, y1) = t_bed; | |
| m->ter(x, y1 + 1) = t_bed; | |
| m->ter(x, y2) = t_bed; | |
| m->ter(x, y2 - 1) = t_bed; | |
| m->ter(x + 1, y1) = t_dresser; | |
| m->ter(x + 1, y2) = t_dresser; | |
| m->place_items(mi_dresser, 70, x + 1, y1, x + 1, y1, false, 0); | |
| m->place_items(mi_dresser, 70, x + 1, y2, x + 1, y2, false, 0); | |
| } | |
| } | |
| m->place_items(mi_bedroom, 84, x1, y1, x2, y2, false, 0); | |
| break; | |
| case room_split: | |
| if (rotate % 2 == 0) | |
| { | |
| int w1 = int((x1 + x2) / 2) - 2, w2 = int((x1 + x2) / 2) + 2; | |
| for (int y = y1; y <= y2; y++) | |
| { | |
| m->ter(w1, y) = t_wall_v; | |
| m->ter(w2, y) = t_wall_v; | |
| } | |
| m->ter(w1, int((y1 + y2) / 2)) = t_door_metal_c; | |
| m->ter(w2, int((y1 + y2) / 2)) = t_door_metal_c; | |
| science_room(m, x1, y1, w1 - 1, y2, 1); | |
| science_room(m, w2 + 1, y1, x2, y2, 3); | |
| } | |
| else | |
| { | |
| int w1 = int((y1 + y2) / 2) - 2, w2 = int((y1 + y2) / 2) + 2; | |
| for (int x = x1; x <= x2; x++) | |
| { | |
| m->ter(x, w1) = t_wall_h; | |
| m->ter(x, w2) = t_wall_h; | |
| } | |
| m->ter(int((x1 + x2) / 2), w1) = t_door_metal_c; | |
| m->ter(int((x1 + x2) / 2), w2) = t_door_metal_c; | |
| science_room(m, x1, y1, x2, w1 - 1, 2); | |
| science_room(m, x1, w2 + 1, x2, y2, 0); | |
| } | |
| break; | |
| } | |
| } | |
| void set_science_room(map* m, int x1, int y1, bool faces_right, int turn) | |
| { | |
| // TODO: More types! | |
| int type = rng(0, 4); | |
| int x2 = x1 + 7; | |
| int y2 = y1 + 4; | |
| switch (type) | |
| { | |
| case 0: // Empty! | |
| return; | |
| case 1: // Chemistry. | |
| // #######. | |
| // #....... | |
| // #....... | |
| // #....... | |
| // #######. | |
| for (int i = x1; i <= x2; i++) | |
| { | |
| for (int j = y1; j <= y2; j++) | |
| { | |
| if ((i == x1 || j == y1 || j == y2) && i != x1) | |
| { | |
| m->ter(i, j) = t_counter; | |
| } | |
| } | |
| } | |
| m->place_items(mi_chemistry, 85, x1 + 1, y1, x2 - 1, y1, false, 0); | |
| m->place_items(mi_chemistry, 85, x1 + 1, y2, x2 - 1, y2, false, 0); | |
| m->place_items(mi_chemistry, 85, x1, y1 + 1, x1, y2 - 1, false, 0); | |
| break; | |
| case 2: // Hydroponics. | |
| // #....... | |
| // #.~~~~~. | |
| // #....... | |
| // #.~~~~~. | |
| // #....... | |
| for (int i = x1; i <= x2; i++) | |
| { | |
| for (int j = y1; j <= y2; j++) | |
| { | |
| if (i == x1) | |
| { | |
| m->ter(i, j) = t_counter; | |
| } | |
| else if (i > x1 + 1 && i < x2 && (j == y1 + 1 || j == y2 - 1)) | |
| { | |
| m->ter(i, j) = t_water_sh; | |
| } | |
| } | |
| } | |
| m->place_items(mi_chemistry, 80, x1, y1, x1, y2, false, turn - 50); | |
| m->place_items(mi_hydro, 92, x1 + 1, y1 + 1, x2 - 1, y1 + 1, false, turn); | |
| m->place_items(mi_hydro, 92, x1 + 1, y2 - 1, x2 - 1, y2 - 1, false, turn); | |
| break; | |
| case 3: // Electronics. | |
| // #######. | |
| // #....... | |
| // #....... | |
| // #....... | |
| // #######. | |
| for (int i = x1; i <= x2; i++) | |
| { | |
| for (int j = y1; j <= y2; j++) | |
| { | |
| if ((i == x1 || j == y1 || j == y2) && i != x1) | |
| { | |
| m->ter(i, j) = t_counter; | |
| } | |
| } | |
| } | |
| m->place_items(mi_electronics, 85, x1 + 1, y1, x2 - 1, y1, false, turn - 50); | |
| m->place_items(mi_electronics, 85, x1 + 1, y2, x2 - 1, y2, false, turn - 50); | |
| m->place_items(mi_electronics, 85, x1, y1 + 1, x1, y2 - 1, false, turn - 50); | |
| break; | |
| case 4: // Monster research. | |
| // .|.####. | |
| // -|...... | |
| // .|...... | |
| // -|...... | |
| // .|.####. | |
| for (int i = x1; i <= x2; i++) | |
| { | |
| for (int j = y1; j <= y2; j++) | |
| { | |
| if (i == x1 + 1) | |
| { | |
| m->ter(i, j) = t_wall_glass_v; | |
| } | |
| else if (i == x1 && (j == y1 + 1 || j == y2 - 1)) | |
| { | |
| m->ter(i, j) = t_wall_glass_h; | |
| } | |
| else if ((j == y1 || j == y2) && i >= x1 + 3 && i <= x2 - 1) | |
| { | |
| m->ter(i, j) = t_counter; | |
| } | |
| } | |
| } | |
| // TODO: Place a monster in the sealed areas. | |
| m->place_items(mi_monparts, 70, x1 + 3, y1, 2 - 1, y1, false, turn - 100); | |
| m->place_items(mi_monparts, 70, x1 + 3, y2, 2 - 1, y2, false, turn - 100); | |
| break; | |
| } | |
| if (!faces_right) // Flip it. | |
| { | |
| ter_id rotated[SEEX * 2][SEEY * 2]; | |
| std::vector<item> itrot[SEEX * 2][SEEY * 2]; | |
| for (int i = x1; i <= x2; i++) | |
| { | |
| for (int j = y1; j <= y2; j++) | |
| { | |
| rotated[i][j] = m->ter(i, j); | |
| itrot[i][j] = m->i_at(i, j); | |
| } | |
| } | |
| for (int i = x1; i <= x2; i++) | |
| { | |
| for (int j = y1; j <= y2; j++) | |
| { | |
| m->ter(i, j) = rotated[x2 - (i - x1)][j]; | |
| m->i_at(i, j) = itrot[x2 - (i - x1)][j]; | |
| } | |
| } | |
| } | |
| } | |
| void silo_rooms(map* m) | |
| { | |
| std::vector<point> rooms; | |
| std::vector<point> room_sizes; | |
| bool okay = true; | |
| do | |
| { | |
| int x, y, height, width; | |
| if (one_in(2)) // True = top/bottom, False = left/right | |
| { | |
| x = rng(0, SEEX * 2 - 6); | |
| y = rng(0, 4); | |
| if (one_in(2)) | |
| { | |
| y = SEEY * 2 - 2 - y; // Bottom of the screen, not the top | |
| } | |
| width = rng(2, 5); | |
| height = 2; | |
| if (x + width >= SEEX * 2 - 1) | |
| { | |
| width = SEEX * 2 - 2 - x; // Make sure our room isn't too wide | |
| } | |
| } | |
| else | |
| { | |
| x = rng(0, 4); | |
| y = rng(0, SEEY * 2 - 6); | |
| if (one_in(2)) | |
| { | |
| x = SEEX * 2 - 3 - x; // Right side of the screen, not the left | |
| } | |
| width = 2; | |
| height = rng(2, 5); | |
| if (y + height >= SEEY * 2 - 1) | |
| { | |
| height = SEEY * 2 - 2 - y; // Make sure our room isn't too tall | |
| } | |
| } | |
| if (!rooms.empty() && // We need at least one room! | |
| (m->ter(x, y) != t_rock || m->ter(x + width, y + height) != t_rock)) | |
| { | |
| okay = false; | |
| } | |
| else | |
| { | |
| rooms.push_back(point(x, y)); | |
| room_sizes.push_back(point(width, height)); | |
| for (int i = x; i <= x + width; i++) | |
| { | |
| for (int j = y; j <= y + height; j++) | |
| { | |
| if (m->ter(i, j) == t_rock) | |
| { | |
| m->ter(i, j) = t_floor; | |
| } | |
| } | |
| } | |
| items_location used1 = mi_none, used2 = mi_none; | |
| switch (rng(1, 14)) // What type of items go here? | |
| { | |
| case 1: | |
| case 2: | |
| used1 = mi_cannedfood; | |
| used2 = mi_fridge; | |
| break; | |
| case 3: | |
| case 4: | |
| used1 = mi_tools; | |
| break; | |
| case 5: | |
| case 6: | |
| used1 = mi_allguns; | |
| used2 = mi_ammo; | |
| break; | |
| case 7: | |
| used1 = mi_allclothes; | |
| break; | |
| case 8: | |
| used1 = mi_manuals; | |
| break; | |
| case 9: | |
| case 10: | |
| case 11: | |
| used1 = mi_electronics; | |
| break; | |
| case 12: | |
| used1 = mi_survival_tools; | |
| break; | |
| case 13: | |
| case 14: | |
| used1 = mi_radio; | |
| break; | |
| } | |
| if (used1 != mi_none) | |
| { | |
| m->place_items(used1, 78, x, y, x + width, y + height, false, 0); | |
| } | |
| if (used2 != mi_none) | |
| { | |
| m->place_items(used2, 64, x, y, x + width, y + height, false, 0); | |
| } | |
| } | |
| } | |
| while (okay); | |
| m->ter(rooms[0].x, rooms[0].y) = t_stairs_up; | |
| int down_room = rng(0, rooms.size() - 1); | |
| point dp = rooms[down_room], ds = room_sizes[down_room]; | |
| m->ter(dp.x + ds.x, dp.y + ds.y) = t_stairs_down; | |
| rooms.push_back(point(SEEX, SEEY)); // So the center circle gets connected | |
| room_sizes.push_back(point(5, 5)); | |
| while (rooms.size() > 1) | |
| { | |
| int best_dist = 999, closest = 0; | |
| for (int i = 1; i < rooms.size(); i++) | |
| { | |
| int dist = trig_dist(rooms[0].x, rooms[0].y, rooms[i].x, rooms[i].y); | |
| if (dist < best_dist) | |
| { | |
| best_dist = dist; | |
| closest = i; | |
| } | |
| } | |
| // We chose the closest room; now draw a corridor there | |
| point origin = rooms[0], origsize = room_sizes[0], dest = rooms[closest]; | |
| int x = origin.x + origsize.x, y = origin.y + origsize.y; | |
| bool x_first = (abs(origin.x - dest.x) > abs(origin.y - dest.y)); | |
| while (x != dest.x || y != dest.y) | |
| { | |
| if (m->ter(x, y) == t_rock) | |
| { | |
| m->ter(x, y) = t_floor; | |
| } | |
| if ((x_first && x != dest.x) || (!x_first && y == dest.y)) | |
| { | |
| if (dest.x < x) | |
| { | |
| x--; | |
| } | |
| else | |
| { | |
| x++; | |
| } | |
| } | |
| else | |
| { | |
| if (dest.y < y) | |
| { | |
| y--; | |
| } | |
| else | |
| { | |
| y++; | |
| } | |
| } | |
| } | |
| rooms.erase(rooms.begin()); | |
| room_sizes.erase(room_sizes.begin()); | |
| } | |
| } | |
| void build_mine_room(map* m, room_type type, int x1, int y1, int x2, int y2) | |
| { | |
| direction door_side; | |
| std::vector<direction> possibilities; | |
| int midx = int((x1 + x2) / 2), midy = int((y1 + y2) / 2); | |
| if (x2 < SEEX) | |
| { | |
| possibilities.push_back(EAST); | |
| } | |
| if (x1 > SEEX + 1) | |
| { | |
| possibilities.push_back(WEST); | |
| } | |
| if (y1 > SEEY + 1) | |
| { | |
| possibilities.push_back(NORTH); | |
| } | |
| if (y2 < SEEY) | |
| { | |
| possibilities.push_back(SOUTH); | |
| } | |
| if (possibilities.empty()) // We're in the middle of the map! | |
| { | |
| if (midx <= SEEX) | |
| { | |
| possibilities.push_back(EAST); | |
| } | |
| else | |
| { | |
| possibilities.push_back(WEST); | |
| } | |
| if (midy <= SEEY) | |
| { | |
| possibilities.push_back(SOUTH); | |
| } | |
| else | |
| { | |
| possibilities.push_back(NORTH); | |
| } | |
| } | |
| door_side = possibilities[rng(0, possibilities.size() - 1)]; | |
| point door_point; | |
| switch (door_side) | |
| { | |
| case NORTH: | |
| door_point.x = midx; | |
| door_point.y = y1; | |
| break; | |
| case EAST: | |
| door_point.x = x2; | |
| door_point.y = midy; | |
| break; | |
| case SOUTH: | |
| door_point.x = midx; | |
| door_point.y = y2; | |
| break; | |
| case WEST: | |
| door_point.x = x1; | |
| door_point.y = midy; | |
| break; | |
| } | |
| square(m, t_floor, x1, y1, x2, y2); | |
| line(m, t_wall_h, x1, y1, x2, y1); | |
| line(m, t_wall_h, x1, y2, x2, y2); | |
| line(m, t_wall_v, x1, y1 + 1, x1, y2 - 1); | |
| line(m, t_wall_v, x2, y1 + 1, x2, y2 - 1); | |
| // Main build switch! | |
| switch (type) | |
| { | |
| case room_mine_shaft: | |
| { | |
| m->ter(x1 + 1, y1 + 1) = t_console; | |
| line(m, t_wall_h, x2 - 2, y1 + 2, x2 - 1, y1 + 2); | |
| m->ter(x2 - 2, y1 + 1) = t_elevator; | |
| m->ter(x2 - 1, y1 + 1) = t_elevator_control_off; | |
| computer* tmpcomp = m->add_computer(x1 + 1, y1 + 1, "NEPowerOS", 2); | |
| tmpcomp->add_option("Divert power to elevator", COMPACT_ELEVATOR_ON, 0); | |
| tmpcomp->add_failure(COMPFAIL_ALARM); | |
| } | |
| break; | |
| case room_mine_office: | |
| line(m, t_counter, midx, y1 + 2, midx, y2 - 2); | |
| line(m, t_window, midx - 1, y1, midx + 1, y1); | |
| line(m, t_window, midx - 1, y2, midx + 1, y2); | |
| line(m, t_window, x1, midy - 1, x1, midy + 1); | |
| line(m, t_window, x2, midy - 1, x2, midy + 1); | |
| m->place_items(mi_office, 80, x1 + 1, y1 + 1, x2 - 1, y2 - 1, false, 0); | |
| break; | |
| case room_mine_storage: | |
| m->place_items(mi_mine_storage, 85, x1 + 2, y1 + 2, x2 - 2, y2 - 2, false, 0); | |
| break; | |
| case room_mine_fuel: | |
| { | |
| int spacing = rng(2, 4); | |
| if (door_side == NORTH || door_side == SOUTH) | |
| { | |
| int y = (door_side == NORTH ? y1 + 2 : y2 - 2); | |
| for (int x = x1 + 1; x <= x2 - 1; x += spacing) | |
| { | |
| m->ter(x, y) = t_gas_pump; | |
| } | |
| } | |
| else | |
| { | |
| int x = (door_side == EAST ? x2 - 2 : x1 + 2); | |
| for (int y = y1 + 1; y <= y2 - 1; y += spacing) | |
| { | |
| m->ter(x, y) = t_gas_pump; | |
| } | |
| } | |
| } | |
| break; | |
| case room_mine_housing: | |
| if (door_side == NORTH || door_side == SOUTH) | |
| { | |
| for (int y = y1 + 2; y <= y2 - 2; y += 2) | |
| { | |
| m->ter(x1 , y) = t_window; | |
| m->ter(x1 + 1, y) = t_bed; | |
| m->ter(x1 + 2, y) = t_bed; | |
| m->ter(x2 , y) = t_window; | |
| m->ter(x2 - 1, y) = t_bed; | |
| m->ter(x2 - 2, y) = t_bed; | |
| m->ter(x1 + 1, y + 1) = t_dresser; | |
| m->place_items(mi_dresser, 78, x1 + 1, y + 1, x1 + 1, y + 1, false, 0); | |
| m->ter(x2 - 1, y + 1) = t_dresser; | |
| m->place_items(mi_dresser, 78, x2 - 1, y + 1, x2 - 1, y + 1, false, 0); | |
| } | |
| } | |
| else | |
| { | |
| for (int x = x1 + 2; x <= x2 - 2; x += 2) | |
| { | |
| m->ter(x, y1) = t_window; | |
| m->ter(x, y1 + 1) = t_bed; | |
| m->ter(x, y1 + 2) = t_bed; | |
| m->ter(x, y2) = t_window; | |
| m->ter(x, y2 - 1) = t_bed; | |
| m->ter(x, y2 - 2) = t_bed; | |
| m->ter(x + 1, y1 + 1) = t_dresser; | |
| m->place_items(mi_dresser, 78, x + 1, y1 + 1, x + 1, y1 + 1, false, 0); | |
| m->ter(x + 1, y2 - 1) = t_dresser; | |
| m->place_items(mi_dresser, 78, x + 1, y2 - 1, x + 1, y2 - 1, false, 0); | |
| } | |
| } | |
| m->place_items(mi_bedroom, 65, x1 + 1, y1 + 1, x2 - 1, y2 - 1, false, 0); | |
| break; | |
| } | |
| if (type == room_mine_fuel) // Fuel stations are open on one side | |
| { | |
| switch (door_side) | |
| { | |
| case NORTH: | |
| line(m, t_floor, x1, y1 , x2, y1); | |
| break; | |
| case EAST: | |
| line(m, t_floor, x2, y1 + 1, x2, y2 - 1); | |
| break; | |
| case SOUTH: | |
| line(m, t_floor, x1, y2 , x2, y2); | |
| break; | |
| case WEST: | |
| line(m, t_floor, x1, y1 + 1, x1, y2 - 1); | |
| break; | |
| } | |
| } | |
| else | |
| { | |
| if (type == room_mine_storage) // Storage has a locked door | |
| { | |
| m->ter(door_point.x, door_point.y) = t_door_locked; | |
| } | |
| else | |
| { | |
| m->ter(door_point.x, door_point.y) = t_door_c; | |
| } | |
| } | |
| } | |
| map_extra random_map_extra(map_extras embellishments) | |
| { | |
| int pick = 0; | |
| // Set pick to the total of all the chances for map extras | |
| for (int i = 0; i < num_map_extras; i++) | |
| { | |
| pick += embellishments.chances[i]; | |
| } | |
| // Set pick to a number between 0 and the total | |
| pick = rng(0, pick - 1); | |
| int choice = -1; | |
| while (pick >= 0) | |
| { | |
| choice++; | |
| pick -= embellishments.chances[choice]; | |
| } | |
| return map_extra(choice); | |
| } | |
| room_type pick_mansion_room(int x1, int y1, int x2, int y2) | |
| { | |
| int dx = abs(x1 - x2), dy = abs(y1 - y2), area = dx * dy; | |
| int shortest = (dx < dy ? dx : dy), longest = (dx > dy ? dx : dy); | |
| std::vector<room_type> valid; | |
| if (shortest >= 12) | |
| { | |
| valid.push_back(room_mansion_courtyard); | |
| } | |
| if (shortest >= 7 && area >= 64 && area <= 100) | |
| { | |
| valid.push_back(room_mansion_bedroom); | |
| } | |
| if (shortest >= 9) | |
| { | |
| valid.push_back(room_mansion_library); | |
| } | |
| if (shortest >= 6 && area <= 60) | |
| { | |
| valid.push_back(room_mansion_kitchen); | |
| } | |
| if (longest >= 7 && shortest >= 5) | |
| { | |
| valid.push_back(room_mansion_dining); | |
| } | |
| if (shortest >= 6 && longest <= 10) | |
| { | |
| valid.push_back(room_mansion_game); | |
| } | |
| if (shortest >= 10) | |
| { | |
| valid.push_back(room_mansion_pool); | |
| } | |
| if (longest <= 6 || shortest <= 4) | |
| { | |
| valid.push_back(room_mansion_bathroom); | |
| } | |
| if (longest >= 8 && shortest <= 6) | |
| { | |
| valid.push_back(room_mansion_gallery); | |
| } | |
| if (valid.empty()) | |
| { | |
| debugmsg("x: %d - %d, dx: %d\n\ | |
| y: %d - %d, dy: %d", x1, x2, dx, | |
| y1, y2, dy); | |
| return room_null; | |
| } | |
| return valid[ rng(0, valid.size() - 1) ]; | |
| } | |
| void build_mansion_room(map* m, room_type type, int x1, int y1, int x2, int y2) | |
| { | |
| int dx = abs(x1 - x2), dy = abs(y1 - y2); | |
| int cx_low = (x1 + x2) / 2, cx_hi = (x1 + x2 + 1) / 2, | |
| cy_low = (y1 + y2) / 2, cy_hi = (y1 + y2 + 1) / 2; | |
| /* | |
| debugmsg("\ | |
| x: %d - %d, dx: %d cx: %d/%d\n\ | |
| x: %d - %d, dx: %d cx: %d/%d", x1, x2, dx, cx_low, cx_hi, | |
| y1, y2, dy, cy_low, cy_hi); | |
| */ | |
| bool walled_south = (y2 >= SEEY * 2 - 2); | |
| switch (type) | |
| { | |
| case room_mansion_courtyard: | |
| for (int x = x1; x <= x2; x++) | |
| { | |
| for (int y = y1; y <= y2; y++) | |
| { | |
| m->ter(x, y) = grass_or_dirt(); | |
| } | |
| } | |
| if (one_in(4)) // Tree grid | |
| { | |
| for (int x = 1; x <= dx / 2; x += 4) | |
| { | |
| for (int y = 1; y <= dx / 2; y += 4) | |
| { | |
| m->ter(x1 + x, y1 + y) = t_tree; | |
| m->ter(x2 - x, y2 - y) = t_tree; | |
| } | |
| } | |
| } | |
| if (one_in(3)) // shrub-lined | |
| { | |
| for (int i = x1; i <= x2; i++) | |
| { | |
| if (m->ter(i, y2 + 1) != t_door_c) | |
| { | |
| m->ter(i, y2) = t_shrub; | |
| } | |
| } | |
| if (walled_south && x1 <= SEEX && SEEX <= x2) | |
| { | |
| m->ter(SEEX - 1, y2) = grass_or_dirt(); | |
| m->ter(SEEX, y2) = grass_or_dirt(); | |
| } | |
| } | |
| break; | |
| case room_mansion_entry: | |
| if (!one_in(3)) // Columns | |
| { | |
| for (int y = y1 + 2; y <= y2; y += 3) | |
| { | |
| m->ter(cx_low - 3, y) = t_column; | |
| m->ter(cx_low + 3, y) = t_column; | |
| } | |
| } | |
| if (one_in(6)) // Suits of armor | |
| { | |
| int start = y1 + rng(2, 4), end = y2 - rng(0, 4), step = rng(3, 6); | |
| for (int y = start; y <= end; y += step) | |
| { | |
| m->add_item(x1 + 1, y, (*(m->itypes))[itm_helmet_plate], 0); | |
| m->add_item(x1 + 1, y, (*(m->itypes))[itm_armor_plate], 0); | |
| if (one_in(2)) | |
| { | |
| m->add_item(x1 + 1, y, (*(m->itypes))[itm_pike], 0); | |
| } | |
| else if (one_in(3)) | |
| { | |
| m->add_item(x1 + 1, y, (*(m->itypes))[itm_broadsword], 0); | |
| } | |
| else if (one_in(6)) | |
| { | |
| m->add_item(x1 + 1, y, (*(m->itypes))[itm_mace], 0); | |
| } | |
| else if (one_in(6)) | |
| { | |
| m->add_item(x1 + 1, y, (*(m->itypes))[itm_morningstar], 0); | |
| } | |
| m->add_item(x2 - 1, y, (*(m->itypes))[itm_helmet_plate], 0); | |
| m->add_item(x2 - 1, y, (*(m->itypes))[itm_armor_plate], 0); | |
| if (one_in(2)) | |
| { | |
| m->add_item(x2 - 1, y, (*(m->itypes))[itm_pike], 0); | |
| } | |
| else if (one_in(3)) | |
| { | |
| m->add_item(x2 - 1, y, (*(m->itypes))[itm_broadsword], 0); | |
| } | |
| else if (one_in(6)) | |
| { | |
| m->add_item(x2 - 1, y, (*(m->itypes))[itm_mace], 0); | |
| } | |
| else if (one_in(6)) | |
| { | |
| m->add_item(x2 - 1, y, (*(m->itypes))[itm_morningstar], 0); | |
| } | |
| } | |
| } | |
| break; | |
| case room_mansion_bedroom: | |
| if (dx > dy || (dx == dy && one_in(2))) // horizontal | |
| { | |
| int dressy = (one_in(2) ? cy_low - 2 : cy_low + 2); | |
| if (one_in(2)) // bed on left | |
| { | |
| square(m, t_bed, x1 + 1, cy_low - 1, x1 + 3, cy_low + 1); | |
| m->ter(x1 + 1, dressy) = t_dresser; | |
| m->place_items(mi_dresser, 80, x1 + 1, dressy, x1 + 1, dressy, false, 0); | |
| } | |
| else // bed on right | |
| { | |
| square(m, t_bed, x2 - 3, cy_low - 1, x2 - 1, cy_low + 1); | |
| m->ter(x1 + 1, dressy) = t_dresser; | |
| m->place_items(mi_dresser, 80, x2 - 1, dressy, x2 - 1, dressy, false, 0); | |
| } | |
| } | |
| else // vertical | |
| { | |
| int dressx = (one_in(2) ? cx_low - 2 : cx_low + 2); | |
| if (one_in(2)) // bed at top | |
| { | |
| square(m, t_bed, cx_low - 1, y1 + 1, cx_low + 1, y1 + 3); | |
| m->ter(dressx, y1 + 1) = t_dresser; | |
| m->place_items(mi_dresser, 80, dressx, y1 + 1, dressx, y1 + 1, false, 0); | |
| } | |
| else // bed at bottom | |
| { | |
| square(m, t_bed, cx_low - 1, y2 - 3, cx_low + 1, y2 - 1); | |
| m->ter(dressx, y2 - 1) = t_dresser; | |
| m->place_items(mi_dresser, 80, dressx, y2 - 1, dressx, y2 - 1, false, 0); | |
| } | |
| } | |
| m->place_items(mi_bedroom, 75, x1, y1, x2, y2, false, 0); | |
| if (one_in(10)) | |
| { | |
| m->place_items(mi_homeguns, 58, x1, y1, x2, y2, false, 0); | |
| } | |
| break; | |
| case room_mansion_library: | |
| if (dx < dy || (dx == dy && one_in(2))) // vertically-aligned bookshelves | |
| { | |
| for (int x = x1 + 1; x <= cx_low - 2; x += 3) | |
| { | |
| for (int y = y1 + 1; y <= y2 - 3; y += 4) | |
| { | |
| square(m, t_bookcase, x, y, x + 1, y + 2); | |
| m->place_items(mi_novels, 85, x, y, x + 1, y + 2, false, 0); | |
| m->place_items(mi_manuals, 62, x, y, x + 1, y + 2, false, 0); | |
| m->place_items(mi_textbooks, 40, x, y, x + 1, y + 2, false, 0); | |
| } | |
| } | |
| for (int x = x2 - 1; x >= cx_low + 2; x -= 3) | |
| { | |
| for (int y = y1 + 1; y <= y2 - 3; y += 4) | |
| { | |
| square(m, t_bookcase, x - 1, y, x, y + 2); | |
| m->place_items(mi_novels, 85, x - 1, y, x, y + 2, false, 0); | |
| m->place_items(mi_manuals, 62, x - 1, y, x, y + 2, false, 0); | |
| m->place_items(mi_textbooks, 40, x - 1, y, x, y + 2, false, 0); | |
| } | |
| } | |
| } | |
| else // horizontally-aligned bookshelves | |
| { | |
| for (int y = y1 + 1; y <= cy_low - 2; y += 3) | |
| { | |
| for (int x = x1 + 1; x <= x2 - 3; x += 4) | |
| { | |
| square(m, t_bookcase, x, y, x + 2, y + 1); | |
| m->place_items(mi_novels, 85, x, y, x + 2, y + 1, false, 0); | |
| m->place_items(mi_manuals, 62, x, y, x + 2, y + 1, false, 0); | |
| m->place_items(mi_textbooks, 40, x, y, x + 2, y + 1, false, 0); | |
| } | |
| } | |
| for (int y = y2 - 1; y >= cy_low + 2; y -= 3) | |
| { | |
| for (int x = x1 + 1; x <= x2 - 3; x += 4) | |
| { | |
| square(m, t_bookcase, x, y - 1, x + 2, y); | |
| m->place_items(mi_novels, 85, x, y - 1, x + 2, y, false, 0); | |
| m->place_items(mi_manuals, 62, x, y - 1, x + 2, y, false, 0); | |
| m->place_items(mi_textbooks, 40, x, y - 1, x + 2, y, false, 0); | |
| } | |
| } | |
| } | |
| break; | |
| case room_mansion_kitchen: | |
| square(m, t_counter, cx_low, cy_low, cx_hi, cy_hi); | |
| m->place_items(mi_cleaning, 58, x1 + 1, y1 + 1, x2 - 1, y2 - 1, false, 0); | |
| if (one_in(2)) // Fridge/racks on left/right | |
| { | |
| line(m, t_fridge, cx_low - 1, cy_low, cx_low - 1, cy_hi); | |
| m->place_items(mi_fridge, 82, cx_low - 1, cy_low, cx_low - 1, cy_hi, | |
| false, 0); | |
| line(m, t_rack, cx_hi + 1, cy_low, cx_hi + 1, cy_hi); | |
| m->place_items(mi_cannedfood, 50, cx_hi + 1, cy_low, cx_hi + 1, cy_hi, | |
| false, 0); | |
| m->place_items(mi_pasta, 50, cx_hi + 1, cy_low, cx_hi + 1, cy_hi, | |
| false, 0); | |
| } | |
| else // Fridge/racks on top/bottom | |
| { | |
| line(m, t_fridge, cx_low, cy_low - 1, cx_hi, cy_low - 1); | |
| m->place_items(mi_fridge, 82, cx_low, cy_low - 1, cx_hi, cy_low - 1, | |
| false, 0); | |
| line(m, t_rack, cx_low, cy_hi + 1, cx_hi, cy_hi + 1); | |
| m->place_items(mi_cannedfood, 50, cx_low, cy_hi + 1, cx_hi, cy_hi + 1, | |
| false, 0); | |
| m->place_items(mi_pasta, 50, cx_low, cy_hi + 1, cx_hi, cy_hi + 1, | |
| false, 0); | |
| } | |
| break; | |
| case room_mansion_dining: | |
| if (dx < dy || (dx == dy && one_in(2))) // vertically-aligned table | |
| { | |
| line(m, t_table, cx_low, y1 + 2, cx_low, y2 - 2); | |
| line(m, t_bench, cx_low - 1, y1 + 2, cx_low - 1, y2 - 2); | |
| line(m, t_bench, cx_low + 1, y1 + 2, cx_low + 1, y2 - 2); | |
| m->place_items(mi_dining, 78, cx_low, y1 + 2, cx_low, y2 - 2, false, 0); | |
| } | |
| else // horizontally-aligned table | |
| { | |
| line(m, t_table, x1 + 2, cy_low, x2 - 2, cy_low); | |
| line(m, t_bench, x1 + 2, cy_low - 1, x2 - 2, cy_low - 1); | |
| line(m, t_bench, x1 + 2, cy_low + 1, x2 - 2, cy_low + 1); | |
| m->place_items(mi_dining, 78, x1 + 2, cy_low, x2 - 2, cy_low, false, 0); | |
| } | |
| break; | |
| case room_mansion_game: | |
| if (dx < dy || one_in(2)) // vertically-aligned table | |
| { | |
| square(m, t_pool_table, cx_low, cy_low - 1, cx_low + 1, cy_low + 1); | |
| m->place_items(mi_pool_table, 80, cx_low, cy_low - 1, cx_low + 1, cy_low + 1, | |
| false, 0); | |
| } | |
| else // horizontally-aligned table | |
| { | |
| square(m, t_pool_table, cx_low - 1, cy_low, cx_low + 1, cy_low + 1); | |
| m->place_items(mi_pool_table, 80, cx_low - 1, cy_low, cx_low + 1, cy_low + 1, | |
| false, 0); | |
| } | |
| break; | |
| case room_mansion_pool: | |
| square(m, t_water_sh, x1 + 2, y1 + 2, x2 - 2, y2 - 2); | |
| break; | |
| case room_mansion_bathroom: | |
| m->ter(rng(x1 + 1, x2 - 1), rng(y1 + 1, y2 - 1)) = t_toilet; | |
| m->place_items(mi_harddrugs, 20, x1 + 1, y1 + 1, x2 - 1, y2 - 1, false, 0); | |
| m->place_items(mi_softdrugs, 72, x1 + 1, y1 + 1, x2 - 1, y2 - 1, false, 0); | |
| m->place_items(mi_cleaning, 48, x1 + 1, y1 + 1, x2 - 1, y2 - 1, false, 0); | |
| break; | |
| case room_mansion_gallery: | |
| for (int x = x1 + 1; x <= cx_low - 1; x += rng(2, 4)) | |
| { | |
| for (int y = y1 + 1; y <= cy_low - 1; y += rng(2, 4)) | |
| { | |
| if (one_in(10)) // Suit of armor | |
| { | |
| m->add_item(x, y, (*(m->itypes))[itm_helmet_plate], 0); | |
| m->add_item(x, y, (*(m->itypes))[itm_armor_plate], 0); | |
| if (one_in(2)) | |
| { | |
| m->add_item(x, y, (*(m->itypes))[itm_pike], 0); | |
| } | |
| else if (one_in(3)) | |
| { | |
| m->add_item(x, y, (*(m->itypes))[itm_broadsword], 0); | |
| } | |
| else if (one_in(6)) | |
| { | |
| m->add_item(x, y, (*(m->itypes))[itm_mace], 0); | |
| } | |
| else if (one_in(6)) | |
| { | |
| m->add_item(x, y, (*(m->itypes))[itm_morningstar], 0); | |
| } | |
| } | |
| else // Objets d'art | |
| { | |
| m->ter(x, y) = t_counter; | |
| m->place_items(mi_art, 70, x, y, x, y, false, 0); | |
| } | |
| } | |
| } | |
| for (int x = x2 - 1; x >= cx_hi + 1; x -= rng(2, 4)) | |
| { | |
| for (int y = y2 - 1; y >= cy_hi + 1; y -= rng(2, 4)) | |
| { | |
| if (one_in(10)) // Suit of armor | |
| { | |
| m->add_item(x, y, (*(m->itypes))[itm_helmet_plate], 0); | |
| m->add_item(x, y, (*(m->itypes))[itm_armor_plate], 0); | |
| if (one_in(2)) | |
| { | |
| m->add_item(x, y, (*(m->itypes))[itm_pike], 0); | |
| } | |
| else if (one_in(3)) | |
| { | |
| m->add_item(x, y, (*(m->itypes))[itm_broadsword], 0); | |
| } | |
| else if (one_in(6)) | |
| { | |
| m->add_item(x, y, (*(m->itypes))[itm_mace], 0); | |
| } | |
| else if (one_in(6)) | |
| { | |
| m->add_item(x, y, (*(m->itypes))[itm_morningstar], 0); | |
| } | |
| } | |
| else // Objets d'art | |
| { | |
| m->ter(x, y) = t_counter; | |
| m->place_items(mi_art, 70, x, y, x, y, false, 0); | |
| } | |
| } | |
| } | |
| break; | |
| } | |
| } | |
| void mansion_room(map* m, int x1, int y1, int x2, int y2) | |
| { | |
| room_type type = pick_mansion_room(x1, y1, x2, y2); | |
| build_mansion_room(m, type, x1, y1, x2, y2); | |
| } | |
| void map::add_extra(map_extra type, game* g) | |
| { | |
| item body; | |
| body.make_corpse(g->itypes[itm_corpse], g->mtypes[mon_null], g->turn); | |
| switch (type) | |
| { | |
| case mx_null: | |
| debugmsg("Tried to generate null map extra."); | |
| break; | |
| case mx_helicopter: | |
| { | |
| int cx = rng(4, SEEX * 2 - 5), cy = rng(4, SEEY * 2 - 5); | |
| for (int x = 0; x < SEEX * 2; x++) | |
| { | |
| for (int y = 0; y < SEEY * 2; y++) | |
| { | |
| if (x >= cx - 4 && x <= cx + 4 && y >= cy - 4 && y <= cy + 4) | |
| { | |
| if (!one_in(5)) | |
| { | |
| ter(x, y) = t_wreckage; | |
| } | |
| else if (has_flag(bashable, x, y)) | |
| { | |
| std::string junk; | |
| bash(x, y, 500, junk); // Smash the fuck out of it | |
| bash(x, y, 500, junk); // Smash the fuck out of it some more | |
| } | |
| } | |
| else if (one_in(10)) // 1 in 10 chance of being wreckage anyway | |
| { | |
| ter(x, y) = t_wreckage; | |
| } | |
| } | |
| } | |
| place_items(mi_helicopter, 90, cx - 4, cy - 4, cx + 4, cy + 4, true, 0); | |
| place_items(mi_helicopter, 20, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| items_location extra_items = mi_helicopter; | |
| switch (rng(1, 4)) | |
| { | |
| case 1: | |
| extra_items = mi_military; | |
| break; | |
| case 2: | |
| extra_items = mi_science; | |
| break; | |
| case 3: | |
| extra_items = mi_allguns; | |
| break; | |
| case 4: | |
| extra_items = mi_bionics; | |
| break; | |
| } | |
| place_items(extra_items, 70, cx - 4, cy - 4, cx + 4, cy + 4, true, 0); | |
| } | |
| break; | |
| case mx_military: | |
| { | |
| int num_bodies = dice(2, 6); | |
| for (int i = 0; i < num_bodies; i++) | |
| { | |
| int x, y, tries = 0;; | |
| do // Loop until we find a valid spot to dump a body, or we give up | |
| { | |
| x = rng(0, SEEX * 2 - 1); | |
| y = rng(0, SEEY * 2 - 1); | |
| tries++; | |
| } | |
| while (tries < 10 && move_cost(x, y) == 0); | |
| if (tries < 10) // We found a valid spot! | |
| { | |
| add_item(x, y, body); | |
| place_items(mi_military, 86, x, y, x, y, true, 0); | |
| if (one_in(8)) | |
| { | |
| add_item(x, y, (*itypes)[itm_id_military], 0); | |
| } | |
| } | |
| } | |
| place_items(mi_rare, 25, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| } | |
| break; | |
| case mx_science: | |
| { | |
| int num_bodies = dice(2, 5); | |
| for (int i = 0; i < num_bodies; i++) | |
| { | |
| int x, y, tries = 0; | |
| do // Loop until we find a valid spot to dump a body, or we give up | |
| { | |
| x = rng(0, SEEX * 2 - 1); | |
| y = rng(0, SEEY * 2 - 1); | |
| tries++; | |
| } | |
| while (tries < 10 && move_cost(x, y) == 0); | |
| if (tries < 10) // We found a valid spot! | |
| { | |
| add_item(x, y, body); | |
| add_item(x, y, (*itypes)[itm_id_science], 0); | |
| place_items(mi_science, 84, x, y, x, y, true, 0); | |
| } | |
| } | |
| place_items(mi_rare, 45, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); | |
| } | |
| break; | |
| case mx_stash: | |
| { | |
| int x = rng(0, SEEX * 2 - 1), y = rng(0, SEEY * 2 - 1); | |
| if (move_cost(x, y) != 0) | |
| { | |
| ter(x, y) = t_dirt; | |
| } | |
| int size; | |
| items_location stash; | |
| switch (rng(1, 6)) // What kind of stash? | |
| { | |
| case 1: | |
| stash = mi_stash_food; | |
| size = 90; | |
| break; | |
| case 2: | |
| stash = mi_stash_ammo; | |
| size = 80; | |
| break; | |
| case 3: | |
| stash = mi_rare; | |
| size = 70; | |
| break; | |
| case 4: | |
| stash = mi_stash_wood; | |
| size = 90; | |
| break; | |
| case 5: | |
| stash = mi_stash_drugs; | |
| size = 85; | |
| break; | |
| case 6: | |
| stash = mi_trash; | |
| size = 92; | |
| break; | |
| } | |
| if (move_cost(x, y) == 0) | |
| { | |
| ter(x, y) = t_dirt; | |
| } | |
| place_items(stash, size, x, y, x, y, true, 0); | |
| // Now add traps around that stash | |
| for (int i = x - 4; i <= x + 4; i++) | |
| { | |
| for (int j = y - 4; j <= y + 4; j++) | |
| { | |
| if (i >= 0 && j >= 0 && i < SEEX * 2 && j < SEEY * 2 && one_in(4)) | |
| { | |
| trap_id placed; | |
| switch (rng(1, 7)) | |
| { | |
| case 1: | |
| case 2: | |
| case 3: | |
| placed = tr_beartrap; | |
| break; | |
| case 4: | |
| case 5: | |
| placed = tr_nailboard; | |
| break; | |
| case 6: | |
| placed = tr_crossbow; | |
| break; | |
| case 7: | |
| placed = tr_shotgun_2; | |
| break; | |
| } | |
| if (placed == tr_beartrap && has_flag(diggable, i, j)) | |
| { | |
| if (one_in(8)) | |
| { | |
| placed = tr_landmine_buried; | |
| } | |
| else | |
| { | |
| placed = tr_beartrap_buried; | |
| } | |
| } | |
| add_trap(i, j, placed); | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| case mx_drugdeal: | |
| { | |
| // Decide on a drug type | |
| int num_drugs; | |
| itype* drugtype; | |
| switch (rng(1, 10)) | |
| { | |
| case 1: // Weed | |
| num_drugs = rng(20, 30); | |
| drugtype = (*itypes)[itm_weed]; | |
| break; | |
| case 2: | |
| case 3: | |
| case 4: | |
| case 5: // Cocaine | |
| num_drugs = rng(10, 20); | |
| drugtype = (*itypes)[itm_coke]; | |
| break; | |
| case 6: | |
| case 7: | |
| case 8: // Meth | |
| num_drugs = rng(8, 14); | |
| drugtype = (*itypes)[itm_meth]; | |
| break; | |
| case 9: | |
| case 10: // Heroin | |
| num_drugs = rng(6, 12); | |
| drugtype = (*itypes)[itm_heroin]; | |
| break; | |
| } | |
| int num_bodies_a = dice(3, 3); | |
| int num_bodies_b = dice(3, 3); | |
| bool north_south = one_in(2); | |
| bool a_has_drugs = one_in(2); | |
| for (int i = 0; i < num_bodies_a; i++) | |
| { | |
| int x, y, tries = 0; | |
| do // Loop until we find a valid spot to dump a body, or we give up | |
| { | |
| if (north_south) | |
| { | |
| x = rng(0, SEEX * 2 - 1); | |
| y = rng(0, SEEY - 4); | |
| } | |
| else | |
| { | |
| x = rng(0, SEEX - 4); | |
| y = rng(0, SEEY * 2 - 1); | |
| } | |
| tries++; | |
| } | |
| while (tries < 10 && move_cost(x, y) == 0); | |
| if (tries < 10) // We found a valid spot! | |
| { | |
| add_item(x, y, body); | |
| place_items(mi_drugdealer, 75, x, y, x, y, true, 0); | |
| if (a_has_drugs && num_drugs > 0) | |
| { | |
| int drugs_placed = rng(2, 6); | |
| if (drugs_placed > num_drugs) | |
| { | |
| drugs_placed = num_drugs; | |
| num_drugs = 0; | |
| } | |
| add_item(x, y, drugtype, 0, drugs_placed); | |
| } | |
| } | |
| } | |
| for (int i = 0; i < num_bodies_b; i++) | |
| { | |
| int x, y, tries = 0; | |
| do // Loop until we find a valid spot to dump a body, or we give up | |
| { | |
| if (north_south) | |
| { | |
| x = rng(0, SEEX * 2 - 1); | |
| y = rng(SEEY + 3, SEEY * 2 - 1); | |
| } | |
| else | |
| { | |
| x = rng(SEEX + 3, SEEX * 2 - 1); | |
| y = rng(0, SEEY * 2 - 1); | |
| } | |
| tries++; | |
| } | |
| while (tries < 10 && move_cost(x, y) == 0); | |
| if (tries < 10) // We found a valid spot! | |
| { | |
| add_item(x, y, body); | |
| place_items(mi_drugdealer, 75, x, y, x, y, true, 0); | |
| if (!a_has_drugs && num_drugs > 0) | |
| { | |
| int drugs_placed = rng(2, 6); | |
| if (drugs_placed > num_drugs) | |
| { | |
| drugs_placed = num_drugs; | |
| num_drugs = 0; | |
| } | |
| add_item(x, y, drugtype, 0, drugs_placed); | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| case mx_supplydrop: | |
| { | |
| int num_crates = rng(1, 5); | |
| for (int i = 0; i < num_crates; i++) | |
| { | |
| int x, y, tries = 0; | |
| do // Loop until we find a valid spot to dump a body, or we give up | |
| { | |
| x = rng(0, SEEX * 2 - 1); | |
| y = rng(0, SEEY * 2 - 1); | |
| tries++; | |
| } | |
| while (tries < 10 && move_cost(x, y) == 0); | |
| ter(x, y) = t_crate_c; | |
| switch (rng(1, 10)) | |
| { | |
| case 1: | |
| case 2: | |
| case 3: | |
| case 4: | |
| place_items(mi_mil_food, 88, x, y, x, y, true, 0); | |
| break; | |
| case 5: | |
| case 6: | |
| case 7: | |
| place_items(mi_grenades, 82, x, y, x, y, true, 0); | |
| break; | |
| case 8: | |
| case 9: | |
| place_items(mi_mil_armor, 75, x, y, x, y, true, 0); | |
| break; | |
| case 10: | |
| place_items(mi_mil_rifles, 80, x, y, x, y, true, 0); | |
| break; | |
| } | |
| } | |
| } | |
| break; | |
| case mx_portal: | |
| { | |
| int x = rng(1, SEEX * 2 - 2), y = rng(1, SEEY * 2 - 2); | |
| for (int i = x - 1; i <= x + 1; i++) | |
| { | |
| for (int j = y - 1; j <= y + 1; j++) | |
| { | |
| ter(i, j) = t_rubble; | |
| } | |
| } | |
| add_trap(x, y, tr_portal); | |
| int num_monsters = rng(0, 4); | |
| for (int i = 0; i < num_monsters; i++) | |
| { | |
| mon_id type = mon_id(rng(mon_gelatin, mon_blank)); | |
| int mx = rng(1, SEEX * 2 - 2), my = rng(1, SEEY * 2 - 2); | |
| ter(mx, my) = t_rubble; | |
| add_spawn(type, 1, mx, my); | |
| } | |
| } | |
| break; | |
| case mx_minefield: | |
| { | |
| int num_mines = rng(6, 20); | |
| for (int x = 0; x < SEEX * 2; x++) | |
| { | |
| for (int y = 0; y < SEEY * 2; y++) | |
| { | |
| if (one_in(3)) | |
| { | |
| ter(x, y) = t_dirt; | |
| } | |
| } | |
| } | |
| for (int i = 0; i < num_mines; i++) | |
| { | |
| int x = rng(0, SEEX * 2 - 1), y = rng(0, SEEY * 2 - 1); | |
| if (!has_flag(diggable, x, y) || one_in(8)) | |
| { | |
| ter(x, y) = t_dirtmound; | |
| } | |
| add_trap(x, y, tr_landmine_buried); | |
| } | |
| } | |
| break; | |
| case mx_wolfpack: | |
| add_spawn(mon_wolf, rng(3, 6), SEEX, SEEY); | |
| break; | |
| case mx_cougar: | |
| add_spawn(mon_cougar, 1, SEEX, SEEY); | |
| break; | |
| case mx_crater: | |
| { | |
| int size = rng(2, 6); | |
| int x = rng(size, SEEX * 2 - 1 - size), y = rng(size, SEEY * 2 - 1 - size); | |
| for (int i = x - size; i <= x + size; i++) | |
| { | |
| for (int j = y - size; j <= y + size; j++) | |
| { | |
| ter(i, j) = t_rubble; | |
| radiation(i, j) += rng(20, 40); | |
| } | |
| } | |
| } | |
| break; | |
| case mx_fumarole: | |
| { | |
| int x1 = rng(0, SEEX - 1), y1 = rng(0, SEEY - 1), | |
| x2 = rng(SEEX, SEEX * 2 - 1), y2 = rng(SEEY, SEEY * 2 - 1); | |
| std::vector<point> fumarole = line_to(x1, y1, x2, y2, 0); | |
| for (int i = 0; i < fumarole.size(); i++) | |
| { | |
| ter(fumarole[i].x, fumarole[i].y) = t_lava; | |
| } | |
| } | |
| break; | |
| case mx_portal_in: | |
| { | |
| int x = rng(5, SEEX * 2 - 6), y = rng(5, SEEY * 2 - 6); | |
| add_field(g, x, y, fd_fatigue, 3); | |
| for (int i = x - 5; i <= x + 5; i++) | |
| { | |
| for (int j = y - 5; j <= y + 5; j++) | |
| { | |
| if (rng(0, 9) > trig_dist(x, y, i, j)) | |
| { | |
| marlossify(i, j); | |
| if (ter(i, j) == t_marloss) | |
| { | |
| add_item(x, y, (*itypes)[itm_marloss_berry], g->turn); | |
| } | |
| if (one_in(15)) | |
| { | |
| monster creature(g->mtypes[mon_id(rng(mon_gelatin, mon_blank))]); | |
| creature.spawn(i, j); | |
| g->z.push_back(creature); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| case mx_anomaly: | |
| { | |
| point center(rng(6, SEEX * 2 - 7), rng(6, SEEY * 2 - 7)); | |
| artifact_natural_property prop = | |
| artifact_natural_property(rng(ARTPROP_NULL + 1, ARTPROP_MAX - 1)); | |
| create_anomaly(center.x, center.y, prop); | |
| add_item(center.x, center.y, g->new_natural_artifact(prop), 0); | |
| } | |
| break; | |
| } // switch (prop) | |
| } | |
| void map::create_anomaly(int cx, int cy, artifact_natural_property prop) | |
| { | |
| rough_circle(this, t_rubble, cx, cy, 5); | |
| switch (prop) | |
| { | |
| case ARTPROP_WRIGGLING: | |
| case ARTPROP_MOVING: | |
| for (int i = cx - 5; i <= cx + 5; i++) | |
| { | |
| for (int j = cy - 5; j <= cy + 5; j++) | |
| { | |
| if (ter(i, j) == t_rubble) | |
| { | |
| add_field(NULL, i, j, fd_push_items, 1); | |
| if (one_in(3)) | |
| { | |
| add_item(i, j, (*itypes)[itm_rock], 0); | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| case ARTPROP_GLOWING: | |
| case ARTPROP_GLITTERING: | |
| for (int i = cx - 5; i <= cx + 5; i++) | |
| { | |
| for (int j = cy - 5; j <= cy + 5; j++) | |
| { | |
| if (ter(i, j) == t_rubble && one_in(2)) | |
| { | |
| add_trap(i, j, tr_glow); | |
| } | |
| } | |
| } | |
| break; | |
| case ARTPROP_HUMMING: | |
| case ARTPROP_RATTLING: | |
| for (int i = cx - 5; i <= cx + 5; i++) | |
| { | |
| for (int j = cy - 5; j <= cy + 5; j++) | |
| { | |
| if (ter(i, j) == t_rubble && one_in(2)) | |
| { | |
| add_trap(i, j, tr_hum); | |
| } | |
| } | |
| } | |
| break; | |
| case ARTPROP_WHISPERING: | |
| case ARTPROP_ENGRAVED: | |
| for (int i = cx - 5; i <= cx + 5; i++) | |
| { | |
| for (int j = cy - 5; j <= cy + 5; j++) | |
| { | |
| if (ter(i, j) == t_rubble && one_in(3)) | |
| { | |
| add_trap(i, j, tr_shadow); | |
| } | |
| } | |
| } | |
| break; | |
| case ARTPROP_BREATHING: | |
| for (int i = cx - 1; i <= cx + 1; i++) | |
| { | |
| for (int j = cy - 1; j <= cy + 1; j++) | |
| if (i == cx && j == cy) | |
| { | |
| add_spawn(mon_breather_hub, 1, i, j); | |
| } | |
| else | |
| { | |
| add_spawn(mon_breather, 1, i, j); | |
| } | |
| } | |
| break; | |
| case ARTPROP_DEAD: | |
| for (int i = cx - 5; i <= cx + 5; i++) | |
| { | |
| for (int j = cy - 5; j <= cy + 5; j++) | |
| { | |
| if (ter(i, j) == t_rubble) | |
| { | |
| add_trap(i, j, tr_drain); | |
| } | |
| } | |
| } | |
| break; | |
| case ARTPROP_ITCHY: | |
| for (int i = cx - 5; i <= cx + 5; i++) | |
| { | |
| for (int j = cy - 5; j <= cy + 5; j++) | |
| { | |
| if (ter(i, j) == t_rubble) | |
| { | |
| radiation(i, j) = rng(0, 10); | |
| } | |
| } | |
| } | |
| break; | |
| case ARTPROP_ELECTRIC: | |
| case ARTPROP_CRACKLING: | |
| add_field(NULL, cx, cy, fd_shock_vent, 3); | |
| break; | |
| case ARTPROP_SLIMY: | |
| add_field(NULL, cx, cy, fd_acid_vent, 3); | |
| break; | |
| case ARTPROP_WARM: | |
| for (int i = cx - 5; i <= cx + 5; i++) | |
| { | |
| for (int j = cy - 5; j <= cy + 5; j++) | |
| { | |
| if (ter(i, j) == t_rubble) | |
| { | |
| add_field(NULL, i, j, fd_fire_vent, 1 + (rl_dist(cx, cy, i, j) % 3)); | |
| } | |
| } | |
| } | |
| break; | |
| case ARTPROP_SCALED: | |
| for (int i = cx - 5; i <= cx + 5; i++) | |
| { | |
| for (int j = cy - 5; j <= cy + 5; j++) | |
| { | |
| if (ter(i, j) == t_rubble) | |
| { | |
| add_trap(i, j, tr_snake); | |
| } | |
| } | |
| } | |
| break; | |
| case ARTPROP_FRACTAL: | |
| create_anomaly(cx - 4, cy - 4, | |
| artifact_natural_property(rng(ARTPROP_NULL + 1, ARTPROP_MAX - 1))); | |
| create_anomaly(cx + 4, cy - 4, | |
| artifact_natural_property(rng(ARTPROP_NULL + 1, ARTPROP_MAX - 1))); | |
| create_anomaly(cx - 4, cy + 4, | |
| artifact_natural_property(rng(ARTPROP_NULL + 1, ARTPROP_MAX - 1))); | |
| create_anomaly(cx + 4, cy - 4, | |
| artifact_natural_property(rng(ARTPROP_NULL + 1, ARTPROP_MAX - 1))); | |
| break; | |
| } | |
| } | |
| void line(map* m, ter_id type, int x1, int y1, int x2, int y2) | |
| { | |
| std::vector<point> line = line_to(x1, y1, x2, y2, 0); | |
| for (int i = 0; i < line.size(); i++) | |
| { | |
| m->ter(line[i].x, line[i].y) = type; | |
| } | |
| m->ter(x1, y1) = type; | |
| } | |
| void square(map* m, ter_id type, int x1, int y1, int x2, int y2) | |
| { | |
| for (int x = x1; x <= x2; x++) | |
| { | |
| for (int y = y1; y <= y2; y++) | |
| { | |
| m->ter(x, y) = type; | |
| } | |
| } | |
| } | |
| void rough_circle(map* m, ter_id type, int x, int y, int rad) | |
| { | |
| for (int i = x - rad; i <= x + rad; i++) | |
| { | |
| for (int j = y - rad; j <= y + rad; j++) | |
| { | |
| if (rl_dist(x, y, i, j) + rng(0, 3) <= rad) | |
| { | |
| m->ter(i, j) = type; | |
| } | |
| } | |
| } | |
| } | |
| void add_corpse(game* g, map* m, int x, int y) | |
| { | |
| item body; | |
| body.make_corpse(g->itypes[itm_corpse], g->mtypes[mon_null], 0); | |
| m->add_item(x, y, body); | |
| m->put_items_from(mi_shoes, 1, x, y); | |
| m->put_items_from(mi_pants, 1, x, y); | |
| m->put_items_from(mi_shirts, 1, x, y); | |
| if (one_in(6)) | |
| { | |
| m->put_items_from(mi_jackets, 1, x, y); | |
| } | |
| if (one_in(15)) | |
| { | |
| m->put_items_from(mi_bags, 1, x, y); | |
| } | |
| } |