/* * 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: AreaTransition * Description: - */ #define Uses_Ui #define Uses_World #define Uses_Area #define Uses_Sector #define Uses_Character #define Uses_Event #define Uses_LoadSave #define Uses_ProgramManager #define Uses_Death #include "mheader.h" #include "areatran.h" static LIST * CharacterTransferList = NULL; static LIST * EventTransferList = NULL; static void grab_characters_to_transfer(void); static void transfer_characters(DIRECTION); static AREA_POINT * location_after_transition(AREA_POINT *, DIRECTION); /* * moves the player's party to a different area */ void move_party_to_area(const WORLD_POINT *target_point, DIRECTION direction, bool from_nowhere ) { /* regular area transition */ if (!from_nowhere) { save_point_create(); remove_splatter(); grab_characters_to_transfer(); area_write(NULL); area_clear(); /* special case: the PC is coming from "nowhere" */ } else { CharacterTransferList = list_new(); EventTransferList = list_new(); list_add(CharacterTransferList, player_character()); } area_read(target_point); transfer_characters(direction); update_view_character(player_controlled_character()); } /* * grabs all characters which are supposed to be transfered */ static void grab_characters_to_transfer(void) { LIST_NODE *node; CharacterTransferList = list_new(); EventTransferList = list_new(); for (node = area_character_list()->head; node != NULL; ) { CHARACTER *character; character = (CHARACTER *)node->data; node = node->next; if (character->party != PARTY_PLAYER) { continue; } remove_character(character, EventTransferList); list_add(CharacterTransferList, character); } } /* * transfers characters */ static void transfer_characters(DIRECTION move_direction) { LIST_NODE *node; AREA_POINT spawn_start; location_after_transition(&spawn_start, move_direction); for (node = CharacterTransferList->head; node != NULL; node = node->next) { CHARACTER *character; AREA_POINT area_point; character = (CHARACTER *)node->data; area_point = spawn_start; if (!sector_is_class(&area_point, SC_MOVE_TARGET_SAFE)) { SECTOR *sector; sector = sector_adjacent(&area_point, SC_MOVE_TARGET_SAFE ); if (sector == NULL) { die("*** CORE ERROR *** no room "\ "to transfer characters" ); } } place_character(character, &area_point); } list_free(CharacterTransferList); list_add_list(area_event_list(), EventTransferList); list_free(EventTransferList); } /* * returns the location at which the party starts after transition */ static AREA_POINT * location_after_transition(AREA_POINT *location, DIRECTION move_direction ) { const AREA_SECTION *bounds; bounds = area_bounds(); if (move_direction == DIRECTION_ELEVATOR) { sector_elevator(location); return location; } else if (move_direction == DIRECTION_WAY_UP) { sector_way_down(location); return location; } else if (move_direction == DIRECTION_WAY_DOWN) { sector_way_up(location); return location; } else if (move_direction == DIRECTION_LEFT) { location->x = bounds->right; location->y = bounds->bottom / 2; } else if (move_direction == DIRECTION_RIGHT) { location->x = bounds->left; location->y = bounds->bottom / 2; } else if (move_direction == DIRECTION_UP) { location->x = bounds->right / 2; location->y = bounds->bottom; } else if (move_direction == DIRECTION_DOWN) { location->x = bounds->right / 2; location->y = bounds->top; } else if (move_direction == DIRECTION_UP_LEFT) { location->x = bounds->right; location->y = bounds->bottom; } else if (move_direction == DIRECTION_UP_RIGHT) { location->x = bounds->left; location->y = bounds->bottom; } else if (move_direction == DIRECTION_DOWN_LEFT) { location->x = bounds->right; location->y = bounds->top; } else if (move_direction == DIRECTION_DOWN_RIGHT) { location->x = bounds->left; location->y = bounds->top; } return location; }