/* * 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: World * Description: - */ #define Uses_Ui #define Uses_Util #define Uses_Area #define Uses_AreaTransition #define Uses_ProgramManager #define Uses_LoadSave /* hack - fix later */ #define Uses_Perception #include "mheader.h" #include "world.h" /* * world tile box buffer size */ #define WORLD_TILE_BOX_BUFFER_SIZE 16 static void * world_tile_data_new(void); static void world_tile_data_free(void *); /* * world tile data template (default values) */ static const WORLD_TILE_DATA WorldTileDataTemplate = { /* NAME */ "", /* SYMBOL */ 'E', /* SCREEN_SYMBOL */ 'E', /* COLOUR */ C_RED, /* N_LEVELS */ 0, /* SCRIPT */ "" }; /* * the world */ static WORLD World; /* * the world tile box */ static BOX * WorldTileBox = NULL; /* * World module init */ void world_init(void) { clear_string(World.description); WorldTileBox = box_new(world_tile_data_new, world_tile_data_free, WORLD_TILE_BOX_BUFFER_SIZE ); } /* * World module clean up */ void world_clean_up(void) { if (WorldTileBox != NULL) { box_free(WorldTileBox); } } /* * returns the world */ WORLD * world(void) { return &World; } /* * returns a world tile pointer */ WORLD_TILE * world_tile(const WORLD_POINT *p) { return &World.map[p->y][p->x]; } /* * returns a world tile data pointer */ WORLD_TILE_DATA * world_tile_data(const WORLD_POINT *p) { WORLD_TILE *tile; tile = world_tile(p); return WorldTileBox->item[*tile]; } /* * adds a tile to the world tile box */ WORLD_TILE_DATA * world_tile_box_new_tile(void) { return box_new_item(WorldTileBox); } /* * optimizes the tile box */ void world_tile_box_optimize(void) { box_optimize(WorldTileBox); } /* * returns true if the coordinates of both points are equal */ bool world_points_equal(const WORLD_POINT *p1, const WORLD_POINT *p2) { if (p1->z == p2->z && p1->y == p2->y && p1->x == p2->x) { return true; } return false; } /* * moves a world point one step in the passed direction */ void move_world_point(WORLD_POINT *world_point, DIRECTION direction) { world_point->x += direction_modifier(COORD_X, direction); world_point->y += direction_modifier(COORD_Y, direction); } /* * returns true if the passed point is out of bounds */ bool out_of_world_bounds(const WORLD_POINT *p) { if (p->y < 0 || p->x < 0 || p->y >= WORLD_HEIGHT || p->x >= WORLD_WIDTH) { return true; } return false; } /* * world map screen */ void world_map_screen(CHARACTER *character) { COMMAND entered_command; DIRECTION direction; WORLD_POINT current_position; current_position = active_area()->location; command_bar_clear(); command_bar_add_move_commands(); while (true) { WORLD_POINT previous_position; render_world_map_screen(¤t_position, character); update_screen(); entered_command = command_bar_get_command(); move_command_to_direction(&direction, entered_command); previous_position = current_position; move_world_point(¤t_position, direction); if (out_of_world_bounds(¤t_position)) { current_position = previous_position; continue; } if (area_exists(¤t_position)) { move_party_to_area(¤t_position, direction, false ); /* hack */ update_perception_data(character); break; } } } /* * symbol -> world tile */ WORLD_TILE symbol_to_world_tile(SYMBOL symbol) { WORLD_TILE tile; for (tile = 0; tile < WorldTileBox->current_size; tile++) { const WORLD_TILE_DATA *tile_data; tile_data = WorldTileBox->item[tile]; if (tile_data->symbol == symbol) { return tile; } } die("*** CORE ERROR *** invalid world map symbol: %c", symbol); /* NEVER REACHED */ return 0; } /* * allocs world tile data */ static void * world_tile_data_new(void) { WORLD_TILE_DATA *tile_data; tile_data = checked_malloc(sizeof *tile_data); *tile_data = WorldTileDataTemplate; return tile_data; } /* * frees world tile data */ static void world_tile_data_free(void *data) { free(data); }