// Battle for Allen Creek
// terrain.js
// copyright (c) 2009 Mark Butler
// 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.
function Terrain() {
var maxTerrainX;
var maxTerrainY;
var terrainArray;
var towns;
var terrainTypes;
var reinforceZones;
var allAreAttackingAcrossRiverCombatEffect;
this.towns = new Array();
this.terrainTypes = new Array();
this.reinforceZones = new Array();
this.allAreAttackingAcrossRiverCombatEffect = 3;
// -------------- data -----------------------
this.addTown( "Marysville", 403 );
// code, name, displayName, entranceCost, useMaxMove, combatEffect, isRoadType
this.addTerrainType(0, "offmap", "", 1, false, 0, false);
this.addTerrainType(1, "clear", "", 2, false, 0, false);
this.addTerrainType(2, "rough", "rough", 3, false, 1, false);
this.addTerrainType(4, "road", "road", 1, false, 0, true);
this.addTerrainType(8, "town", "town", 0, false, 2, false);
this.addTerrainType(16, "forest", "forest", 4, false, 2, false);
this.addTerrainType(32, "river", "river", 0, true, 0, false);
this.addReinforceZone(501, "R");
this.addReinforceZone(103, "B");
this.addReinforceZone(104, "B");
this.addReinforceZone(105, "B");
// -------------- data -----------------------
this.terrainArray = new Array (
new Array ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
new Array ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
new Array ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
new Array ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
new Array ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
new Array ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
new Array ( 0, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0 ),
new Array ( 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 ),
new Array ( 0, 0, 0, 0, 1, 0, 1, 0, 5, 0, 5, 0, 1, 0, 0, 0 ),
new Array ( 0, 0, 0, 1, 0, 1, 0, 1, 0, 33, 0, 1, 0, 1, 0, 0 ),
new Array ( 0, 0, 0, 0, 1, 0, 17, 0, 5, 0, 5, 0, 1, 0, 0, 0 ),
new Array ( 0, 0, 0, 1, 0, 17, 0, 1, 0, 33, 0, 1, 0, 1, 0, 0 ),
new Array ( 0, 0, 0, 0, 17, 0, 17, 0, 5, 0, 6, 0, 2, 0, 0, 0 ),
new Array ( 0, 0, 0, 1, 0, 17, 0, 1, 0, 33, 0, 2, 0, 1, 0, 0 ),
new Array ( 0, 0, 0, 0, 17, 0, 17, 0, 5, 0, 6, 0, 2, 0, 0, 0 ),
new Array ( 0, 0, 0, 1, 0, 17, 0, 1, 0, 33, 0, 6, 0, 1, 0, 0 ),
new Array ( 0, 0, 0, 0, 17, 0, 17, 0, 5, 0, 1, 0, 6, 0, 0, 0 ),
new Array ( 0, 0, 0, 1, 0, 17, 0, 1, 0, 38, 0, 1, 0, 1, 0, 0 ),
new Array ( 0, 0, 0, 0, 17, 0, 21, 0, 1, 0, 13, 0, 5, 0, 0, 0 ),
new Array ( 0, 0, 0, 1, 0, 17, 0, 5, 0, 38, 0, 1, 0, 1, 0, 0 ),
new Array ( 0, 0, 0, 0, 17, 0, 21, 0, 5, 0, 38, 0, 5, 0, 0, 0 ),
new Array ( 0, 0, 0, 1, 0, 17, 0, 1, 0, 1, 0, 33, 0, 1, 0, 0 ),
new Array ( 0, 0, 0, 0, 1, 0, 21, 0, 1, 0, 13, 0, 5, 0, 0, 0 ),
new Array ( 0, 0, 0, 5, 0, 5, 0, 1, 0, 1, 0, 33, 0, 1, 0, 0 ),
new Array ( 0, 0, 0, 0, 5, 0, 1, 0, 1, 0, 5, 0, 5, 0, 0, 0 ),
new Array ( 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 0 ),
new Array ( 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ),
new Array ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
new Array ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 )
);
this.maxTerrainX = this.terrainArray[0].length;
this.maxTerrainY = this.terrainArray.length;
//alert( this.maxTerrainX + ", " + this.maxTerrainY );
}
function Town ( _name, _x, _y ) {
var name, x, y;
this.name = _name;
this.x = _x;
this.y = _y;
}
function TerrainAddTown( name, hexagonNumber)
{
var hexagon = new Hexagon(hexagonNumber);
var town = new Town(name, hexagon.getHexagonX(), hexagon.getHexagonY());
this.towns.push(town);
}
function TerrainGetTownName( x, y ) {
var townName = "";
for ( var i = 0; i < this.towns.length; i++ ) {
if ( this.towns[i].x == x && this.towns[i].y == y ) {
townName += this.towns[i].name;
}
}
return townName;
}
function TerrainType(_code, _name, _displayName, _entranceCost, _useMaxMove, _combatEffect, _isRoadType) {
var code;
var name;
var name;
var displayName;
var entranceCost;
var useMaxMove;
var combatEffect;
var isRoadType;
this.code = _code;
this.name = _name;
this.displayName = _displayName;
this.entranceCost = _entranceCost;
this.useMaxMove = _useMaxMove;
this.combatEffect = _combatEffect;
this.isRoadType = _isRoadType;
}
function TerrainAddTerrainType(code, name, displayName, entranceCost, useMaxMove, combatEffect, isRoadType) {
var terrainType = new TerrainType(code, name, displayName, entranceCost, useMaxMove, combatEffect, isRoadType);
this.terrainTypes.push(terrainType);
}
function ReinforceZone( _hexagonX, _hexagonY, _zoneName)
{
var hexagonX;
var hexagonY;
var zoneName;
this.hexagonX = _hexagonX;
this.hexagonY = _hexagonY;
this.zoneName = _zoneName;
}
function TerrainAddReinforceZone( _hexagon, _zoneName )
{
var hexagon = new Hexagon(_hexagon);
var reinforceZone = new ReinforceZone(hexagon.getHexagonX(), hexagon.getHexagonY(), _zoneName);
this.reinforceZones.push(reinforceZone);
}
function TerrainGetTerrainCode( x, y ) {
var terrainCode;
if ( ( x >= 0 && x < this.maxTerrainX ) && ( y >= 0 && y < this.maxTerrainY ) )
terrainCode = this.terrainArray[y][x];
else
terrainCode = -1;
return terrainCode;
}
function TerrainGetTerrainName( x, y ) {
var code = this.getTerrainCode( x, y );
var terrainName = "";
if ( ( x >= 0 && x < this.maxTerrainX ) && ( y >= 0 && y < this.maxTerrainY ) ) {
for( var i = 1; i < this.terrainTypes.length; i++ ) {
if( (this.terrainTypes[i].code & code) == this.terrainTypes[i].code ) {
terrainName += this.terrainTypes[i].displayName;
terrainName += " ";
}
}
}
return terrainName;
}
function TerrainTerrainIs( hexpartX, hexpartY, name)
{
var code = this.getTerrainCode(hexpartX, hexpartY);
var terrainCode = 0;
var found = false;
for (var i = 1; i < this.terrainTypes.length; i++ )
{
if (this.terrainTypes[i].name == name)
{
terrainCode = this.terrainTypes[i].code;
}
}
if (terrainCode != 0)
{
for ( i = 1; i < this.terrainTypes.length; i++ )
{
if ((terrainCode & code) == terrainCode)
{
found = true;
}
}
}
return found;
}
function TerrainMoveIsRoad( startX, startY, endX, endY)
{
var moveIsRoad = false;
var hexsideX = ( startX + endX ) / 2;
var hexsideY = ( startY + endY ) / 2;
if( ( this.terrainIs(startX, startY, "road") == true )
&& ( this.terrainIs(hexsideX, hexsideY, "road") == true )
&& ( this.terrainIs(startY, startY, "road") == true ) )
{
moveIsRoad = true;
}
return moveIsRoad;
}
function TerrainGetTerrainArray( ) {
var array;
array = "this.terrainArray = new Array (";
for( var y = 0; y <= this.maxTerrainY; y++ ) {
array += "
new Array ( ";
for( var x = 0; x <= this.maxTerrainX; x++ ) {
array += " " + this.getTerrainCode( x, y);
if( x < this.maxTerrainX) array += ", ";
}
array += " )";
if( y < this.maxTerrainY) array += ",";
}
array += "
);";
return array;
}
function TerrainGetBlankTerrainArray( maxHexagonX, maxHexagonY ) {
var maxX = maxHexagonX + 3;
var maxY = maxHexagonY + 4;
var array;
array = "this.terrainArray = new Array (";
for( var y = 0; y <= maxY ; y++ ) {
array += "
new Array ( ";
for( var x = 0; x <= maxX; x++ ) {
if ( x >= 4 && x <= maxHexagonX && y >= 8 && y <= maxHexagonY )
{
array += " 1";
}
else
{
array += " 0";
}
if( x < maxX) array += ", ";
}
array += " )";
if( y < maxY ) array += ",";
}
array += "
);";
return array;
}
function TerrainSetTerrain( letter, x, y ) {
//alert( letter + " : " + x + ", " + y );
var code = this.terrainArray[y][x];
switch ( letter ) {
case "h":
if ( ( (code & 2) == 2 )) {
this.terrainArray[y][x] = this.terrainArray[y][x] - 2;
this.terrainArray[y][x] = this.terrainArray[y][x] + 1;
}
else {
this.terrainArray[y][x] = this.terrainArray[y][x] - 1;
this.terrainArray[y][x] = this.terrainArray[y][x] + 2;
}
break;
case "r":
if ( ( (code & 4) == 4 )) {
this.terrainArray[y][x] = this.terrainArray[y][x] - 4;
}
else {
this.terrainArray[y][x] = this.terrainArray[y][x] + 4;
}
break;
case "t":
if ( ( (code & 8) == 8 )) {
this.terrainArray[y][x] = this.terrainArray[y][x] - 8;
}
else {
this.terrainArray[y][x] = this.terrainArray[y][x] + 8;
}
break;
case "f":
if ( ( (code & 16) == 16 )) {
this.terrainArray[y][x] = this.terrainArray[y][x] - 16;
}
else {
this.terrainArray[y][x] = this.terrainArray[y][x] + 16;
}
break;
case "v":
if ( ( (code & 32) == 32 )) {
this.terrainArray[y][x] = this.terrainArray[y][x] - 32;
}
else {
this.terrainArray[y][x] = this.terrainArray[y][x] + 32;
}
break;
}
}
function TerrainGetTerrainEntranceMoveCost(endX, endY, name ) {
var entranceMoveCost = 0;
var terrainType;
for ( var i = 1; i < this.terrainTypes.length; i++ )
{
terrainType = this.terrainTypes[i];
if ((this.terrainIs(endX, endY, terrainType.name) == true)
&& (terrainType.isRoadType == false))
{
if (terrainType.entranceCost > entranceMoveCost)
{
entranceMoveCost = terrainType.entranceCost;
}
}
}
return entranceMoveCost;
}
function TerrainGetTerrainMoveCost(startX, startY, endX, endY, maxMoveAmount ) {
var moveCost = 0;
var hexsideX = ( startX + endX ) / 2;
var hexsideY = ( startY + endY ) / 2;
if (this.isExit(startX, startY) == false && this.isExit(endX, endY) == false) {
// if road, override terrain
if (this.moveIsRoad(startX, startY, endX, endY) == true) {
moveCost = 1;
}
else {
// get entrance cost
moveCost = this.getTerrainEntranceMoveCost(endX, endY);
// check hexside for river
if( this.terrainIs(hexsideX, hexsideY, "river") == true ) {
moveCost = maxMoveAmount
}
}
}
return moveCost;
}
function TerrainGetTerrainRoadMoveCost()
{
return 1;
}
function TerrainGetDefenderTerrainCombatEffect(hexagonX, hexagonY)
{
var combatEffect;
combatEffect = 0;
for ( var i = 1; i < this.terrainTypes.length; i++ )
{
if ( this.terrainTypes[i].combatEffect > combatEffect)
{
combatEffect = this.terrainTypes[i].combatEffect;
}
}
return combatEffect;
}
function TerrainGetAllAreAttackingAcrossRiverCombatEffect()
{
return this.allAreAttackingAcrossRiverCombatEffect;
}
function TerrainIsExit( x, y ) {
var isExit = false;
var terrainCode;
terrainCode = this.getTerrainCode( x, y );
if ( terrainCode == 0 ) {
isExit = true;
}
return isExit;
}
function TerrainGetReinforceZone( x, y )
{
var zoneName = "";
var hexagon = new Hexagon(x, y);
for( var i = 0; i < this.reinforceZones.length; i++ )
{
if ( this.reinforceZones[i].hexagonX == hexagon.getHexagonX()
&& this.reinforceZones[i].hexagonY == hexagon.getHexagonY() )
{
zoneName = this.reinforceZones[i].zoneName;
}
}
return zoneName;
}
Terrain.prototype.addTown = TerrainAddTown;
Terrain.prototype.getTownName = TerrainGetTownName;
Terrain.prototype.addTerrainType = TerrainAddTerrainType;
Terrain.prototype.addReinforceZone = TerrainAddReinforceZone;
Terrain.prototype.getTerrainCode = TerrainGetTerrainCode;
Terrain.prototype.getTerrainName = TerrainGetTerrainName;
Terrain.prototype.terrainIs = TerrainTerrainIs;
Terrain.prototype.moveIsRoad = TerrainMoveIsRoad;
Terrain.prototype.getTerrainArray = TerrainGetTerrainArray;
Terrain.prototype.getBlankTerrainArray = TerrainGetBlankTerrainArray;
Terrain.prototype.setTerrain= TerrainSetTerrain;
Terrain.prototype.getTerrainEntranceMoveCost = TerrainGetTerrainEntranceMoveCost;
Terrain.prototype.getTerrainMoveCost = TerrainGetTerrainMoveCost;
Terrain.prototype.getTerrainRoadMoveCost = TerrainGetTerrainRoadMoveCost;
Terrain.prototype.getAllAreAttackingAcrossRiverCombatEffect = TerrainGetAllAreAttackingAcrossRiverCombatEffect;
Terrain.prototype.isExit = TerrainIsExit;
Terrain.prototype.getReinforceZone = TerrainGetReinforceZone;
Terrain.prototype.getDefenderTerrainCombatEffect = TerrainGetDefenderTerrainCombatEffect;