Files
oboe/Win32/game/boe.town.cpp
2014-07-30 12:08:10 -06:00

1684 lines
57 KiB
C++

#include <windows.h>
#include <cstdio>
#include "global.h"
#include "boe.graphics.h"
#include "boe.newgraph.h"
#include "boe.fileio.h"
#include "boe.items.h"
#include "boe.itemdata.h"
#include "boe.monster.h"
#include "boe.town.h"
#include "boe.combat.h"
#include "boe.party.h"
#include "boe.text.h"
#include "tools/soundtool.h"
#include "boe.fields.h"
#include "boe.locutils.h"
#include "boe.infodlg.h"
#include "boe.graphutil.h"
#include "tools/dlogtool.h"
#include "tools/mathutil.h"
#include "globvar.h"
void force_town_enter(short which_town,location where_start)
{
town_force = which_town;
town_force_loc = where_start;
}
void start_town_mode(short which_town, short entry_dir)
//short entry_dir; // if 9, go to forced
{
short i,m,n;
char message[60];
short j,k,town_number;
short former_town;
location loc;
unsigned char temp;
Boolean monsters_loaded = false, town_toast = false;
Boolean play_town_sound = false;
if (town_force < INVALID_TOWN) which_town = town_force;
else play_town_sound = true;
former_town = town_number = which_town;
if ((town_number < 0) || (town_number >= scenario.num_towns))
{
char text[256];
wsprintf(text, "town number = %i, max = %i, %i, %i", town_number,
scenario.num_towns, sizeof(short), sizeof(WORD));
give_error("The scenario tried to put you into a town that doesn't exist.",text,0);
return;
}
// Now adjust town number as necessary.
for (i = 0; i < 10; i++)
if ((scenario.town_to_add_to[i] >= 0) && (scenario.town_to_add_to[i] < 200) &&
(town_number == scenario.town_to_add_to[i]) &&
(sd_legit(scenario.flag_to_add_to_town[i][0],scenario.flag_to_add_to_town[i][1]) == true))
{
former_town = town_number;
town_number += PSD[scenario.flag_to_add_to_town[i][0]][scenario.flag_to_add_to_town[i][1]];
// Now update horses & boats
for (i = 0; i < 30; i++)
if ((party.horses[i].exists == true) && (party.horses[i].which_town == former_town))
party.horses[i].which_town = town_number;
for (i = 0; i < 30; i++)
if ((party.boats[i].exists == true) && (party.boats[i].which_town == former_town))
party.boats[i].which_town = town_number;
}
if ((town_number < 0) || (town_number >= scenario.num_towns))
{
give_error("The scenario tried to put you into a town that doesn't exist.","2",0);
return;
}
overall_mode = MODE_TOWN;
load_town(town_number,0,0,NULL);
c_town.town_num = town_number;
if (play_town_sound == true)
{
if (c_town.town.lighting > 0) play_sound(95);
else play_sound(16);
}
belt_present = false;
// Set up map, using stored map
for (i = 0; i < town_size[town_type]; i++)
for (j = 0; j < town_size[town_type]; j++) {
c_town.explored[i][j] = 0;
if (town_maps.town_maps[c_town.town_num][i / 8][j] & (char)(s_pow(2,i % 8)))
make_explored(i,j);
/* if (t_d.terrain[i][j] == 0) current_ground = 0;
else if (t_d.terrain[i][j] == 2) current_ground = 2;*/
if ((scenario.ter_types[t_d.terrain[i][j]].special >= TER_SPEC_CONVEYOR_NORTH) &&
(scenario.ter_types[t_d.terrain[i][j]].special <= TER_SPEC_CONVEYOR_WEST))
belt_present = true;
}
c_town.hostile = 0;
c_town.monst.which_town = town_number;
c_town.monst.friendly = 0;
for (i = 0; i < 4; i++)
if (town_number == party.creature_save[i].which_town) {
c_town.monst = party.creature_save[i];
monsters_loaded = true;
for (j = 0; j < T_M; j++) {
if (loc_off_act_area(c_town.monst.dudes[j].m_loc) == true)
c_town.monst.dudes[j].active = 0;
if (c_town.monst.dudes[j].active == 2)
c_town.monst.dudes[j].active = 1;
c_town.monst.dudes[j].m_loc = t_d.creatures[j].start_loc;
c_town.monst.dudes[j].m_d.health = c_town.monst.dudes[j].m_d.m_health;
c_town.monst.dudes[j].m_d.mp = c_town.monst.dudes[j].m_d.max_mp;
c_town.monst.dudes[j].m_d.morale = c_town.monst.dudes[j].m_d.m_morale;
for (k = 0; k < 15; k++)
c_town.monst.dudes[j].m_d.status[k] = 0;
if (c_town.monst.dudes[j].summoned > 0)
c_town.monst.dudes[j].active = 0;
monst_target[j] = 6;
}
// Now, travelling NPCs might have arrived. Go through and put them in.
// These should have protected status (i.e. spec1 >= 200, spec1 <= 204)
for (j = 0; j < T_M; j++) {
switch (c_town.monst.dudes[j].monst_start.time_flag){
case 4: case 5 : case 6:
if ((((short) (party.age / 1000) % 3) + 4) != c_town.monst.dudes[j].monst_start.time_flag)
c_town.monst.dudes[j].active = 0;
else {
c_town.monst.dudes[j].active = 1;
c_town.monst.dudes[j].monst_start.spec_enc_code = 0;
// Now remove time flag so it doesn't get reappearing
c_town.monst.dudes[j].monst_start.time_flag = 0;
c_town.monst.dudes[j].m_loc = t_d.creatures[j].start_loc;
c_town.monst.dudes[j].m_d.health = c_town.monst.dudes[j].m_d.m_health;
}
break ;
// Now, appearing/disappearing monsters might have arrived/disappeared.
case 1:
if (day_reached(c_town.monst.dudes[j].monst_start.monster_time, c_town.monst.dudes[j].monst_start.time_code) == true)
{
c_town.monst.dudes[j].active = 1;
c_town.monst.dudes[j].monst_start.time_flag=0; // Now remove time flag so it doesn't get reappearing
}
break;
case 2:
if (day_reached(c_town.monst.dudes[j].monst_start.monster_time, c_town.monst.dudes[j].monst_start.time_code) == true)
{
c_town.monst.dudes[j].active = 0;
c_town.monst.dudes[j].monst_start.time_flag=0; // Now remove time flag so it doesn't get disappearing again
}
break;
case 7:
if (calc_day() >= party.key_times[c_town.monst.dudes[j].monst_start.time_code]){ //calc_day is used because of the "definition" of party.key_times
c_town.monst.dudes[j].active = 1;
c_town.monst.dudes[j].monst_start.time_flag=0; // Now remove time flag so it doesn't get reappearing
}
break;
case 8:
if (calc_day() >= party.key_times[c_town.monst.dudes[j].monst_start.time_code]){
c_town.monst.dudes[j].active = 0;
c_town.monst.dudes[j].monst_start.time_flag=0; // Now remove time flag so it doesn't get disappearing again
}
break;
case 0:
break;
default:
break;
}
}
for (j = 0; j < town_size[town_type]; j++)
for (k = 0; k < town_size[town_type]; k++) { // now load in saved setup,
// except that barrels and crates restore to orig locs
temp = setup_save.setup[i][j][k] & 231;
misc_i[j][k] = (misc_i[j][k] & 24) | temp;//setup_save.setup[i][j][k];
}
}
if (monsters_loaded == false) {
for (i = 0; i < T_M; i++)
if (t_d.creatures[i].number == 0) {
c_town.monst.dudes[i].active = 0;
c_town.monst.dudes[i].number = 0;
c_town.monst.dudes[i].monst_start.time_flag = 0;
c_town.monst.dudes[i].m_loc.x = 80;
c_town.monst.dudes[i].monst_start.spec_enc_code = 0;
}
else {
// First set up the values.
monst_target[i] = 6;
c_town.monst.dudes[i].active = 1;
c_town.monst.dudes[i].number = t_d.creatures[i].number;
c_town.monst.dudes[i].attitude = t_d.creatures[i].start_attitude;
c_town.monst.dudes[i].m_loc = t_d.creatures[i].start_loc;
c_town.monst.dudes[i].mobile = t_d.creatures[i].mobile;
c_town.monst.dudes[i].m_d = return_monster_template(c_town.monst.dudes[i].number);
c_town.monst.dudes[i].summoned = 0;
c_town.monst.dudes[i].monst_start = t_d.creatures[i];
if (c_town.monst.dudes[i].monst_start.spec_enc_code > 0)
c_town.monst.dudes[i].active = 0;
// Now, if necessary, fry the monster.
switch (c_town.monst.dudes[i].monst_start.time_flag) {
case 1:
if (day_reached(c_town.monst.dudes[i].monst_start.monster_time,
c_town.monst.dudes[i].monst_start.time_code) == false)
c_town.monst.dudes[i].active = 0;
break;
case 2:
if (day_reached(c_town.monst.dudes[i].monst_start.monster_time,
c_town.monst.dudes[i].monst_start.time_code) == true)
c_town.monst.dudes[i].active = 0;
break;
case 3:
// unused
break;
case 4: case 5: case 6:
if ((((short) (party.age / 1000) % 3) + 4) != c_town.monst.dudes[i].monst_start.time_flag) {
c_town.monst.dudes[i].active = 0;
c_town.monst.dudes[i].monst_start.spec_enc_code = 50;
}
else {
c_town.monst.dudes[i].active = 1;
// Now remove time flag so it doesn't keep reappearing
c_town.monst.dudes[i].monst_start.time_flag = 0;
}
break;
case 7:
if (calc_day() < party.key_times[c_town.monst.dudes[i].monst_start.time_code])
c_town.monst.dudes[i].active = 0;
break;
case 8:
if (calc_day() >= party.key_times[c_town.monst.dudes[i].monst_start.time_code])
c_town.monst.dudes[i].active = 0;
break;
case 9:
if (c_town.town.town_chop_time > 0)
if (day_reached(c_town.town.town_chop_time,c_town.town.town_chop_key) == true) {
c_town.monst.dudes[i].active += 10;
break;
}
c_town.monst.dudes[i].active = 0;
break;
case 0:
break;
default:
break; }
}
}
// Now munch all large monsters that are misplaced
// only large monsters, as some smaller monsters are intentionally placed
// where they cannot be
for (i = 0; i < T_M; i++) {
if (c_town.monst.dudes[i].active > 0)
if (((c_town.monst.dudes[i].m_d.x_width > 1) || (c_town.monst.dudes[i].m_d.y_width > 1)) &&
(monst_can_be_there(c_town.monst.dudes[i].m_loc,i) == false))
c_town.monst.dudes[i].active = 0;
}
// Trash town?
if (party.m_killed[c_town.town_num] > c_town.town.max_num_monst) {
town_toast = true;
add_string_to_buf("Area has been cleaned out.");
}
if (c_town.town.town_chop_time > 0) {
if (day_reached(c_town.town.town_chop_time,c_town.town.town_chop_key) == true){
//add_string_to_buf("Area has been abandoned.");
for (i = 0; i < T_M; i++)
if ((c_town.monst.dudes[i].active > 0) && (c_town.monst.dudes[i].active < 10) &&
(c_town.monst.dudes[i].attitude % 2 == 1))
c_town.monst.dudes[i].active += 10;
town_toast = true;
}
}
if (town_toast == true) {
for (i = 0; i < T_M; i++)
if (c_town.monst.dudes[i].active >= 10)
c_town.monst.dudes[i].active -= 10;
else c_town.monst.dudes[i].active = 0;
}
if (((short) town_toast > 0) && (c_town.town.spec_on_entry_if_dead >= 0)){ //handle entering town special events
special_queue[queue_position].queued_special = c_town.town.spec_on_entry_if_dead; //there's always at last one free slot in the special queue for entering town special, if exists
special_queue[queue_position].mode = SPEC_ENTER_TOWN;
queue_position = min(19, queue_position + 1);//safety valve
}
else if (c_town.town.spec_on_entry >= 0){
special_queue[queue_position].queued_special = c_town.town.spec_on_entry; //there's always at last one free slot in the special queue for entering town special, if exists
special_queue[queue_position].mode = SPEC_ENTER_TOWN;
queue_position = min(19, queue_position + 1);//safety valve
}
// Flush excess doomguards and viscous goos
for (i = 0; i < T_M; i++)
if ((c_town.monst.dudes[i].m_d.spec_skill == MONSTER_SPLITS) &&
(c_town.monst.dudes[i].number != t_d.creatures[i].number))
c_town.monst.dudes[i].active = 0;
quickfire = false;
crate = false;
barrel = false;
web = false;
fire_barrier = false;
force_barrier = false;
// Set up field booleans, correct for doors
for (j = 0; j < town_size[town_type]; j++)
for (k = 0; k < town_size[town_type]; k++) {
loc.x = j; loc.y = k;
if (loc.isDoor()) misc_i[j][k] = misc_i[j][k] & 3;
// Set up field booleans
if (is_web(j,k) == true) web = true;
if (is_crate(j,k) == true) crate = true;
if (is_barrel(j,k) == true) barrel = true;
if (is_fire_barrier(j,k) == true) fire_barrier = true;
if (is_force_barrier(j,k) == true) force_barrier = true;
if (is_quickfire(j,k) == true) quickfire = true;
}
// Set up items, maybe place items already there
for (i = 0; i < NUM_TOWN_ITEMS; i++)
t_i.items[i] = return_dummy_item();
for (j = 0; j < 3; j++)
if (scenario.store_item_towns[j] == town_number) {
for (i = 0; i < NUM_TOWN_ITEMS; i++)
t_i.items[i] = stored_items[j].items[i];
}
for (i = 0; i < 64; i++)
if ((c_town.town.preset_items[i].item_code >= 0)
&& (((party.item_taken[c_town.town_num][i / 8] & s_pow(2,i % 8)) == 0) ||
(c_town.town.preset_items[i].always_there == true))) {
for (j = 0; j < NUM_TOWN_ITEMS; j++)
// place the preset item, if party hasn't gotten it already
if (t_i.items[j].variety == ITEM_TYPE_NO_ITEM) {
t_i.items[j] = get_stored_item(c_town.town.preset_items[i].item_code);
t_i.items[j].item_loc = c_town.town.preset_items[i].item_loc;
// Not using the items data flags, starting with forcing an ability
if (c_town.town.preset_items[i].ability >= ITEM_NO_ABILITY) {
switch (t_i.items[j].variety) {
case ITEM_TYPE_GOLD: case ITEM_TYPE_FOOD: // If gold or food, this value is amount
if (c_town.town.preset_items[i].ability > ITEM_NO_ABILITY)
t_i.items[j].item_level = c_town.town.preset_items[i].ability;
break;
}
}
if (c_town.town.preset_items[i].property == true)
t_i.items[j].item_properties = t_i.items[j].item_properties | 2;
if (town_toast == true)
t_i.items[j].item_properties = t_i.items[j].item_properties & 253;
if (c_town.town.preset_items[i].contained == true)
t_i.items[j].item_properties = t_i.items[j].item_properties | 8;
t_i.items[j].is_special = i + 1;
j = NUM_TOWN_ITEMS;
}
}
for (i = 0; i < T_M; i++)
if (loc_off_act_area(c_town.monst.dudes[i].m_loc) == true)
c_town.monst.dudes[i].active = 0;
for (i = 0; i < NUM_TOWN_ITEMS; i++)
if (loc_off_act_area(t_i.items[i].item_loc) == true)
t_i.items[i].variety = ITEM_TYPE_NO_ITEM;
// Clean out unwanted monsters
for (i = 0; i < T_M; i++)
if (sd_legit(c_town.monst.dudes[i].monst_start.spec1,c_town.monst.dudes[i].monst_start.spec2) == true) {
if (party.stuff_done[c_town.monst.dudes[i].monst_start.spec1][c_town.monst.dudes[i].monst_start.spec2] > 0)
c_town.monst.dudes[i].active = 0;
}
erase_specials();
make_town_trim(0);
c_town.p_loc = (entry_dir < 9) ? c_town.town.start_locs[entry_dir] : town_force_loc;
center = c_town.p_loc;
if (party.in_boat >= 0) {
party.boats[party.in_boat].which_town = which_town;
party.boats[party.in_boat].boat_loc = c_town.p_loc;
}
if (party.in_horse >= 0) {
party.horses[party.in_horse].which_town = which_town;
party.horses[party.in_horse].horse_loc = c_town.p_loc;
}
// End flying
if (party.stuff_done[SDF_FLYING] > 0)
{
party.stuff_done[SDF_FLYING] = 0;
add_string_to_buf("You land, and enter. ");
}
// No hostile monsters present.
party.stuff_done[SDF_MONSTERS_ALERTNESS] = 0;
add_string_to_buf("Now entering:");
sprintf (message, " %-30.30s ",data_store->town_strs[0]);
add_string_to_buf(message);
// clear entry space, and check exploration
misc_i[c_town.p_loc.x][c_town.p_loc.y] = misc_i[c_town.p_loc.x][c_town.p_loc.y] & 3;
update_explored(c_town.p_loc);
// If a PC dead, drop his items
for (m = 0; m < 6; m++)
for (n = 0; n < 24; n++)
if ((adven[m].isAlive() == false) && (adven[m].items[n].variety != ITEM_TYPE_NO_ITEM)) {
place_item(adven[m].items[n],c_town.p_loc,true);
adven[m].items[n].variety = ITEM_TYPE_NO_ITEM;
}
for (i = 0; i < T_M; i++)
{monster_targs[i].x = 0; monster_targs[i].y = 0;}
//// check horses
for (i = 0; i < 30; i++) {
if ((scenario.scen_boats[i].which_town >= 0) && (scenario.scen_boats[i].boat_loc.x >= 0)) {
if (party.boats[i].exists == false) {
party.boats[i] = scenario.scen_boats[i];
party.boats[i].exists = true;
}
}
if ((scenario.scen_horses[i].which_town >= 0) && (scenario.scen_horses[i].horse_loc.x >= 0)) {
if (party.horses[i].exists == false) {
party.horses[i] = scenario.scen_horses[i];
party.horses[i].exists = true;
}
}
}
// Place correct graphics
redraw_screen(0);
clear_map();
reset_item_max();
town_force = INVALID_TOWN;
}
location end_town_mode(short switching_level,location destination) // returns new party location
{
location to_return;
short i,j,k;
Boolean data_saved = false,combat_end = false;
if (is_combat()) combat_end = true;
if (overall_mode == MODE_TOWN) {
for (i = 0; i < 4; i++)
if (party.creature_save[i].which_town == c_town.town_num) {
party.creature_save[i] = c_town.monst;
for (j = 0; j < town_size[town_type]; j++)
for (k = 0; k < town_size[town_type]; k++)
setup_save.setup[i][j][k] = misc_i[j][k];
data_saved = true;
}
if (data_saved == false) {
party.creature_save[party.at_which_save_slot] = c_town.monst;
for (j = 0; j < town_size[town_type]; j++)
for (k = 0; k < town_size[town_type]; k++)
setup_save.setup[party.at_which_save_slot][j][k] = misc_i[j][k];
party.at_which_save_slot = (party.at_which_save_slot == 3) ? 0 : party.at_which_save_slot + 1;
}
// Store items, if necessary
for (j = 0; j < 3; j++)
if (scenario.store_item_towns[j] == c_town.town_num) {
for (i = 0; i < NUM_TOWN_ITEMS; i++)
if ((t_i.items[i].variety != ITEM_TYPE_NO_ITEM) && (t_i.items[i].is_special == 0) &&
((t_i.items[i].item_loc.x >= scenario.store_item_rects[j].left) &&
(t_i.items[i].item_loc.x <= scenario.store_item_rects[j].right) &&
(t_i.items[i].item_loc.y >= scenario.store_item_rects[j].top) &&
(t_i.items[i].item_loc.y <= scenario.store_item_rects[j].bottom)) ) {
stored_items[j].items[i] = t_i.items[i];
}
else stored_items[j].items[i].variety = ITEM_TYPE_NO_ITEM;
}
// Clean up special data, just in case
for (i = 0; i < T_M; i++) {
c_town.monst.dudes[i].monst_start.spec1 = 0;
c_town.monst.dudes[i].monst_start.spec2 = 0;
}
// Now store map
for (i = 0; i < town_size[town_type]; i++)
for (j = 0; j < town_size[town_type]; j++)
if (is_explored(i,j) > 0) {
town_maps.town_maps[c_town.town_num][i / 8][j] = town_maps.town_maps[c_town.town_num][i / 8][j] |
(char) (s_pow(2,i % 8));
}
to_return = party.p_loc;
for (i = 0; i < 30; i++)
if ((party.party_event_timers[i] > 0) && (party.global_or_town[i] == 1))
party.party_event_timers[i] = 0;
}
// Check for exit specials, if leaving town
if (switching_level == 0) {
to_return = party.p_loc;
if (is_town()) { //there's always at last a free slot in the special queue for exiting town special
if (destination.x <= c_town.town.in_town_rect.left) {
if (c_town.town.exit_locs[1].x > 0)
to_return = c_town.town.exit_locs[1].toGlobal();
else to_return.x--;
party.p_loc = to_return; party.p_loc.x++;
if(c_town.town.exit_specs[1] >= 0){//if there's a special "on exit" node to execute
special_queue[queue_position].queued_special = c_town.town.exit_specs[1];
special_queue[queue_position].mode = SPEC_LEAVE_TOWN;
queue_position = min(19, queue_position + 1);//safety valve
}
}
else if (destination.x >= c_town.town.in_town_rect.right) {
if (c_town.town.exit_locs[3].x > 0)
to_return = c_town.town.exit_locs[3].toGlobal();
else to_return.x++;
party.p_loc = to_return; party.p_loc.x--;
if(c_town.town.exit_specs[3] >= 0){//if there's a special "on exit" node to execute
special_queue[queue_position].queued_special = c_town.town.exit_specs[3];
special_queue[queue_position].mode = SPEC_LEAVE_TOWN;
queue_position = min(19, queue_position + 1);//safety valve
}
}
else if (destination.y <= c_town.town.in_town_rect.top) {
if (c_town.town.exit_locs[0].x > 0)
to_return = c_town.town.exit_locs[0].toGlobal();
else to_return.y--;
party.p_loc = to_return; party.p_loc.y++;
if(c_town.town.exit_specs[0] >= 0){//if there's a special "on exit" node to execute
special_queue[queue_position].queued_special = c_town.town.exit_specs[0];
special_queue[queue_position].mode = SPEC_LEAVE_TOWN;
queue_position = min(19, queue_position + 1);//safety valve
}
}
else if (destination.y >= c_town.town.in_town_rect.bottom) {
if (c_town.town.exit_locs[2].x > 0)
to_return = c_town.town.exit_locs[2].toGlobal();
else to_return.y++;
party.p_loc = to_return; party.p_loc.y--;
if(c_town.town.exit_specs[2] >= 0){//if there's a special "on exit node" to execute
special_queue[queue_position].queued_special = c_town.town.exit_specs[2];
special_queue[queue_position].mode = SPEC_LEAVE_TOWN;
queue_position = min(19, queue_position + 1);//safety valve
}
}
}
}
if (switching_level == 0)
{
fix_boats();
overall_mode = MODE_OUTDOORS;
erase_out_specials();
party.stuff_done[SDF_STEALTH] = 0;
for (i = 0; i < 6; i++)
for (j = 0; j < 15; j++)
if ((j != 2) && (j != 7) && (j != 9))
adven[i].status[j] = 0;
update_explored(to_return);
redraw_screen(0);
}
if (combat_end == false) clear_map();
c_town.town_num = -1; //no longer in a town
return to_return;
}
void start_town_combat(short direction)
{
short i;
create_town_combat_terrain();
place_party(direction);
if (current_pc == 6) {
for (i = 0; i < 6; i++)
if (adven[i].isAlive()) {
current_pc = i;
i = 6;
}
}
center = pc_pos[current_pc];
which_combat_type = 1;
overall_mode = MODE_COMBAT;
combat_active_pc = 6;
for (i = 0; i < T_M; i++)
monst_target[i] = 6;
for (i = 0; i < 6; i++) {
last_attacked[i] = T_M + 10;
pc_parry[i] = 0;
pc_dir[i] = direction;
adven[current_pc].direction = direction;
if (adven[i].isAlive())
update_explored(pc_pos[i]);
}
store_current_pc = current_pc;
current_pc = 0;
set_pc_moves();
pick_next_pc();
center = pc_pos[current_pc];
draw_buttons(0);
put_pc_screen();
set_stat_window(current_pc);
give_help(48,49,0);
}
short end_town_combat()
{
short num_tries = 0,r1,i;
r1 = get_ran(1,0,5);
while ((adven[r1].isAlive() == false) && (num_tries++ < 1000))
r1 = get_ran(1,0,5);
c_town.p_loc = pc_pos[r1];
overall_mode = MODE_TOWN;
current_pc = store_current_pc;
if (adven[current_pc].isAlive() == false)
current_pc = first_active_pc();
for (i = 0; i < 6; i++)
pc_parry[i] = 0;
return pc_dir[r1];
}
void place_party(short direction)
{
Boolean spot_ok[14] = {true,true,true,true,true,true,true,
true,true,true,true,true,true,true};
location pos_locs[14];
location check_loc;
short x_adj,y_adj,how_many_ok = 1,where_in_a = 0,i;
for (i = 0; i < 14; i++) {
check_loc = c_town.p_loc;
if (direction % 4 < 2)
x_adj = ((direction % 2 == 0) ? hor_vert_place[i].x : diag_place[i].x);
else x_adj = ((direction % 2 == 0) ? hor_vert_place[i].y : diag_place[i].y);
if (direction % 2 == 0)
x_adj = (direction < 4) ? x_adj : -1 * x_adj;
else x_adj = ((direction == 1) || (direction == 7)) ? -1 * x_adj : x_adj;
check_loc.x -= x_adj;
if (direction % 4 < 2)
y_adj = ((direction % 2 == 0) ? hor_vert_place[i].y : diag_place[i].y);
else y_adj = ((direction % 2 == 0) ? hor_vert_place[i].x : diag_place[i].x);
if (direction % 2 == 0)
y_adj = ((direction > 1) && (direction < 6)) ? y_adj : -1 * y_adj;
else y_adj = ((direction == 3) || (direction == 1)) ? -1 * y_adj : y_adj;
check_loc.y -= y_adj;
pos_locs[i] = check_loc;
if ((loc_off_act_area(check_loc) == false) &&
(is_blocked(check_loc) == false) && (is_special(check_loc) == false) && (get_obscurity(check_loc.x,check_loc.y) == 0)
&& (can_see(c_town.p_loc,check_loc,1) < 1)) {
spot_ok[i] = true;
how_many_ok += (i > 1) ? 1 : 0;
}
else spot_ok[i] = false;
if (i == 0)
spot_ok[i] = true;
}
i = 0;
while (i < 6) {
if (adven[i].isAlive()) {
if (how_many_ok == 1)
pc_pos[i] = pos_locs[where_in_a];
else {
pc_pos[i] = pos_locs[where_in_a];
if (how_many_ok > 1)
where_in_a++;
how_many_ok--;
while (spot_ok[where_in_a] == false)
where_in_a++;
}
}
i++;
}
}
void create_town_combat_terrain()
{
location where;
for (where.x = 0; where.x < town_size[town_type]; where.x++)
for (where.y = 0; where.y < town_size[town_type]; where.y++)
combat_terrain[where.x][where.y] = t_d.terrain[where.x][where.y];
}
void create_out_combat_terrain(short type,short num_walls)
// spec_code is encounter's spec_code
{
short i,j,k,r1,ter_type;
// 0 grass 1 cave 2 mntn 3 bridge 4 cave bridge 5 rubble cave 6 cave tree 7 cave mush
// 8 cave swamp 9 surface rocks 10 surface swamp 11 surface woods 12 s. shrub 13 stalags
// 14 cave road, 15 grass road, 16 mountain road
short general_types[260] = {1,1,0,0,0,1,1,1,1,1,
1,1,1,1,1,1,1,1,2,2,
2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,// 50
0,3,3,3,3,3,3,5,5,5,
6,6,7,7,1,1,8,9,10,11,
11,11,12,13,13,9,9,9,1,1,
1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,// 100
1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,// 150
1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,
1,0,1,1,1,1,1,1,1,0,
0,0,0,0,0,0,0,0,0,0,
0,0,14,15,16,0,0,1,1,1,// 200
1,0,2,1,1,1,0,1,1,1,
1,1,0,0,0,0,1,0,1,1,
1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1};// 250
short ter_base[17] = {2,0,36,50,71, 0,0,0,0,2, 2,2,2,0, 0,2,36};
//short ground_type[14] = {2,0,36,50,71, 0,0,0,0,2, 2,2,2,0};
location special_ter_locs[15] =
{
location(11,10),location(11,14),location(10,20),location(11,26),location(9,30),
location(15,19),location(23,19),location(19,29),location(20,11),location(28,16),
location(28,24),location(27,19),location(27,29),location(15,28),location(19,19)
};
unsigned char cave_pillar[4][4] = {{0,14,11,1},{14,19,20,11},{17,18,21,8},{1,17,8,0}};
unsigned char mntn_pillar[4][4] = {{37,29,27,36},{29,33,34,27},{31,32,35,25},{36,31,25,37}};
unsigned char surf_lake[4][4] = {{56,55,54,3},{57,50,61,54},{58,51,59,53},{3,4,58,52}};
unsigned char cave_lake[4][4] = {{93,96,71,71},{96,71,71,71},{71,71,71,96},{71,71,71,96}};
location stuff_ul;
short terrain_odds[17][10] = {{3,80,4,40,115,20,114,10,112,1},
{1,50,93,25,94,5,98,10,95,1},
{37,20,0,0,0,0,0,0,0,0},
{64,3,63,1,0,0,0,0,0,0},
{74,1,0,0,0,0,0,0,0,0},
{84,700,97,30,98,20,92,4,95,1},
{93,280,91,300,92,270,95,7,98,10},
{1,800,93,600,94,10,92,10,95,4},
{1,700,96,200,95,100,92,10,112,5},
{3,600,87,90,110,20,114,6,113,2},
{3,200,4,400,111,250,0,0,0,0},
{3,200,4,300,112,50,113,60,114,100},
{3,100,4,250,115,120,114,30,112,2},
{1,25,84,15,98,300,97,280,0,0},
{1,50,93,25,94,5,98,10,95,1},
{3,80,4,40,115,20,114,10,112,1},
{37,20,0,0,0,0,0,0,0,0}}; // ter then odds then ter then odds ...
ter_type = scenario.ter_types[type].picture;
if(ter_type == 401 || ter_type == 402)
ter_type = 4;
else if (ter_type > 260)
ter_type = 1;
else ter_type = general_types[ter_type];
for (i = 0; i < 48; i++)
for (j = 0; j < 48; j++) {
c_town.explored[i][j] = 0;
misc_i[i][j] = 0;
sfx[i][j] = 0;
if ((j <= 8) || (j >= 35) || (i <= 8) || (i >= 35))
t_d.terrain[i][j] = 90;
else t_d.terrain[i][j] = ter_base[ter_type];
}
for (i = 0; i < 48; i++)
for (j = 0; j < 48; j++)
for (k = 0; k < 5; k++)
if ((t_d.terrain[i][j] != 90) && (get_ran(1,1,1000) < terrain_odds[ter_type][k * 2 + 1]))
t_d.terrain[i][j] = terrain_odds[ter_type][k * 2];
t_d.terrain[0][0] = ter_base[ter_type];
if (ter_type == 3) {
t_d.terrain[0][0] = 83;
for (i = 15; i < 26; i++)
for (j = 9; j < 35; j++)
t_d.terrain[i][j] = 83;
}
if(ter_type == 4){
t_d.terrain[0][0] = 82;
for (i = 15; i < 26; i++)
for (j = 9; j < 35; j++)
t_d.terrain[i][j] = 82;
}
if (ter_type == 14 || ter_type == 15 || ter_type == 16) {
t_d.terrain[0][0] = 82;
for (i = 19; i < 23; i++)
for (j = 9; j < 35; j++)
t_d.terrain[i][j] = 82;
}
// Now place special lakes, etc.
if (ter_type == 2)
for (i = 0; i < 15; i++)
if (get_ran(1,0,5) == 1) {
stuff_ul = special_ter_locs[i];
for (j = 0; j < 4; j++)
for (k = 0; k < 4; k++)
t_d.terrain[stuff_ul.x + j][stuff_ul.y + k] = mntn_pillar[k][j];
}
if (t_d.terrain[0][0] == 0)
for (i = 0; i < 15; i++)
if (get_ran(1,0,25) == 1) {
stuff_ul = special_ter_locs[i];
for (j = 0; j < 4; j++)
for (k = 0; k < 4; k++)
t_d.terrain[stuff_ul.x + j][stuff_ul.y + k] = cave_pillar[k][j];
}
if (t_d.terrain[0][0] == 0)
for (i = 0; i < 15; i++)
if (get_ran(1,0,40) == 1) {
stuff_ul = special_ter_locs[i];
for (j = 0; j < 4; j++)
for (k = 0; k < 4; k++)
t_d.terrain[stuff_ul.x + j][stuff_ul.y + k] = cave_lake[k][j];
}
if (t_d.terrain[0][0] == 2)
for (i = 0; i < 15; i++)
if (get_ran(1,0,40) == 1) {
stuff_ul = special_ter_locs[i];
for (j = 0; j < 4; j++)
for (k = 0; k < 4; k++)
t_d.terrain[stuff_ul.x + j][stuff_ul.y + k] = surf_lake[k][j];
}
if (ter_base[ter_type] == 0) {
for (i = 0; i < num_walls; i++) {
r1 = get_ran(1,0,3);
for (j = 9; j < 35; j++)
switch (r1) {
case 0:
t_d.terrain[j][8] = 6;
break;
case 1:
t_d.terrain[8][j] = 9;
break;
case 2:
t_d.terrain[j][35] = 12;
break;
case 3:
t_d.terrain[32][j] = 15;
break;
}
}
if ((t_d.terrain[17][8] == 6) && (t_d.terrain[8][20] == 9))
t_d.terrain[8][8] = 21;
if ((t_d.terrain[32][20] == 15) && (t_d.terrain[17][35] == 12))
t_d.terrain[32][35] = 19;
if ((t_d.terrain[17][8] == 6) && (t_d.terrain[32][20] == 15))
t_d.terrain[32][8] = 32;
if ((t_d.terrain[8][20] == 9) && (t_d.terrain[17][35] == 12))
t_d.terrain[8][35] = 20;
}
if (ter_base[ter_type] == 36) {
for (i = 0; i < num_walls; i++) {
r1 = get_ran(1,0,3);
for (j = 9; j < 35; j++)
switch (r1) {
case 0:
t_d.terrain[j][8] = 24;
break;
case 1:
t_d.terrain[8][j] = 26;
break;
case 2:
t_d.terrain[j][35] = 28;
break;
case 3:
t_d.terrain[32][j] = 30;
break;
}
}
if ((t_d.terrain[17][8] == 6) && (t_d.terrain[8][20] == 9))
t_d.terrain[8][8] = 35;
if ((t_d.terrain[32][20] == 15) && (t_d.terrain[17][35] == 12))
t_d.terrain[32][35] = 33;
if ((t_d.terrain[17][8] == 6) && (t_d.terrain[32][20] == 15))
t_d.terrain[32][8] = 32;
if ((t_d.terrain[8][20] == 9) && (t_d.terrain[17][35] == 12))
t_d.terrain[8][35] = 34;
}
for (i = 0; i < 48; i++)
for (j = 0; j < 48; j++)
combat_terrain[i][j] = t_d.terrain[i][j];
make_town_trim(1);
}
/*void elim_monst(unsigned char which,short spec_a,short spec_b)
{
short i;
if (party.stuff_done[spec_a][spec_b] > 0) {
for (i = 0; i < T_M; i++)
if (c_town.monst.dudes[i].number == which) {
c_town.monst.dudes[i].active = 0;
}
}
}*/
void dump_gold(short print_mes)
//short print_mes; // 0 - no 1 - yes
{
// Mildly kludgy gold check
if (party.gold > 30000) {
party.gold = 30000;
if (print_mes == 1) {
put_pc_screen();
add_string_to_buf("Excess gold dropped. ");
print_buf();
}
}
if (party.food > 25000) {
party.food = 25000;
if (print_mes == 1) {
put_pc_screen();
add_string_to_buf("Excess food dropped. ");
print_buf();
}
}
}
void erase_specials()
{
location where;
short k,sd1,sd2;
special_node_type sn;
if ((is_combat()) && (which_combat_type == 0))
return;
if ((is_town() == false) && (is_combat() == false))
return;
for (k = 0; k < 50; k++) {
//GK if (c_town.town.spec_id[k] >= 0)
{
sn = c_town.town.specials[c_town.town.spec_id[k]];
sd1 = sn.sd1; sd2 = sn.sd2;
if ((sd_legit(sd1,sd2) == true) && (PSD[sd1][sd2] == 250)) {
where = c_town.town.special_locs[k];
if ((where.x != 100) && ((where.x > town_size[town_type]) || (where.y > town_size[town_type])
|| (where.x < 0) || (where.y < 0))) {
MessageBeep(MB_OK);
add_string_to_buf("Town corrupt. Problem fixed.");
print_nums(where.x,where.y,k);
c_town.town.special_locs[k].x = 0;
}
if (where.x != 100) {
switch (scenario.ter_types[t_d.terrain[where.x][where.y]].picture) {
case 207: t_d.terrain[where.x][where.y] = 0; break;
case 208: t_d.terrain[where.x][where.y] = 170; break;
case 209: t_d.terrain[where.x][where.y] = 210; break;
case 210: t_d.terrain[where.x][where.y] = 217; break;
case 211: t_d.terrain[where.x][where.y] = 2; break;
case 212: t_d.terrain[where.x][where.y] = 36; break;
}
take_special(where.x,where.y);
}
}
}
}
}
void erase_out_specials()
{
short i,j,k,l,m;
special_node_type sn;
short sd1,sd2;
shortloc where;
for (k = 0; k < 2; k++)
{
for (l = 0; l < 2; l++)
{
if (quadrant_legal(k,l) == true)
{
for (m = 0; m < 8; m++)
{
if ((outdoors[k][l].exit_dests[m] >= 0) &&
(outdoors[k][l].exit_locs[m].x == minmax(0,47,(int)outdoors[k][l].exit_locs[m].x)) &&
(outdoors[k][l].exit_locs[m].y == minmax(0,47,(int)outdoors[k][l].exit_locs[m].y)))
{
if (party.can_find_town[outdoors[k][l].exit_dests[m]] == 0)
{
out[48 * k + outdoors[k][l].exit_locs[m].x][48 * l + outdoors[k][l].exit_locs[m].y] =
scenario.ter_types[outdoors[k][l].terrain[outdoors[k][l].exit_locs[m].x][outdoors[k][l].exit_locs[m].y]].flag1;
}
else if (party.can_find_town[outdoors[k][l].exit_dests[m]] > 0)
{
out[48 * k + outdoors[k][l].exit_locs[m].x][48 * l + outdoors[k][l].exit_locs[m].y] =
outdoors[k][l].terrain[outdoors[k][l].exit_locs[m].x][outdoors[k][l].exit_locs[m].y];
}
}
}
}
}
}
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
if (quadrant_legal(i,j) == true) {
for (k = 0; k < 18; k++)
//GK if (outdoors[i][j].special_id[k] >= 0)
{
sn = outdoors[i][j].specials[outdoors[i][j].special_id[k]];
sd1 = sn.sd1; sd2 = sn.sd2;
if ((sd_legit(sd1,sd2) == true) && (PSD[sd1][sd2] == 250)) {
where.x = outdoors[i][j].special_locs[k].x;
where.y = outdoors[i][j].special_locs[k].y;
if (where.x != 100) {
if ((where.x > 48) || (where.y > 48)
|| (where.x < 0) || (where.y < 0)) {
MessageBeep(MB_OK);
add_string_to_buf("Outdoor section corrupt. Problem fixed.");
//GK outdoors[i][j].special_id[k] = -1;
outdoors[i][j].special_id[k] = 0xFF;
}
switch (scenario.ter_types[outdoors[i][j].terrain[where.x][where.y]].picture) {
case 207: out[48 * i + where.x][48 * j + where.y] = 0; break;
case 208: out[48 * i + where.x][48 * j + where.y] = 170; break;
case 209: out[48 * i + where.x][48 * j + where.y] = 210; break;
case 210: out[48 * i + where.x][48 * j + where.y] = 217; break;
case 211: out[48 * i + where.x][48 * j + where.y] = 2; break;
case 212: out[48 * i + where.x][48 * j + where.y] = 36; break;
}
}
}
}
}
}
void clear_map()
{
RECT map_world_rect = {0,0,384,384};
HBITMAP old_bmp;
HDC hdc;
HBRUSH oldb;
HPEN oldp;
hdc = CreateCompatibleDC(main_dc);
old_bmp = (HBITMAP) SelectObject(hdc, map_gworld);
oldp = (HPEN) SelectObject(hdc,GetStockObject(BLACK_PEN));
oldb = (HBRUSH) SelectObject(hdc,GetStockObject(BLACK_BRUSH));
Rectangle(hdc, map_world_rect.left,map_world_rect.top,map_world_rect.right,map_world_rect.bottom);
SelectObject(hdc,oldp);
SelectObject(hdc,oldb);
SelectObject(hdc, old_bmp);
DeleteDC(hdc);
draw_map(modeless_dialogs[5],10);
}
void draw_map_rect (HWND the_dialog, short ul_x, short ul_y, short lr_x, short lr_y) //to clean
//ul = upper left
//lr = lower right
{
location map_adj;
location where;
location kludge;
RECT area_to_put_on_map_rect;
RECT draw_rect;
RECT custom_from;
RECT ter_temp_from,orig_draw_rect = {0,0,6,6};
RECT redraw_rect = {0,0,48,48}; // RECTangle visible in view screen
COLORREF map_colors[6] = {RGB(0,0,0),RGB(63,223,95),RGB(0,0,255),RGB(191,0,191),RGB(255,0,0),RGB(204,204,204)};
HDC hdc = NULL;
HBITMAP old_bmp;
HBRUSH old_brush;
HPEN old_pen;
short i,pic,pic2;
Boolean expl,expl2;
short small_adj = 0;
unsigned char what_ter,what_ter2;
Boolean out_mode;
// make map pens
if (hbrush[0] == NULL) {
for (i = 0; i < 6; i++) {
hbrush[i] = CreateSolidBrush(map_colors[i]);
hpen[i] = CreatePen(PS_SOLID,1,map_colors[i]);
}
}
hdc = CreateCompatibleDC(main_dc);
old_bmp = (HBITMAP) SelectObject(hdc, map_gworld);
old_brush = (HBRUSH) SelectObject(hdc,map_brush[0]);
old_pen = (HPEN) SelectObject(hdc,GetStockObject(NULL_PEN));
if (is_out()) { // for outside map, adjust for where in outdoors is being mapped
if (party.i_w_c.x == 1)
map_adj.x += 48;
if (party.i_w_c.y == 1)
map_adj.y += 48;
}
// Now, if shopping or talking, just don't touch anything.
if ((overall_mode == MODE_SHOPPING) || (overall_mode == MODE_TALKING))
redraw_rect.right = -1;
if ((is_out()) ||
((is_combat()) && (which_combat_type == 0)) ||
((overall_mode == MODE_TALKING) && (store_pre_talk_mode == MODE_OUTDOORS)) ||
((overall_mode == MODE_SHOPPING) && (store_pre_shop_mode == MODE_OUTDOORS)))
out_mode = true;
else out_mode = false;
area_to_put_on_map_rect = redraw_rect;
for (where.x= ul_x; where.x <= lr_x; where.x++)
for (where.y= ul_y; where.y <= lr_y; where.y++){
draw_rect = orig_draw_rect;
OffsetRect(&draw_rect,6 * where.x + small_adj, 6 * where.y + small_adj);
if (out_mode == true)
what_ter = out[where.x + 48 * party.i_w_c.x][where.y + 48 * party.i_w_c.y];
else what_ter = t_d.terrain[where.x][where.y];
ter_temp_from = orig_draw_rect;
if (out_mode == true)
expl = out_e[where.x + 48 * party.i_w_c.x][where.y + 48 * party.i_w_c.y];
else expl = is_explored(where.x,where.y);
if (expl != 0) {
map_graphic_placed[where.x / 8][where.y] =
map_graphic_placed[where.x / 8][where.y] | (unsigned char)(s_pow(2,where.x % 8));
pic = scenario.ter_types[what_ter].picture;
if (pic >= 1000) {
if (spec_scen_g != NULL) {
pic = pic % 1000;
custom_from = coord_to_rect(pic % 10, pic / 10);
OffsetRect(&custom_from,-13,-13);
SelectObject(hdc,old_bmp);
rect_draw_some_item(spec_scen_g,custom_from,map_gworld,draw_rect,0,0);
SelectObject(hdc,map_gworld);
}
}
else switch ((pic >= 400) ? anim_map_pats[pic - 400] : map_pats[pic]) {
case 0: case 10: case 11:
if (terrain_pic[what_ter] < 400)
OffsetRect(&ter_temp_from,
6 * (terrain_pic[what_ter] % 10) + 312,6 * (terrain_pic[what_ter] / 10));
else OffsetRect(&ter_temp_from,
24 * ((terrain_pic[what_ter] - 400) / 5) + 312,6 * ((terrain_pic[what_ter] - 400) % 5) + 163);
SelectObject(hdc,old_bmp);
rect_draw_some_item(mixed_gworld,ter_temp_from,
map_gworld,draw_rect,0,0);
SelectObject(hdc,map_gworld);
break;
default:
if (((pic >= 400) ? anim_map_pats[pic - 400] : map_pats[pic]) < 30) {
// Try a little optimization
if ((pic < 400) && (where.x < area_to_put_on_map_rect.right - 1)) {
if (out_mode == true)
what_ter2 = out[(where.x + 1)+ 48 * party.i_w_c.x][where.y + 48 * party.i_w_c.y];
else what_ter2 = t_d.terrain[where.x + 1][where.y];
if (out_mode == true)
expl2 = out_e[(where.x + 1) + 48 * party.i_w_c.x][where.y + 48 * party.i_w_c.y];
else expl2 = is_explored(where.x + 1,where.y);
pic2 = scenario.ter_types[what_ter2].picture;
if (pic2 < 400 && (map_pats[pic] == map_pats[pic2]) && (expl2 != 0)) {
draw_rect.right += 6;
map_graphic_placed[(where.x + 1)/ 8][where.y] =
map_graphic_placed[(where.x + 1)/ 8][where.y] | (unsigned char)(s_pow(2,(where.x + 1)% 8));
}
}
SelectObject(hdc,map_brush[((pic >= 400) ? anim_map_pats[pic - 400] : map_pats[pic]) - 1]);
Rectangle(hdc,draw_rect.left, draw_rect.top,draw_rect.right + 1,draw_rect.bottom + 1);
break;
}
/* OffsetRect(&ter_temp_from,
312 + 24 * ((map_pats[what_ter] - 30) / 5),
138 + 6 * ((map_pats[what_ter] - 30) % 5));
SelectObject(hdc,old_bmp);
rect_draw_some_item(mixed_gworld,ter_temp_from,
map_gworld,draw_rect,0,0);
SelectObject(hdc,map_gworld);*/
break;
}
}
}
SelectObject(hdc,old_brush);
SelectObject(hdc,old_pen);
SelectObject(hdc,old_bmp);
DeleteDC(hdc);
}
void draw_map (HWND the_dialog, short the_item)
//short the_item; // Being sneaky - if this gets value of 5, this is not a full restore -
// just update near party, if it gets 11, blank out middle and leave
// No redrawing in gworld
// If a 10, do a regular full restore
// Also, can get a 5 even when the window is not up, so have to make
// sure dialog exists before accessing it.
{
RECT map_world_rect = {0,0,321,321};
RECT whole_map_win_rect = {0,0,400,400};
location map_adj;
location where;
location kludge;
RECT area_to_draw_from,area_to_draw_on = {47,29,287,269};
RECT area_to_put_on_map_rect;
RECT draw_rect;
RECT custom_from;
RECT ter_temp_from,dlogpicrect = {6,6,42,42},orig_draw_rect = {0,0,6,6};
RECT view_rect= {0,0,48,48},tiny_rect = {0,0,32,32},
redraw_rect = {0,0,48,48},big_rect = {0,0,64,64}; // RECTangle visible in view screen
COLORREF map_colors[6] = {RGB(0,0,0),RGB(63,223,95),RGB(0,0,255),RGB(191,0,191),RGB(255,0,0),RGB(204,204,204)};
HDC hdc = NULL,hdc2;
HBITMAP old_bmp;
HBRUSH old_brush;
HPEN old_pen;
short i,j,pic,pic2;
Boolean draw_surroundings = false,expl,expl2;
Boolean draw_pcs = true;
short total_size = 48; // if full redraw, use this to figure out everything
short small_adj = 0;
unsigned char what_ter,what_ter2;
Boolean out_mode;
// UINT c;
if(c_town.town.defy_mapping == 1 ){//map not available
if (modeless_exists[5] == true){
// RECT text_rect = {30,265,230,275}; // legacy text position (lower left corner)
RECT text_rect = {0,0,300,290};
hdc2 = GetDC(the_dialog);
paint_pattern((HBITMAP) hdc2,2,map_world_rect,0);
SetBkMode(hdc2,TRANSPARENT);
SelectObject(hdc2,bold_font);
SetTextColor(hdc2,RGB(255,255,255));
char_win_draw_string(hdc2,text_rect,"This place defies mapping.",1,10);
GetClientRect(GetDlgItem(the_dialog,1),&draw_rect);
InvalidateRect(GetDlgItem(the_dialog,1),&draw_rect,false);
fry_dc(the_dialog,hdc2);
}
return;
}
if (the_item == 4) {
draw_surroundings = true;
the_item = 5;
}
if (kludge_force_full_refresh == true)
draw_surroundings = true;
if ((modeless_exists[5] == false) && (the_item == 5) && (need_map_full_refresh == true))
return;
if ((modeless_exists[5] == false) && (the_item == 10)) {
need_map_full_refresh = true;
return;
}
if ((modeless_exists[5] == true) && (the_item != 11) && (need_map_full_refresh == true)) {
need_map_full_refresh = false;
the_item = 10;
}
OffsetRect(&area_to_draw_on,0,-23);
if (the_item == 10) {
for (i = 0; i < 8; i++)
for (j = 0; j < 64; j++)
map_graphic_placed[i][j] = 0;
}
town_map_adj.x = 0;
town_map_adj.y = 0;
// view rect is rect that is visible, redraw rect is area to redraw now
// area_to_draw_from is final draw from rect
// area_to_draw_on is final draw to rect
if ((is_out()) || ((is_combat()) && (which_combat_type == 0)) ||
((overall_mode == MODE_TALKING) && (store_pre_talk_mode == MODE_OUTDOORS)) ||
((overall_mode == MODE_SHOPPING) && (store_pre_shop_mode == MODE_OUTDOORS))) {
view_rect.left = minmax(0,8,party.loc_in_sec.x - 20);
view_rect.right = view_rect.left + 40;
view_rect.top = minmax(0,8,party.loc_in_sec.y - 20);
view_rect.bottom = view_rect.top + 40;
redraw_rect = view_rect;
}
else {
switch (town_type) {
case 0:
view_rect.left = minmax(0,24,c_town.p_loc.x - 20);
view_rect.right = view_rect.left + 40;
view_rect.top = minmax(0,24,c_town.p_loc.y - 20);
view_rect.bottom = view_rect.top + 40;
if (the_item == 5)
redraw_rect = view_rect;
else redraw_rect = big_rect;
total_size = 64;
break;
case 1:
view_rect.left = minmax(0,8,c_town.p_loc.x - 20);
view_rect.right = view_rect.left + 40;
view_rect.top = minmax(0,8,c_town.p_loc.y - 20);
view_rect.bottom = view_rect.top + 40;
redraw_rect = view_rect;
break;
case 2:
view_rect = tiny_rect;
redraw_rect = view_rect;
total_size = 32;
break;
}
}
if ((is_out()) || ((is_combat()) && (which_combat_type == 0)) ||
((overall_mode == MODE_TALKING) && (store_pre_talk_mode == MODE_OUTDOORS)) ||
((overall_mode == MODE_SHOPPING) && (store_pre_shop_mode == MODE_OUTDOORS)) ||
(((is_town()) || (is_combat())) && (town_type != 2))) {
area_to_draw_from = view_rect;
area_to_draw_from.left *= 6;
area_to_draw_from.right *= 6;
area_to_draw_from.top *= 6;
area_to_draw_from.bottom *= 6;
}
else {
area_to_draw_from = area_to_draw_on;
OffsetRect(&area_to_draw_from,-1 * area_to_draw_from.left,-1 * area_to_draw_from.top);
small_adj = 0;
}
if (is_combat())
draw_pcs = false;
// make map pens
if (hbrush[0] == NULL) {
for (i = 0; i < 6; i++) {
hbrush[i] = CreateSolidBrush(map_colors[i]);
hpen[i] = CreatePen(PS_SOLID,1,map_colors[i]);
}
}
hdc = CreateCompatibleDC(main_dc);
old_bmp = (HBITMAP) SelectObject(hdc, map_gworld);
old_brush = (HBRUSH) SelectObject(hdc,map_brush[0]);
old_pen = (HPEN) SelectObject(hdc,GetStockObject(NULL_PEN));
if (the_item == 11) {
SelectObject(hdc,GetStockObject(WHITE_BRUSH));
Rectangle(hdc, map_world_rect.left,map_world_rect.top,map_world_rect.right,map_world_rect.bottom);
draw_pcs = false;
}
else {
if (modeless_exists[5] == true) {
SetDlgItemText(the_dialog,3,"");
}
if (is_out()) { // for outside map, adjust for where in outdoors is being mapped
if (party.i_w_c.x == 1)
map_adj.x += 48;
if (party.i_w_c.y == 1)
map_adj.y += 48;
}
// Now, if doing just partial restore, crop redraw_rect to save time.
if (the_item == 5) {
if ((is_out()) || ((is_combat()) && (which_combat_type == 0)) ||
((overall_mode == MODE_TALKING) && (store_pre_talk_mode == MODE_OUTDOORS)) ||
((overall_mode == MODE_SHOPPING) && (store_pre_shop_mode == MODE_OUTDOORS)))
kludge = party.p_loc.toLocal();
else if (is_combat())
kludge = pc_pos[current_pc];
else kludge = c_town.p_loc;
redraw_rect.left = max(0,kludge.x - 4);
redraw_rect.right = min(view_rect.right,kludge.x + 5);
redraw_rect.top = max(0,kludge.y - 4);
redraw_rect.bottom = min(view_rect.bottom,kludge.y + 5);
}
// Now, if shopping or talking, just don't touch anything.
if ((overall_mode == MODE_SHOPPING) || (overall_mode == MODE_TALKING))
redraw_rect.right = -1;
if ((is_out()) ||
((is_combat()) && (which_combat_type == 0)) ||
((overall_mode == MODE_TALKING) && (store_pre_talk_mode == MODE_OUTDOORS)) ||
((overall_mode == MODE_SHOPPING) && (store_pre_shop_mode == MODE_OUTDOORS)))
out_mode = true;
else out_mode = false;
area_to_put_on_map_rect = redraw_rect;
if (the_item == 10) {
area_to_put_on_map_rect.top = area_to_put_on_map_rect.left = 0;
area_to_put_on_map_rect.right = area_to_put_on_map_rect.bottom = total_size;
}
for (where.x= area_to_put_on_map_rect.left; where.x < area_to_put_on_map_rect.right; where.x++)
for (where.y= area_to_put_on_map_rect.top; where.y < area_to_put_on_map_rect.bottom; where.y++)
if ((map_graphic_placed[where.x / 8][where.y] & (unsigned char)(s_pow(2,where.x % 8))) == 0)
{
draw_rect = orig_draw_rect;
OffsetRect(&draw_rect,6 * where.x + small_adj, 6 * where.y + small_adj);
if (out_mode == true)
what_ter = out[where.x + 48 * party.i_w_c.x][where.y + 48 * party.i_w_c.y];
else what_ter = t_d.terrain[where.x][where.y];
ter_temp_from = orig_draw_rect;
if (out_mode == true)
expl = out_e[where.x + 48 * party.i_w_c.x][where.y + 48 * party.i_w_c.y];
else expl = is_explored(where.x,where.y);
if (expl != 0) {
map_graphic_placed[where.x / 8][where.y] =
map_graphic_placed[where.x / 8][where.y] | (unsigned char)(s_pow(2,where.x % 8));
pic = scenario.ter_types[what_ter].picture;
if (pic >= 1000) {
if (spec_scen_g != NULL) {
pic = pic % 1000;
custom_from = coord_to_rect(pic % 10, pic / 10);
OffsetRect(&custom_from,-13,-13);
SelectObject(hdc,old_bmp);
rect_draw_some_item(spec_scen_g,custom_from,map_gworld,draw_rect,0,0);
SelectObject(hdc,map_gworld);
}
}
else switch ((pic >= 400) ? anim_map_pats[pic - 400] : map_pats[pic]) {
case 0: case 10: case 11:
if (terrain_pic[what_ter] < 400)
OffsetRect(&ter_temp_from,
6 * (terrain_pic[what_ter] % 10) + 312,6 * (terrain_pic[what_ter] / 10));
else OffsetRect(&ter_temp_from,
24 * ((terrain_pic[what_ter] - 400) / 5) + 312,6 * ((terrain_pic[what_ter] - 400) % 5) + 163);
SelectObject(hdc,old_bmp);
rect_draw_some_item(mixed_gworld,ter_temp_from,
map_gworld,draw_rect,0,0);
SelectObject(hdc,map_gworld);
break;
default:
// if (((pic >= 400) ? anim_map_pats[pic - 400] : map_pats[pic]) < 30) {//always true ?!?
if ((pic < 400) && (where.x < area_to_put_on_map_rect.right - 1)) {// Try a little optimization
if (out_mode == true)
what_ter2 = out[(where.x + 1)+ 48 * party.i_w_c.x][where.y + 48 * party.i_w_c.y];
else what_ter2 = t_d.terrain[where.x + 1][where.y];
if (out_mode == true)
expl2 = out_e[(where.x + 1) + 48 * party.i_w_c.x][where.y + 48 * party.i_w_c.y];
else expl2 = is_explored(where.x + 1,where.y);
pic2 = scenario.ter_types[what_ter2].picture;
if (pic2 < 400 && (map_pats[pic] == map_pats[pic2]) && (expl2 != 0)) {
draw_rect.right += 6;
map_graphic_placed[(where.x + 1)/ 8][where.y] =
map_graphic_placed[(where.x + 1)/ 8][where.y] | (unsigned char)(s_pow(2,(where.x + 1)% 8));
}
}
SelectObject(hdc,map_brush[((pic >= 400) ? anim_map_pats[pic - 400] : map_pats[pic]) - 1]);
Rectangle(hdc,draw_rect.left, draw_rect.top,draw_rect.right + 1,draw_rect.bottom + 1);
break;
// }
/* OffsetRect(&ter_temp_from,
312 + 24 * ((map_pats[what_ter] - 30) / 5),
138 + 6 * ((map_pats[what_ter] - 30) % 5));//138 ??? <= nevermind cause never called ...
SelectObject(hdc,old_bmp);
rect_draw_some_item(mixed_gworld,ter_temp_from,
map_gworld,draw_rect,0,0);
SelectObject(hdc,map_gworld);*/
break;
}
}
}
}
SelectObject(hdc,old_brush);
SelectObject(hdc,old_pen);
SelectObject(hdc,old_bmp);
DeleteDC(hdc);
// Now place terrain map gworld
if (modeless_exists[5] == true) {
// graphics goes here
hdc2 = GetDC(the_dialog);
if ((draw_surroundings == true) || (the_item != 5)) { // redraw much stuff
paint_pattern((HBITMAP) hdc2,2,whole_map_win_rect,0);
SetBkMode(hdc2,TRANSPARENT);
SelectObject(hdc2,small_bold_font);
GetClientRect(GetDlgItem(the_dialog,1),&draw_rect);
InvalidateRect(GetDlgItem(the_dialog,1),&draw_rect,false);
}
rect_draw_some_item(map_gworld,area_to_draw_from,(HBITMAP) hdc2,area_to_draw_on,0,2);
}
// Now place PCs and monsters
if ((draw_pcs == true) && (modeless_exists[5] == true)) {
if ((is_town()) && (party.stuff_done[SDF_DETECT_MONSTER] > 0))
for (i = 0; i < T_M; i++)
if (c_town.monst.dudes[i].active > 0) {
where = c_town.monst.dudes[i].m_loc;
if ((is_explored(where.x,where.y)) &&
((where.x >= view_rect.left) && (where.x <= view_rect.right)
&& (where.y >= view_rect.top) && (where.x <= view_rect.bottom))){
draw_rect.left = area_to_draw_on.left + 6 * (where.x - view_rect.left);
draw_rect.top = area_to_draw_on.top + 6 * (where.y - view_rect.top);
draw_rect.right = draw_rect.left + 6;
draw_rect.bottom = draw_rect.top + 6;
map_graphic_placed[where.x / 8][where.y] =
map_graphic_placed[where.x / 8][where.y] & ~((unsigned char)(s_pow(2,where.x % 8)));
SelectObject(hdc2,hpen[0]);
SelectObject(hdc2,hbrush[0]);
Rectangle(hdc2, draw_rect.left,draw_rect.top,draw_rect.right,draw_rect.bottom);
SelectObject(hdc2,hpen[4]);
SelectObject(hdc2,hbrush[5]);
Ellipse(hdc2, draw_rect.left,draw_rect.top,draw_rect.right,draw_rect.bottom);
}
}
if ((overall_mode != MODE_SHOPPING) && (overall_mode != MODE_TALKING)) {
where = (is_town()) ? c_town.p_loc : party.p_loc.toLocal();
draw_rect.left = area_to_draw_on.left + 6 * (where.x - view_rect.left);
draw_rect.top = area_to_draw_on.top + 6 * (where.y - view_rect.top);
draw_rect.right = draw_rect.left + 6;
draw_rect.bottom = draw_rect.top + 6;
if ((where.x >= 0) && (where.x < 64) &&
(where.y >= 0) && (where.y < 64)) {
map_graphic_placed[where.x / 8][where.y] = /* Crash! vvv */
map_graphic_placed[where.x / 8][where.y] & ~((unsigned char)(s_pow(2,where.x % 8)));
SelectObject(hdc2,hpen[0]);
SelectObject(hdc2,hbrush[0]);
Rectangle(hdc2, draw_rect.left,draw_rect.top,draw_rect.right,draw_rect.bottom);
SelectObject(hdc2,hpen[3]);
SelectObject(hdc2,hbrush[3]);
Ellipse(hdc2, draw_rect.left,draw_rect.top,draw_rect.right,draw_rect.bottom);
}
}
}
// Now exit gracefully
if (modeless_exists[5] == true) {
// graphics goes here
fry_dc(the_dialog,hdc2);
if ((draw_surroundings == true) || (the_item != 5)) { // redraw much stuff
draw_dialog_graphic(the_dialog, dlogpicrect,
721, false,0); // draw the icon map graphic
}
}
}
BOOL CALLBACK map_dialog_proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM)
{
switch (message) {
case WM_INITDIALOG:
if (store_map_window_rect.right > 0)
MoveWindow(hDlg,store_map_window_rect.left,store_map_window_rect.top,
store_map_window_rect.right - store_map_window_rect.left,
store_map_window_rect.bottom - store_map_window_rect.top,false);
else {
GetWindowRect(hDlg,&store_map_window_rect);
MoveWindow(hDlg,294 + ulx, 47 + uly,
store_map_window_rect.right - store_map_window_rect.left,
store_map_window_rect.bottom - store_map_window_rect.top,false);
}
kludge_force_full_refresh = true;
draw_map(hDlg,10);
kludge_force_full_refresh = false;
SetFocus(mainPtr);
break;
case WM_ERASEBKGND:
return 1;
case WM_PAINT:
kludge_force_full_refresh = true;
draw_map(hDlg,5);
kludge_force_full_refresh = false;
return false;
case WM_KEYDOWN:
if (wParam != VK_RETURN)
return 0;
case WM_COMMAND:
modeless_exists[5] = false;
GetWindowRect(hDlg,&store_map_window_rect);
DestroyWindow(hDlg);
return true;
case WM_DESTROY:
modeless_exists[5] = false;
return 0;
}
return false;
}
void display_map()
{
if ( modeless_exists[5] == true)
return;
modeless_exists[5] = true;
modeless_dialogs[5] = CreateDialog(store_hInstance,
MAKEINTRESOURCE(1046),mainPtr,(DLGPROC) map_dialog_proc);
}
Boolean quadrant_legal(short i, short j)
{
if (party.outdoor_corner.x + i >= scenario.out_width) return false;
if (party.outdoor_corner.y + j >= scenario.out_height) return false;
if (party.outdoor_corner.x + i < 0) return false;
if (party.outdoor_corner.y + j < 0) return false;
return true;
}