/*
* Seven Kingdoms: Ancient Adversaries
*
* Copyright 1997,1998 Enlight Software Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
//Filename : OWORLD.H
//Description : Header file of Object World
#ifndef __OWORLD_H
#define __OWORLD_H
#ifndef __OWORLDMT_H
#include
#endif
#ifndef __ALL_H
#include
#endif
#ifndef __OUNITRES_H
#include
#endif
//----------- Define constant ------------//
#define EXPLORE_RANGE 10
#define SCAN_FIRE_DIST 4
//--------------- Define constant -----------------//
#define MIN_LAND_COST 500000 // Minimum land cost even there is no population at all
//------- define terrain map --------//
#define MIN_GRASS_HEIGHT 100
#define MIN_HILL_HEIGHT 230
#define MIN_MOUNTAIN_HEIGHT 242
#define MIN_ICE_HEIGHT 252
//---------------- Define class World -------------//
class Weather;
class Plasma;
class World
{
public:
MapMatrix *map_matrix;
ZoomMatrix *zoom_matrix;
Location *loc_matrix;
DWORD next_scroll_time; // next scroll time
char scan_fire_x; // cycle from 0 to SCAN_FIRE_DIST-1
char scan_fire_y;
char lightning_signal;
int plant_count;
int plant_limit;
//--------- static member vars --------------//
static short view_top_x, view_top_y; // the view window in the scene, they are relative coordinations on the entire virtual surface.
static int max_x_loc , max_y_loc; // these must be static vars as MAX_WORLD_X_LOC & MAX_WORLD_Y_LOC are defined to use them.
public:
World();
~World();
void init();
void deinit();
void generate_map();
void assign_map();
void paint();
void refresh();
void disp_zoom() { zoom_matrix->disp(); }
void load_map(char*);
int detect();
// ###### begin Gilbert 16/9 ########//
int detect_firm_town();
// ###### end Gilbert 16/9 ########//
void go_loc(int xLoc, int yLoc, int selectedFlag=0);
void disp_next(int seekDir, int sameNation);
int write_file(File*);
int read_file(File*);
public:
#ifdef DEBUG3
Location* get_loc(int xLoc,int yLoc);
BYTE get_region_id(int xLoc,int yLoc);
#else
Location* get_loc(int xLoc,int yLoc)
{ return loc_matrix + MAX_WORLD_X_LOC * yLoc + xLoc; }
BYTE get_region_id(int xLoc,int yLoc)
{ return loc_matrix[MAX_WORLD_X_LOC*yLoc+xLoc].region_id; }
#endif
short get_unit_recno(int xLoc,int yLoc, int mobileType);
void set_unit_recno(int xLoc, int yLoc, int mobileType, int newCargoRecno);
int distance_rating(int xLoc1, int yLoc1, int xLoc2, int yLoc2);
void unveil(int xLoc1, int yLoc1, int xLoc2, int yLoc2);
void explore(int xLoc1, int yLoc1, int xLoc2, int yLoc2);
int is_explored(int xLoc1, int yLoc1, int xLoc2, int yLoc2);
// always call unveil before visit //
void visit(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int range, int extend =0);
void visit_shell(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int visitLevel);
int can_build_firm(int xLoc1, int yLoc1, int firmId, short unitRecno= -1);
int can_build_town(int xLoc1, int yLoc1, short unitRecno= -1);
int can_build_wall(int xLoc1, int yLoc1, short nationRecno);
int can_destruct_wall(int xLoc1, int yLoc1, short nationRecno);
void build_wall_tile(int xLoc1, int yLoc1, short nationRecno, char remoteAction);
void destruct_wall_tile(int xLoc1, int yLoc1, short nationRecno, char remoteAction);
int locate_space(int& xLoc1, int& yLoc1, int xLoc2, int yLoc2,
int spaceLocWidth, int spaceLocHeight, int mobileType=UNIT_LAND, int regionId=0, int buildFlag=0);
int check_unit_space(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int mobileType=UNIT_LAND, int buildFlag=0);
int locate_space_random(int& xLoc1, int& yLoc1, int xLoc2, int yLoc2,
int spaceLocWidth, int spaceLocHeight, int maxTries,
int regionId=0, int buildSite=0, char teraMask=1);
int is_adjacent_region( int x, int y, int regionId );
void draw_link_line(int srcFirmId, int srcTownRecno, int srcXLoc1, int srcYLoc1, int srcXLoc2, int srcYLoc2, int giveEffectiveDis=0);
void set_all_power();
void set_power(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int nationRecno);
void restore_power(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int townRecno, int firmRecno);
void set_surr_power_off(int xLoc, int yLoc);
void process();
void process_visibility();
void next_day();
//------- functions related to plant's growth, see ow_plant.cpp -----//
void plant_ops();
void plant_grow(int pGrow =4, int scanDensity =8);
void plant_reprod(int pRepord =1, int scanDensity =8);
void plant_death(int scanDensity =8);
void plant_spread(int pSpread =5);
void plant_init();
void plant_spray(short *plantIdArray, char strength, short x, short y);
//------- functions related to fire's spreading, see ow_fire.cpp ----//
void init_fire();
void spread_fire(Weather &);
void setup_fire(short x, short y, char fireStrength = 30);
//------- function related to city wall ----------//
void build_wall_section(short x1, short y1, short x2, short y2,
short townRecno, short initHp = 99);
void build_wall(int townRecno, short initHp = 99);
void open_west_gate(short x2, short y1, short townRecno);
void open_east_gate(short x1, short y1, short townRecno);
void open_north_gate(short x1, short y2, short townRecno);
void open_south_gate(short x1, short y1, short townRecno);
int form_wall(short x, short y, short maxRecur=0);
void form_world_wall();
int correct_wall(short x, short y, short maxRecur=2);
//-------- function related to rock ----------//
void add_rock(short rockRecno, short x1, short y1);
void add_dirt(short dirtRecno, short x1, short y1);
// ###### begin Gilbert 22/9 ######//
int can_add_rock(short x1, short y1, short x2, short y2);
int can_add_dirt(short x1, short y1, short x2, short y2);
// ###### end Gilbert 22/9 ######//
// ------ function related to weather ---------//
void earth_quake();
void lightning_strike(short x, short y, short radius=0);
private:
int detect_scroll();
// int detect_firm_town();
//--------- ambient sound functions --------//
void process_ambient_sound();
//--- called by generate_map() only ---//
void add_base_level();
void gen_plasma_map();
void set_tera_id(Plasma &);
void remove_odd(Plasma &, short x, short y, short recur);
void set_climate();
void set_loc_flags();
void substitute_pattern();
void set_region_id();
void fill_region(short x, short y);
// ####### begin Gilbert 22/9 ########//
void gen_rocks(int nGrouped, int nLarge, int nSmall);
void gen_dirt(int nGrouped, int nLarge, int nSmall);
// ####### end Gilbert 22/9 ########//
void set_harbor_bit();
// private function called by build_wall_section
int can_build_area(short x1, short y1, short x2, short y2);
void build_west_gate(short x1, short y1, short townRec, short initHp);
void build_east_gate(short x1, short y1, short townRec, short initHp);
void build_north_gate(short x1, short y1, short townRec, short initHp);
void build_south_gate(short x1, short y1, short townRec, short initHp);
void build_west_wall(short x1, short y1, short y2, short townRec, short initHp);
void build_east_wall(short x1, short y1, short y2, short townRec, short initHp);
void build_north_wall(short x1, short x2, short y1, short townRec, short initHp);
void build_south_wall(short x1, short x2, short y1, short townRec, short initHp);
// see OGENHILL.CPP
void gen_hills(int terrainType);
void put_hill_set(short *px, short *py, short hSetId);
void put_hill_pattern(short *px, short *py, unsigned char patternId);
void fill_hill(short x, short y);
};
//-------- Begin of function World::get_unit_recno -------//
inline short World::get_unit_recno(int xLoc, int yLoc, int mobileType)
{
if( mobileType==UNIT_AIR )
return loc_matrix[MAX_WORLD_X_LOC*yLoc+xLoc].air_cargo_recno;
else
return loc_matrix[MAX_WORLD_X_LOC*yLoc+xLoc].cargo_recno;
}
//--------- End of function World::get_unit_recno -------//
//-------- Begin of function World::set_unit_recno -------//
inline void World::set_unit_recno(int xLoc,int yLoc, int mobileType, int newCargoRecno)
{
if( mobileType==UNIT_AIR )
loc_matrix[MAX_WORLD_X_LOC*yLoc+xLoc].air_cargo_recno = newCargoRecno;
else
loc_matrix[MAX_WORLD_X_LOC*yLoc+xLoc].cargo_recno = newCargoRecno;
err_when(mobileType!=UNIT_AIR && loc_matrix[MAX_WORLD_X_LOC*yLoc+xLoc].is_firm());
}
//--------- End of function World::set_unit_recno -------//
//--------- Begin of function World::distance_rating --------//
//
inline int World::distance_rating(int xLoc1, int yLoc1, int xLoc2, int yLoc2)
{
int curDistance = m.points_distance(xLoc1, yLoc1, xLoc2, yLoc2);
return 100 - 100 * curDistance / MAX_WORLD_X_LOC;
}
//----------- End of function World::distance_rating --------//
extern World world;
#endif