/* * Copyright (C) 2002-2007 The Warp Rogue Team * Part of the Warp Rogue Project * * This software is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License. * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY. * * See the license.txt file for more details. */ /* * Module Name: WorldGeneration * Description: - */ #define Uses_Ui #define Uses_World #define Uses_Area #define Uses_Sector #define Uses_Character #define Uses_CharacterGeneration #define Uses_Object #define Uses_Terrain #define Uses_Npc #define Uses_ProgramManager #define Uses_Util #define Uses_Script #define Uses_DataFile #define Uses_LoadSave #include "mheader.h" #include "generate.h" static void execute_dungeon_script(const WORLD_TILE_DATA *, const WORLD_POINT * ); static void add_connection(OBJECT *); /* * the world generation screen */ void world_generation(void) { WORLD_POINT p; command_bar_clear(); render_world_generation_screen(false); update_screen(); for (p.y = 0; p.y < WORLD_HEIGHT; p.y++) { for (p.x = 0; p.x < WORLD_WIDTH; p.x++) { const WORLD_TILE_DATA *tile_data; tile_data = world_tile_data(&p); if (is_empty_string(tile_data->script)) continue; execute_dungeon_script(tile_data, &p); } } } /* * adds connections */ void add_connections(const AREA_SECTION *bounds, const char *way_up, const char *way_down ) { OBJECT *connection; AREA *area; area = active_area(); sector_set_bounds(bounds); if (area->location.z > WORLD_SURFACE_Z) { connection = object_create(way_down); add_connection(connection); } if (area->location.z < world_tile_data(&area->location)->n_levels - 1) { connection = object_create(way_up); add_connection(connection); } sector_reset_bounds(); } /* * adds the environment */ void add_environment(const char *terrain_name, const char *object_name) { AREA_POINT p; const AREA_SECTION *bounds; bounds = area_bounds(); for (p.y = bounds->top; p.y <= bounds->bottom; p.y++) { for (p.x = bounds->left; p.x <= bounds->right; p.x++) { TERRAIN *terrain; if (sector_at(&p)->terrain != NULL) { continue; } terrain = terrain_create(terrain_name); place_terrain(terrain, &p); if (!is_empty_string(object_name)) { OBJECT *object; object = object_create(object_name); place_object(object, &p); } } } } /* * builds a gate */ void build_gate(AREA_POINT *c, AREA_COORD height, AREA_COORD side_ex) { AREA_COORD y_mod; bool connection_reached; y_mod = 0; connection_reached = false; do { AREA_COORD x_mod; for (x_mod = -(side_ex); x_mod <= side_ex; x_mod++) { OBJECT *object; AREA_POINT p; p.y = c->y + y_mod; p.x = c->x + x_mod; object = object_at(&p); if (object == NULL) { connection_reached = true; } else { object_destroy(object); sector_at(&p)->object = NULL; } } --y_mod; } while (!connection_reached || y_mod > -(height) ); } /* * spawns an NPC */ bool spawn_npc(const char *npc_name) { CHARACTER *npc; AREA_POINT spawn_point; NPC_INDEX npc_index; if (is_empty_string(npc_name)) return false; if (sector_random(&spawn_point, SC_MOVE_TARGET_SAFE) == NULL) { return false; } npc_index = name_to_npc_index(npc_name); if (npc_index == NPC_RANDOM) { npc = create_random_npc(); } else { npc = npc_create_i(npc_index); npc_counter(npc_index)->n_spawned += 1; } place_character(npc, &spawn_point); return true; } /* * executes a dungeon scripts */ static void execute_dungeon_script(const WORLD_TILE_DATA *tile_data, const WORLD_POINT *location ) { AREA *area; WORLD_COORD z; script_load(DIR_WORLD, tile_data->script); script_set_data("GENERATION", "Yes"); area = active_area(); for (z = 0; z < tile_data->n_levels; z++) { strcpy(area->name, tile_data->name); area->location = *location; area->location.z = z; script_set_data_numeric("LEVEL", z); script_execute(); area_write(NULL); area_clear(); } } /* * adds a connection */ static void add_connection(OBJECT *connection) { AREA_POINT location; SECTOR_CLASS wanted_class = SC_FREE_OBJECT_LOCATION; if (object_has_attribute(connection, OA_IMPASSABLE)) { wanted_class = SC_FREE_OBJECT_LOCATION_ANTIBLOCK; } if (sector_random(&location, wanted_class) == NULL) { /* this should never happen ... */ die("*** CORE ERROR *** could not place connection object"); } place_object(connection, &location); }