|
|
|
@ -3,16 +3,18 @@
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// To do:
|
|
|
|
|
// Use available civ-type wall elements rather than palisades: Remove 'endLeft' and 'endRight' as default wall elements and adjust default palisade fortress types
|
|
|
|
|
// Rename wall elements to fit he entity names so that entity = 'structures/' + 'civ + '_' + wallElement.type in the common case
|
|
|
|
|
// Add roman army camp to style palisades and add upgraded default palisade fortress types matching civ default fortresses
|
|
|
|
|
// Add some more checks and warnings for example if wall elements with bending are used for linear/circular wall placement
|
|
|
|
|
// Adjust documentation
|
|
|
|
|
// Add further wall elements cornerHalfIn, cornerHalfOut and adjust default fortress types to better fit in the octagonal territory of a civil center
|
|
|
|
|
// Add further wall elements wallShort, wallLong and adjust default fortress types (Waiting for all entities)
|
|
|
|
|
// Remove endRight, endLeft and adjust generic fortress types palisades
|
|
|
|
|
// Add civil center, corral, farmstead, field, market, mill, temple
|
|
|
|
|
// Adjust default fortress types
|
|
|
|
|
// Add wall style 'roads'
|
|
|
|
|
// Add trsures to 'others'
|
|
|
|
|
// Think of something to enable splitting walls into two walls so more complex walls can be build and roads can have branches/crossroads
|
|
|
|
|
// Adjust documentation
|
|
|
|
|
// ?Use available civ-type wall elements rather than palisades: Remove 'endLeft' and 'endRight' as default wall elements and adjust default palisade fortress types?
|
|
|
|
|
// ?Remove endRight, endLeft and adjust generic fortress types palisades?
|
|
|
|
|
// ?Think of something to enable splitting walls into two walls so more complex walls can be build and roads can have branches/crossroads?
|
|
|
|
|
// ?Readjust placement angle for wall elements with bending when used in linear/circular walls by their bending?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////
|
|
|
|
@ -29,7 +31,7 @@
|
|
|
|
|
function WallElement(type, entity, angle, width, indent, bending)
|
|
|
|
|
{
|
|
|
|
|
// NOTE: Not all wall elements have a symetry. So there's an direction 'outside' (towards right/positive X by default)
|
|
|
|
|
// In this sense 'left'/'right' means left/right of you when you stand upon the wall and look 'outside'
|
|
|
|
|
// In this sense 'left'/'right' means left/right of you when standing upon the wall and look 'outside'
|
|
|
|
|
// The wall is build towards 'left' so the next wall element will be placed left of the previous one (towards positive Y by default)
|
|
|
|
|
// In this sense the wall's direction is left meaning the 'bending' of a corner is used for the element following the corner
|
|
|
|
|
// With 'inside' and 'outside' defined as above, corners bend 'in'/'out' meaning placemant angle is increased/decreased (counter clockwise like object placement)
|
|
|
|
@ -37,14 +39,14 @@ function WallElement(type, entity, angle, width, indent, bending)
|
|
|
|
|
// Wall element type documentation:
|
|
|
|
|
// Enlengthening straight blocking (mainly left/right symetric) wall elements (Walls and wall fortifications)
|
|
|
|
|
// 'wall': A blocking straight wall element that mainly lengthens the wall, self-explanatory
|
|
|
|
|
// 'wallShort': self-explanatory. NOTE: Not implemented yet, waiting for finalized templates...
|
|
|
|
|
// 'wallLong': self-explanatory. NOTE: Not implemented yet, waiting for finalized templates...
|
|
|
|
|
// 'wallShort': self-explanatory
|
|
|
|
|
// 'wallLong': self-explanatory
|
|
|
|
|
// 'tower': A blocking straight wall element with damage potential (but for palisades) that slightly lengthens the wall, exsample: wall tower, palisade tower(No attack)
|
|
|
|
|
// 'wallFort': A blocking straight wall element with massive damage potential that lengthens the wall, exsample: fortress, palisade fort
|
|
|
|
|
// Enlengthening straight non/custom blocking (mainly left/right symetric) wall elements (Gates and entrys)
|
|
|
|
|
// 'gate': A blocking straight wall element with passability determined by owner, example: gate (Functionality not yet implemented)
|
|
|
|
|
// 'entry': A wall element like the gate but without an actual template or just a flag/column/obelisk
|
|
|
|
|
// 'entryTower': A non-blocking straight wall element represented by a single (maybe indented) template, example: defense tower, wall tower, outpost, watchtower
|
|
|
|
|
// 'entry': A non-blocking straight wall element (same width as gate) but without an actual template or just a flag/column/obelisk
|
|
|
|
|
// 'entryTower': A non-blocking straight wall element (same width as gate) represented by a single (maybe indented) template, example: defense tower, wall tower, outpost, watchtower
|
|
|
|
|
// 'entryFort': A non-blocking straight wall element represented by a single (maybe indented) template, example: fortress, palisade fort
|
|
|
|
|
// Bending wall elements (Wall corners)
|
|
|
|
|
// 'cornerIn': A wall element bending the wall by PI/2 'inside' (left, +, see above), example: wall tower, palisade curve
|
|
|
|
@ -62,6 +64,7 @@ function WallElement(type, entity, angle, width, indent, bending)
|
|
|
|
|
this.bending = (bending !== undefined) ? bending : 0*PI;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////
|
|
|
|
|
// Fortress class definition
|
|
|
|
|
////////////////////////////
|
|
|
|
@ -80,193 +83,84 @@ function Fortress(type, wall, center)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////
|
|
|
|
|
// Setup data structure for some default wall styles
|
|
|
|
|
////////////////////////////////////////////////////
|
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
|
// Setup data structure for default wall styles
|
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// A wall style is an associative array with all wall elements of that style in it associated with the wall element type string.
|
|
|
|
|
// wallStyles holds all the wall styles within an associative array while a wall style is associated with the civ string or another descriptive strings like 'palisades', 'fence', 'cart', 'celt'...
|
|
|
|
|
var wallStyles = {};
|
|
|
|
|
// Add civilisation wall style 'athen'
|
|
|
|
|
wallStyles['athen'] = {};
|
|
|
|
|
wallStyles['athen']['wall'] = new WallElement('wall', 'structures/athen_wall_medium', 0*PI, 5.9);
|
|
|
|
|
wallStyles['athen']['wallLong'] = new WallElement('wall', 'structures/athen_wall_long', 0*PI, 8.9);
|
|
|
|
|
wallStyles['athen']['wallShort'] = new WallElement('wall', 'structures/athen_wall_short', 0*PI, 3);
|
|
|
|
|
wallStyles['athen']['tower'] = new WallElement('tower', 'structures/athen_wall_tower', PI, 1.7);
|
|
|
|
|
|
|
|
|
|
// Generic civ dependent wall style definition. 'rome_siege' needs some tweek...
|
|
|
|
|
var scaleByCiv = {'athen' : 1.5, 'cart' : 1.8, 'celt' : 1.5, 'hele' : 1.5, 'iber' : 1.5, 'mace' : 1.5, 'pers' : 1.5, 'rome' : 1.5, 'spart' : 1.5, 'rome_siege' : 1.5};
|
|
|
|
|
for (var style in scaleByCiv)
|
|
|
|
|
{
|
|
|
|
|
var civ = style;
|
|
|
|
|
if (style == 'rome_siege')
|
|
|
|
|
civ = 'rome';
|
|
|
|
|
wallStyles[style] = {};
|
|
|
|
|
// Default wall elements
|
|
|
|
|
wallStyles[style]['tower'] = new WallElement('tower', 'structures/' + style + '_wall_tower', PI, scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['endLeft'] = new WallElement('endLeft', 'structures/' + style + '_wall_tower', PI, scaleByCiv[style]); // Same as tower. To be compatible with palisades...
|
|
|
|
|
wallStyles[style]['endRight'] = new WallElement('endRight', 'structures/' + style + '_wall_tower', PI, scaleByCiv[style]); // Same as tower. To be compatible with palisades...
|
|
|
|
|
wallStyles[style]['cornerIn'] = new WallElement('cornerIn', 'structures/' + style + '_wall_tower', 5*PI/4, 0, 0.35*scaleByCiv[style], PI/2); // 2^0.5 / 4 ~= 0.35 ~= 1/3
|
|
|
|
|
wallStyles[style]['cornerOut'] = new WallElement('cornerOut', 'structures/' + style + '_wall_tower', 3*PI/4, 0.71*scaleByCiv[style], 0, -PI/2); // // 2^0.5 / 2 ~= 0.71 ~= 2/3
|
|
|
|
|
wallStyles[style]['wallShort'] = new WallElement('wallShort', 'structures/' + style + '_wall_short', 0*PI, 2*scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['wall'] = new WallElement('wall', 'structures/' + style + '_wall_medium', 0*PI, 4*scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['wallLong'] = new WallElement('wallLong', 'structures/' + style + '_wall_long', 0*PI, 6*scaleByCiv[style]);
|
|
|
|
|
// Gate and entrance wall elements
|
|
|
|
|
if (style == 'cart')
|
|
|
|
|
var gateWidth = 3.5*scaleByCiv[style];
|
|
|
|
|
else if (style == 'celt')
|
|
|
|
|
var gateWidth = 4*scaleByCiv[style];
|
|
|
|
|
// else if (style == 'iber')
|
|
|
|
|
// var gateWidth = 5.5*scaleByCiv[style];
|
|
|
|
|
else
|
|
|
|
|
var gateWidth = 6*scaleByCiv[style];
|
|
|
|
|
wallStyles[style]['gate'] = new WallElement('gate', 'structures/' + style + '_wall_gate', 0*PI, gateWidth);
|
|
|
|
|
wallStyles[style]['entry'] = new WallElement('entry', undefined, 0*PI, gateWidth);
|
|
|
|
|
if (civ == 'iber') // Adjust iberians to have no upkeep at entries with a tower for convinience ATM, may be changed
|
|
|
|
|
wallStyles[style]['entryTower'] = new WallElement('entryTower', 'structures/' + civ + '_wall_tower', PI, gateWidth, -4*scaleByCiv[style]);
|
|
|
|
|
else
|
|
|
|
|
wallStyles[style]['entryTower'] = new WallElement('entryTower', 'structures/' + civ + '_defense_tower', PI, gateWidth, -4*scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['entryFort'] = new WallElement('entryFort', 'structures/' + civ + '_fortress', 0*PI, 8*scaleByCiv[style], 6*scaleByCiv[style]);
|
|
|
|
|
// Defensive wall elements with 0 width outside the wall
|
|
|
|
|
wallStyles[style]['outpost'] = new WallElement('outpost', 'structures/' + civ + '_outpost', PI, 0, -4*scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['defenseTower'] = new WallElement('defenseTower', 'structures/' + civ + '_defenseTower', PI, 0, -4*scaleByCiv[style]);
|
|
|
|
|
// Base buildings wall elements with 0 width inside the wall
|
|
|
|
|
wallStyles[style]['barracks'] = new WallElement('barracks', 'structures/' + civ + '_barracks', PI, 0, 4.5*scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['civilCentre'] = new WallElement('civilCentre', 'structures/' + civ + '_civil_centre', PI, 0, 4.5*scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['farmstead'] = new WallElement('farmstead', 'structures/' + civ + '_farmstead', PI, 0, 4.5*scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['field'] = new WallElement('field', 'structures/' + civ + '_field', PI, 0, 4.5*scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['fortress'] = new WallElement('fortress', 'structures/' + civ + '_fortress', PI, 0, 4.5*scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['house'] = new WallElement('house', 'structures/' + civ + '_house', PI, 0, 4.5*scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['market'] = new WallElement('market', 'structures/' + civ + '_market', PI, 0, 4.5*scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['mill'] = new WallElement('mill', 'structures/' + civ + '_mill', PI, 0, 4.5*scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['temple'] = new WallElement('temple', 'structures/' + civ + '_temple', PI, 0, 4.5*scaleByCiv[style]);
|
|
|
|
|
// Generic space/gap wall elements
|
|
|
|
|
wallStyles[style]['space1'] = new WallElement('space1', undefined, 0*PI, scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['space2'] = new WallElement('space2', undefined, 0*PI, 2*scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['space3'] = new WallElement('space3', undefined, 0*PI, 3*scaleByCiv[style]);
|
|
|
|
|
wallStyles[style]['space4'] = new WallElement('space4', undefined, 0*PI, 4*scaleByCiv[style]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add wall fortresses for all generic styles
|
|
|
|
|
wallStyles['athen']['wallFort'] = new WallElement('wallFort', 'structures/athen_fortress', 2*PI/2 /* PI/2 */, 5.1 /* 5.6 */, 1.9 /* 1.9 */);
|
|
|
|
|
wallStyles['athen']['gate'] = new WallElement('gate', 'structures/athen_wall_gate', 0*PI, 9.1);
|
|
|
|
|
wallStyles['athen']['entry'] = new WallElement('entry', undefined, wallStyles['athen']['gate'].angle, wallStyles['athen']['gate'].width);
|
|
|
|
|
wallStyles['athen']['entryTower'] = new WallElement('entry', 'structures/athen_defense_tower', PI, wallStyles['athen']['gate'].width, -5);
|
|
|
|
|
wallStyles['athen']['entryFort'] = new WallElement('entryFort', 'structures/athen_fortress', 5*PI/2, 12, 7);
|
|
|
|
|
wallStyles['athen']['cornerIn'] = new WallElement('cornerIn', 'structures/athen_wall_tower', 5*PI/4, 0, 0.5, PI/2);
|
|
|
|
|
wallStyles['athen']['cornerOut'] = new WallElement('cornerOut', 'structures/athen_wall_tower', 3*PI/4, 1, 0, -PI/2);
|
|
|
|
|
wallStyles['athen']['outpost'] = new WallElement('outpost', 'structures/athen_outpost', PI, 0, -5);
|
|
|
|
|
wallStyles['athen']['house'] = new WallElement('house', 'structures/athen_house', 3*PI/2, 0, 6);
|
|
|
|
|
wallStyles['athen']['barracks'] = new WallElement('barracks', 'structures/athen_barracks', PI, 0, 6);
|
|
|
|
|
wallStyles['athen']['endRight'] = new WallElement('endRight', wallStyles['athen']['tower'].entity, wallStyles['athen']['tower'].angle, wallStyles['athen']['tower'].width);
|
|
|
|
|
wallStyles['athen']['endLeft'] = new WallElement('endLeft', wallStyles['athen']['tower'].entity, wallStyles['athen']['tower'].angle, wallStyles['athen']['tower'].width);
|
|
|
|
|
// Add civilisation wall style 'cart'
|
|
|
|
|
wallStyles['cart'] = {};
|
|
|
|
|
wallStyles['cart']['wall'] = new WallElement('wall', 'structures/cart_wall_medium', 0*PI, 7.2);
|
|
|
|
|
wallStyles['cart']['wallLong'] = new WallElement('wall', 'structures/cart_wall_long', 0*PI, 10.8);
|
|
|
|
|
wallStyles['cart']['wallShort'] = new WallElement('wall', 'structures/cart_wall_short', 0*PI, 3.6);
|
|
|
|
|
wallStyles['cart']['tower'] = new WallElement('tower', 'structures/cart_wall_tower', PI, 2.4);
|
|
|
|
|
wallStyles['cart']['wallFort'] = new WallElement('wallFort', 'structures/cart_fortress', PI, 5.1, 1.6);
|
|
|
|
|
wallStyles['cart']['gate'] = new WallElement('gate', 'structures/cart_wall_gate', 0*PI, 6.2);
|
|
|
|
|
wallStyles['cart']['entry'] = new WallElement('entry', undefined, wallStyles['cart']['gate'].angle, wallStyles['cart']['gate'].width);
|
|
|
|
|
wallStyles['cart']['entryTower'] = new WallElement('entryTower', 'structures/cart_defense_tower', PI, wallStyles['cart']['gate'].width, -5);
|
|
|
|
|
wallStyles['cart']['entryFort'] = new WallElement('entryFort', 'structures/cart_fortress', PI, 12, 7);
|
|
|
|
|
wallStyles['cart']['cornerIn'] = new WallElement('cornerIn', 'structures/cart_wall_tower', 5*PI/4, 0, 0.8, PI/2);
|
|
|
|
|
wallStyles['cart']['cornerOut'] = new WallElement('cornerOut', 'structures/cart_wall_tower', 3*PI/4, 1.3 /*1.6*/, 0, -PI/2);
|
|
|
|
|
wallStyles['cart']['outpost'] = new WallElement('outpost', 'structures/cart_outpost', PI, 0, -5);
|
|
|
|
|
wallStyles['cart']['house'] = new WallElement('house', 'structures/cart_house', PI, 0, 7);
|
|
|
|
|
wallStyles['cart']['barracks'] = new WallElement('barracks', 'structures/cart_barracks', PI, 0, 7);
|
|
|
|
|
wallStyles['cart']['endRight'] = new WallElement('endRight', wallStyles['cart']['tower'].entity, wallStyles['cart']['tower'].angle, wallStyles['cart']['tower'].width);
|
|
|
|
|
wallStyles['cart']['endLeft'] = new WallElement('endLeft', wallStyles['cart']['tower'].entity, wallStyles['cart']['tower'].angle, wallStyles['cart']['tower'].width);
|
|
|
|
|
// Add civilisation wall style 'celt'
|
|
|
|
|
wallStyles['celt'] = {};
|
|
|
|
|
wallStyles['celt']['wall'] = new WallElement('wall', 'structures/celt_wall_medium', 0*PI, 5.9);
|
|
|
|
|
wallStyles['celt']['wallLong'] = new WallElement('wall', 'structures/celt_wall_long', 0*PI, 8.9);
|
|
|
|
|
wallStyles['celt']['wallShort'] = new WallElement('wall', 'structures/celt_wall_short', 0*PI, 2.9);
|
|
|
|
|
wallStyles['celt']['tower'] = new WallElement('tower', 'structures/celt_wall_tower', PI, 1.7);
|
|
|
|
|
wallStyles['celt']['wallFort'] = new WallElement('wallFort', 'structures/celt_fortress_g', PI, 4.2, 1.5);
|
|
|
|
|
wallStyles['celt']['gate'] = new WallElement('gate', 'structures/celt_wall_gate', 0*PI, 5.6);
|
|
|
|
|
wallStyles['celt']['entry'] = new WallElement('entry', undefined, wallStyles['celt']['gate'].angle, wallStyles['celt']['gate'].width);
|
|
|
|
|
wallStyles['celt']['entryTower'] = new WallElement('entryTower', 'structures/celt_defense_tower', PI, wallStyles['celt']['gate'].width, -5);
|
|
|
|
|
wallStyles['celt']['entryFort'] = new WallElement('entryFort', 'structures/celt_fortress_b', PI, 8, 5);
|
|
|
|
|
wallStyles['celt']['cornerIn'] = new WallElement('cornerIn', 'structures/celt_wall_tower', 5*PI/4, 0, 0.7, PI/2);
|
|
|
|
|
wallStyles['celt']['cornerOut'] = new WallElement('cornerOut', 'structures/celt_wall_tower', 3*PI/4, 1.3, 0, -PI/2);
|
|
|
|
|
wallStyles['celt']['outpost'] = new WallElement('outpost', 'structures/celt_outpost', PI, 0, -5);
|
|
|
|
|
wallStyles['celt']['house'] = new WallElement('house', 'structures/celt_house', PI, 0, 3);
|
|
|
|
|
wallStyles['celt']['barracks'] = new WallElement('barracks', 'structures/celt_barracks', PI, 0, 7);
|
|
|
|
|
wallStyles['celt']['endRight'] = new WallElement('endRight', wallStyles['celt']['tower'].entity, wallStyles['celt']['tower'].angle, wallStyles['celt']['tower'].width);
|
|
|
|
|
wallStyles['celt']['endLeft'] = new WallElement('endLeft', wallStyles['celt']['tower'].entity, wallStyles['celt']['tower'].angle, wallStyles['celt']['tower'].width);
|
|
|
|
|
// Add civilisation wall style 'hele'
|
|
|
|
|
wallStyles['hele'] = {};
|
|
|
|
|
wallStyles['hele']['wall'] = new WallElement('wall', 'structures/hele_wall_medium', 0*PI, 5.9);
|
|
|
|
|
wallStyles['hele']['wallLong'] = new WallElement('wall', 'structures/hele_wall_long', 0*PI, 8.9);
|
|
|
|
|
wallStyles['hele']['wallShort'] = new WallElement('wall', 'structures/hele_wall_short', 0*PI, 3);
|
|
|
|
|
wallStyles['hele']['tower'] = new WallElement('tower', 'structures/hele_wall_tower', PI, 1.7);
|
|
|
|
|
wallStyles['hele']['wallFort'] = new WallElement('wallFort', 'structures/hele_fortress', 2*PI/2 /* PI/2 */, 5.1 /* 5.6 */, 1.9 /* 1.9 */);
|
|
|
|
|
wallStyles['hele']['gate'] = new WallElement('gate', 'structures/hele_wall_gate', 0*PI, 9.1);
|
|
|
|
|
wallStyles['hele']['entry'] = new WallElement('entry', undefined, wallStyles['hele']['gate'].angle, wallStyles['hele']['gate'].width);
|
|
|
|
|
wallStyles['hele']['entryTower'] = new WallElement('entry', 'structures/hele_defense_tower', PI, wallStyles['hele']['gate'].width, -5);
|
|
|
|
|
wallStyles['hele']['entryFort'] = new WallElement('entryFort', 'structures/hele_fortress', 5*PI/2, 12, 7);
|
|
|
|
|
wallStyles['hele']['cornerIn'] = new WallElement('cornerIn', 'structures/hele_wall_tower', 5*PI/4, 0, 0.5, PI/2);
|
|
|
|
|
wallStyles['hele']['cornerOut'] = new WallElement('cornerOut', 'structures/hele_wall_tower', 3*PI/4, 1, 0, -PI/2);
|
|
|
|
|
wallStyles['hele']['outpost'] = new WallElement('outpost', 'structures/hele_outpost', PI, 0, -5);
|
|
|
|
|
wallStyles['hele']['house'] = new WallElement('house', 'structures/hele_house', 3*PI/2, 0, 6);
|
|
|
|
|
wallStyles['hele']['barracks'] = new WallElement('barracks', 'structures/hele_barracks', PI, 0, 6);
|
|
|
|
|
wallStyles['hele']['endRight'] = new WallElement('endRight', wallStyles['hele']['tower'].entity, wallStyles['hele']['tower'].angle, wallStyles['hele']['tower'].width);
|
|
|
|
|
wallStyles['hele']['endLeft'] = new WallElement('endLeft', wallStyles['hele']['tower'].entity, wallStyles['hele']['tower'].angle, wallStyles['hele']['tower'].width);
|
|
|
|
|
// Add civilisation wall style 'iber'
|
|
|
|
|
wallStyles['iber'] = {};
|
|
|
|
|
wallStyles['iber']['wall'] = new WallElement('wall', 'structures/iber_wall_medium', 0*PI, 6);
|
|
|
|
|
wallStyles['iber']['wallLong'] = new WallElement('wall', 'structures/iber_wall_long', 0*PI, 9);
|
|
|
|
|
wallStyles['iber']['wallShort'] = new WallElement('wall', 'structures/iber_wall_short', 0*PI, 2.9);
|
|
|
|
|
wallStyles['iber']['tower'] = new WallElement('tower', 'structures/iber_wall_tower', PI, 1.7);
|
|
|
|
|
wallStyles['iber']['wallFort'] = new WallElement('wallFort', 'structures/iber_fortress', PI, 5, 0.2);
|
|
|
|
|
wallStyles['iber']['gate'] = new WallElement('gate', 'structures/iber_wall_gate', 0*PI, 7.9);
|
|
|
|
|
wallStyles['iber']['entry'] = new WallElement('entry', undefined, wallStyles['iber']['gate'].angle, wallStyles['iber']['gate'].width);
|
|
|
|
|
wallStyles['iber']['entryTower'] = new WallElement('entryTower', 'structures/iber_wall_tower', PI, wallStyles['iber']['gate'].width, -5);
|
|
|
|
|
wallStyles['iber']['entryFort'] = new WallElement('entryFort', 'structures/iber_fortress', PI/2, 12, 7);
|
|
|
|
|
wallStyles['iber']['cornerIn'] = new WallElement('cornerIn', 'structures/iber_wall_tower', 5*PI/4, 1.7, 0, PI/2);
|
|
|
|
|
wallStyles['iber']['cornerOut'] = new WallElement('cornerOut', 'structures/iber_wall_tower', 3*PI/4, 1.7, 0, -PI/2);
|
|
|
|
|
wallStyles['iber']['outpost'] = new WallElement('outpost', 'structures/iber_outpost', PI, 0, -5);
|
|
|
|
|
wallStyles['iber']['house'] = new WallElement('house', 'structures/iber_house', PI, 0, 4);
|
|
|
|
|
wallStyles['iber']['barracks'] = new WallElement('barracks', 'structures/iber_barracks', PI, 0, 7);
|
|
|
|
|
wallStyles['iber']['endRight'] = new WallElement('endRight', wallStyles['iber']['tower'].entity, wallStyles['iber']['tower'].angle, wallStyles['iber']['tower'].width);
|
|
|
|
|
wallStyles['iber']['endLeft'] = new WallElement('endLeft', wallStyles['iber']['tower'].entity, wallStyles['iber']['tower'].angle, wallStyles['iber']['tower'].width);
|
|
|
|
|
// Add civilisation wall style 'mace'
|
|
|
|
|
wallStyles['mace'] = {};
|
|
|
|
|
wallStyles['mace']['wall'] = new WallElement('wall', 'structures/mace_wall_medium', 0*PI, 5.9);
|
|
|
|
|
wallStyles['mace']['wallLong'] = new WallElement('wall', 'structures/mace_wall_long', 0*PI, 8.9);
|
|
|
|
|
wallStyles['mace']['wallShort'] = new WallElement('wall', 'structures/mace_wall_short', 0*PI, 3);
|
|
|
|
|
wallStyles['mace']['tower'] = new WallElement('tower', 'structures/mace_wall_tower', PI, 1.7);
|
|
|
|
|
wallStyles['mace']['wallFort'] = new WallElement('wallFort', 'structures/mace_fortress', 2*PI/2 /* PI/2 */, 5.1 /* 5.6 */, 1.9 /* 1.9 */);
|
|
|
|
|
wallStyles['mace']['gate'] = new WallElement('gate', 'structures/mace_wall_gate', 0*PI, 9.1);
|
|
|
|
|
wallStyles['mace']['entry'] = new WallElement('entry', undefined, wallStyles['mace']['gate'].angle, wallStyles['mace']['gate'].width);
|
|
|
|
|
wallStyles['mace']['entryTower'] = new WallElement('entry', 'structures/mace_defense_tower', PI, wallStyles['mace']['gate'].width, -5);
|
|
|
|
|
wallStyles['mace']['entryFort'] = new WallElement('entryFort', 'structures/mace_fortress', 5*PI/2, 12, 7);
|
|
|
|
|
wallStyles['mace']['cornerIn'] = new WallElement('cornerIn', 'structures/mace_wall_tower', 5*PI/4, 0, 0.5, PI/2);
|
|
|
|
|
wallStyles['mace']['cornerOut'] = new WallElement('cornerOut', 'structures/mace_wall_tower', 3*PI/4, 1, 0, -PI/2);
|
|
|
|
|
wallStyles['mace']['outpost'] = new WallElement('outpost', 'structures/mace_outpost', PI, 0, -5);
|
|
|
|
|
wallStyles['mace']['house'] = new WallElement('house', 'structures/mace_house', 3*PI/2, 0, 6);
|
|
|
|
|
wallStyles['mace']['barracks'] = new WallElement('barracks', 'structures/mace_barracks', PI, 0, 6);
|
|
|
|
|
wallStyles['mace']['endRight'] = new WallElement('endRight', wallStyles['mace']['tower'].entity, wallStyles['mace']['tower'].angle, wallStyles['mace']['tower'].width);
|
|
|
|
|
wallStyles['mace']['endLeft'] = new WallElement('endLeft', wallStyles['mace']['tower'].entity, wallStyles['mace']['tower'].angle, wallStyles['mace']['tower'].width);
|
|
|
|
|
// Add civilisation wall style 'pers'
|
|
|
|
|
wallStyles['pers'] = {};
|
|
|
|
|
wallStyles['pers']['wall'] = new WallElement('wall', 'structures/pers_wall_medium', 0*PI, 6);
|
|
|
|
|
wallStyles['pers']['wallLong'] = new WallElement('wall', 'structures/pers_wall_long', 0*PI, 9);
|
|
|
|
|
wallStyles['pers']['wallShort'] = new WallElement('wall', 'structures/pers_wall_short', 0*PI, 3);
|
|
|
|
|
wallStyles['pers']['tower'] = new WallElement('tower', 'structures/pers_wall_tower', PI, 1.7);
|
|
|
|
|
wallStyles['pers']['wallFort'] = new WallElement('wallFort', 'structures/pers_fortress', PI, 5.6/*5.5*/, 1.9/*1.7*/);
|
|
|
|
|
wallStyles['pers']['gate'] = new WallElement('gate', 'structures/pers_wall_gate', 0*PI, 6);
|
|
|
|
|
wallStyles['pers']['entry'] = new WallElement('entry', undefined, wallStyles['pers']['gate'].angle, wallStyles['pers']['gate'].width);
|
|
|
|
|
wallStyles['pers']['entryTower'] = new WallElement('entry', 'structures/pers_defense_tower', PI, wallStyles['pers']['gate'].width, -5);
|
|
|
|
|
wallStyles['pers']['entryFort'] = new WallElement('entryFort', 'structures/pers_fortress', PI, 12, 7);
|
|
|
|
|
wallStyles['pers']['cornerIn'] = new WallElement('cornerIn', 'structures/pers_wall_tower', 5*PI/4, 0.2, 0.5, PI/2);
|
|
|
|
|
wallStyles['pers']['cornerOut'] = new WallElement('cornerOut', 'structures/pers_wall_tower', 3*PI/4, 0.8, 0, -PI/2);
|
|
|
|
|
wallStyles['pers']['outpost'] = new WallElement('outpost', 'structures/pers_outpost', PI, 0, -5);
|
|
|
|
|
wallStyles['pers']['house'] = new WallElement('house', 'structures/pers_house', PI, 0, 6);
|
|
|
|
|
wallStyles['pers']['barracks'] = new WallElement('barracks', 'structures/pers_barracks', PI, 0, 7);
|
|
|
|
|
wallStyles['pers']['endRight'] = new WallElement('endRight', wallStyles['pers']['tower'].entity, wallStyles['pers']['tower'].angle, wallStyles['pers']['tower'].width);
|
|
|
|
|
wallStyles['pers']['endLeft'] = new WallElement('endLeft', wallStyles['pers']['tower'].entity, wallStyles['pers']['tower'].angle, wallStyles['pers']['tower'].width);
|
|
|
|
|
// Add civilisation wall style 'rome'
|
|
|
|
|
wallStyles['rome'] = {};
|
|
|
|
|
wallStyles['rome']['wall'] = new WallElement('wall', 'structures/rome_wall_medium', 0*PI, 6);
|
|
|
|
|
wallStyles['rome']['wallLong'] = new WallElement('wall', 'structures/rome_wall_long', 0*PI, 9);
|
|
|
|
|
wallStyles['rome']['wallShort'] = new WallElement('wall', 'structures/rome_wall_short', 0*PI, 3);
|
|
|
|
|
wallStyles['rome']['tower'] = new WallElement('tower', 'structures/rome_wall_tower', PI, 2.1);
|
|
|
|
|
wallStyles['rome']['wallFort'] = new WallElement('wallFort', 'structures/rome_fortress', PI, 6.3, 2.1);
|
|
|
|
|
wallStyles['rome']['gate'] = new WallElement('gate', 'structures/rome_wall_gate', 0*PI, 5.9);
|
|
|
|
|
wallStyles['rome']['entry'] = new WallElement('entry', undefined, wallStyles['rome']['gate'].angle, wallStyles['rome']['gate'].width);
|
|
|
|
|
wallStyles['rome']['entryTower'] = new WallElement('entryTower', 'structures/rome_defense_tower', PI, wallStyles['rome']['gate'].width, -5);
|
|
|
|
|
wallStyles['rome']['entryFort'] = new WallElement('entryFort', 'structures/rome_fortress', PI, 12, 7);
|
|
|
|
|
wallStyles['rome']['cornerIn'] = new WallElement('cornerIn', 'structures/rome_wall_tower', 5*PI/4, 0, 0.7, PI/2);
|
|
|
|
|
wallStyles['rome']['cornerOut'] = new WallElement('cornerOut', 'structures/rome_wall_tower', 3*PI/4, 1.1, 0, -PI/2);
|
|
|
|
|
wallStyles['rome']['outpost'] = new WallElement('outpost', 'structures/rome_outpost', PI, 0, -5);
|
|
|
|
|
wallStyles['rome']['house'] = new WallElement('house', 'structures/rome_house', PI, 0, 7);
|
|
|
|
|
wallStyles['rome']['barracks'] = new WallElement('barracks', 'structures/rome_barracks', PI, 0, 6);
|
|
|
|
|
wallStyles['rome']['endRight'] = new WallElement('endRight', wallStyles['rome']['tower'].entity, wallStyles['rome']['tower'].angle, wallStyles['rome']['tower'].width);
|
|
|
|
|
wallStyles['rome']['endLeft'] = new WallElement('endLeft', wallStyles['rome']['tower'].entity, wallStyles['rome']['tower'].angle, wallStyles['rome']['tower'].width);
|
|
|
|
|
// Add civilisation wall style 'spart'
|
|
|
|
|
wallStyles['spart'] = {};
|
|
|
|
|
wallStyles['spart']['wall'] = new WallElement('wall', 'structures/spart_wall_medium', 0*PI, 5.9);
|
|
|
|
|
wallStyles['spart']['wallLong'] = new WallElement('wall', 'structures/spart_wall_long', 0*PI, 8.9);
|
|
|
|
|
wallStyles['spart']['wallShort'] = new WallElement('wall', 'structures/spart_wall_short', 0*PI, 3);
|
|
|
|
|
wallStyles['spart']['tower'] = new WallElement('tower', 'structures/spart_wall_tower', PI, 1.7);
|
|
|
|
|
wallStyles['spart']['wallFort'] = new WallElement('wallFort', 'structures/spart_fortress', 2*PI/2 /* PI/2 */, 5.1 /* 5.6 */, 1.9 /* 1.9 */);
|
|
|
|
|
wallStyles['spart']['gate'] = new WallElement('gate', 'structures/spart_wall_gate', 0*PI, 9.1);
|
|
|
|
|
wallStyles['spart']['entry'] = new WallElement('entry', undefined, wallStyles['spart']['gate'].angle, wallStyles['spart']['gate'].width);
|
|
|
|
|
wallStyles['spart']['entryTower'] = new WallElement('entry', 'structures/spart_defense_tower', PI, wallStyles['spart']['gate'].width, -5);
|
|
|
|
|
wallStyles['spart']['entryFort'] = new WallElement('entryFort', 'structures/spart_fortress', 5*PI/2, 12, 7);
|
|
|
|
|
wallStyles['spart']['cornerIn'] = new WallElement('cornerIn', 'structures/spart_wall_tower', 5*PI/4, 0, 0.5, PI/2);
|
|
|
|
|
wallStyles['spart']['cornerOut'] = new WallElement('cornerOut', 'structures/spart_wall_tower', 3*PI/4, 1, 0, -PI/2);
|
|
|
|
|
wallStyles['spart']['outpost'] = new WallElement('outpost', 'structures/spart_outpost', PI, 0, -5);
|
|
|
|
|
wallStyles['spart']['house'] = new WallElement('house', 'structures/spart_house', 3*PI/2, 0, 6);
|
|
|
|
|
wallStyles['spart']['barracks'] = new WallElement('barracks', 'structures/spart_barracks', PI, 0, 6);
|
|
|
|
|
wallStyles['spart']['endRight'] = new WallElement('endRight', wallStyles['spart']['tower'].entity, wallStyles['spart']['tower'].angle, wallStyles['spart']['tower'].width);
|
|
|
|
|
wallStyles['spart']['endLeft'] = new WallElement('endLeft', wallStyles['spart']['tower'].entity, wallStyles['spart']['tower'].angle, wallStyles['spart']['tower'].width);
|
|
|
|
|
// Add special wall style 'romeSiege'
|
|
|
|
|
wallStyles['romeSiege'] = {};
|
|
|
|
|
wallStyles['romeSiege']['wall'] = new WallElement('wall', 'structures/rome_siege_wall_medium', 0*PI, 6);
|
|
|
|
|
wallStyles['romeSiege']['wallLong'] = new WallElement('wall', 'structures/rome_siege_wall_long', 0*PI, 9);
|
|
|
|
|
wallStyles['romeSiege']['wallShort'] = new WallElement('wall', 'structures/rome_siege_wall_short', 0*PI, 3);
|
|
|
|
|
wallStyles['romeSiege']['tower'] = new WallElement('tower', 'structures/rome_siege_wall_tower', PI, 1.3);
|
|
|
|
|
wallStyles['romeSiege']['wallFort'] = new WallElement('wallFort', 'structures/rome_army_camp', PI, 7.2, 2);
|
|
|
|
|
wallStyles['romeSiege']['gate'] = new WallElement('gate', 'structures/rome_siege_wall_gate', 0*PI, 9);
|
|
|
|
|
wallStyles['romeSiege']['entry'] = new WallElement('entry', undefined, wallStyles['romeSiege']['gate'].angle, wallStyles['romeSiege']['gate'].width);
|
|
|
|
|
wallStyles['romeSiege']['entryTower'] = new WallElement('entryTower', 'structures/rome_defense_tower', PI, wallStyles['romeSiege']['gate'].width, -5);
|
|
|
|
|
wallStyles['romeSiege']['entryFort'] = new WallElement('entryFort', 'structures/rome_army_camp', PI, 12, 7);
|
|
|
|
|
wallStyles['romeSiege']['cornerIn'] = new WallElement('cornerIn', 'structures/rome_siege_wall_tower', 5*PI/4, 0.0, 0.6, PI/2);
|
|
|
|
|
wallStyles['romeSiege']['cornerOut'] = new WallElement('cornerOut', 'structures/rome_siege_wall_tower', 3*PI/4, 1.1, 0, -PI/2);
|
|
|
|
|
wallStyles['romeSiege']['outpost'] = new WallElement('outpost', 'structures/rome_outpost', PI, 0, -5);
|
|
|
|
|
wallStyles['romeSiege']['house'] = new WallElement('house', 'structures/rome_tent', PI, 0, 4);
|
|
|
|
|
wallStyles['romeSiege']['barracks'] = new WallElement('barracks', 'structures/rome_barracks', PI, 0, 6);
|
|
|
|
|
wallStyles['romeSiege']['endRight'] = new WallElement('endRight', wallStyles['romeSiege']['tower'].entity, wallStyles['romeSiege']['tower'].angle, wallStyles['romeSiege']['tower'].width);
|
|
|
|
|
wallStyles['romeSiege']['endLeft'] = new WallElement('endLeft', wallStyles['romeSiege']['tower'].entity, wallStyles['romeSiege']['tower'].angle, wallStyles['romeSiege']['tower'].width);
|
|
|
|
|
// Adjust 'rome_siege' style
|
|
|
|
|
wallStyles['rome_siege']['wallFort'] = new WallElement('wallFort', 'structures/rome_army_camp', PI, 7.2, 2);
|
|
|
|
|
wallStyles['rome_siege']['entryFort'] = new WallElement('entryFort', 'structures/rome_army_camp', PI, 12, 7);
|
|
|
|
|
wallStyles['rome_siege']['house'] = new WallElement('house', 'structures/rome_tent', PI, 0, 4);
|
|
|
|
|
|
|
|
|
|
// Add special wall styles not well to implement generic (and to show how custom styles can be added)
|
|
|
|
|
|
|
|
|
|
// Add special wall style 'palisades'
|
|
|
|
|
wallStyles['palisades'] = {};
|
|
|
|
|
wallStyles['palisades']['wall'] = new WallElement('wall', 'other/palisades_rocks_medium', 0*PI, 2.3);
|
|
|
|
@ -285,7 +179,9 @@ wallStyles['palisades']['house'] = new WallElement('house', 'other/celt_hut', PI
|
|
|
|
|
wallStyles['palisades']['barracks'] = new WallElement('barracks', 'other/celt_tavern', PI, 0, 5);
|
|
|
|
|
wallStyles['palisades']['endRight'] = new WallElement('endRight', 'other/palisades_rocks_end', -PI/2, 0.2);
|
|
|
|
|
wallStyles['palisades']['endLeft'] = new WallElement('endLeft', 'other/palisades_rocks_end', PI/2, 0.2);
|
|
|
|
|
|
|
|
|
|
// Add special wall style 'road'
|
|
|
|
|
|
|
|
|
|
// Add special wall element collection 'other'
|
|
|
|
|
// NOTE: This is not a wall style in the common sense. Use with care!
|
|
|
|
|
wallStyles['other'] = {};
|
|
|
|
@ -352,6 +248,24 @@ var wallPart = ['entry', 'endLeft', 'wall', 'outpost', 'wall', 'cornerIn', 'wall
|
|
|
|
|
'cornerOut', 'wall', 'outpost', 'wall', 'cornerIn', 'wall', 'outpost', 'wall', 'endRight'];
|
|
|
|
|
fortressTypes['giant'].wall = wallPart.concat(wallPart, wallPart, wallPart);
|
|
|
|
|
|
|
|
|
|
// Add (some) iberian civ bonus fortress (The civ can still be set, just an uncommon default fortress)
|
|
|
|
|
var wall = ['gate', 'tower', 'wall', 'cornerIn', 'wallLong', 'tower',
|
|
|
|
|
'gate', 'tower', 'wallLong', 'cornerIn', 'wall', 'tower',
|
|
|
|
|
'gate', 'wall', 'cornerIn', 'wall', 'cornerOut', 'wall', 'cornerIn', 'wallLong', 'tower',
|
|
|
|
|
'gate', 'tower', 'wallLong', 'cornerIn', 'wall', 'tower', 'wall', 'cornerIn', 'wall'];
|
|
|
|
|
fortressTypes['iberCivBonus'] = new Fortress('iberCivBonus', wall);
|
|
|
|
|
var wall = ['gate', 'tower', 'wall', 'cornerIn', 'wall', 'cornerOut', 'wall', 'cornerIn', 'wallLong', 'tower',
|
|
|
|
|
'gate', 'tower', 'wallLong', 'cornerIn', 'wall', 'tower', 'wall', 'cornerIn', 'wall', 'cornerOut',
|
|
|
|
|
'gate', 'tower', 'wall', 'cornerIn', 'wallLong', 'tower',
|
|
|
|
|
'gate', 'tower', 'wallLong', 'cornerIn', 'wall', 'tower'];
|
|
|
|
|
fortressTypes['iberCivBonus2'] = new Fortress('iberCivBonus2', wall);
|
|
|
|
|
var wall = ['gate', 'tower', 'wall', 'cornerOut', 'wallShort', 'cornerIn', 'wall', 'cornerIn', 'wallLong', 'cornerIn', 'wallShort', 'cornerOut', 'wall', 'tower',
|
|
|
|
|
'gate', 'tower', 'wallLong', 'cornerIn', 'wallLong', 'cornerIn', 'wallShort', 'cornerOut',
|
|
|
|
|
'gate', 'tower', 'wall', 'cornerIn', 'wall', 'cornerOut', 'wallShort', 'cornerIn', 'wall', 'tower',
|
|
|
|
|
'gate', 'tower', 'wallShort', 'cornerIn', 'wall', 'tower', 'wallShort', 'tower'];
|
|
|
|
|
fortressTypes['iberCivBonus3'] = new Fortress('iberCivBonus3', wall);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Setup some semi default fortresses for 'palisades' style
|
|
|
|
|
var fortressTypeKeys = ['tiny', 'small', 'medium', 'normal', 'large', 'veryLarge', 'giant'];
|
|
|
|
|
for (var i = 0; i < fortressTypeKeys.length; i++)
|
|
|
|
@ -370,9 +284,9 @@ for (var i = 0; i < fortressTypeKeys.length; i++)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
// Define the abstract getWallAlignment and getWallCenter function
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Define some helper functions: getWallAlignment, getWallCenter, getWallLength
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// Get alignment of a wall
|
|
|
|
|
// Returns a list of lists of most arguments needed to place the different wall elements for a given wall
|
|
|
|
@ -419,14 +333,9 @@ function getWallAlignment(startX, startY, wall, style, orientation)
|
|
|
|
|
return alignment;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Get the center of a wall (mainly usefull for closed walls like fortresses)
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// Center calculation works like getting the center of mass assuming all wall elements have the same 'waight'
|
|
|
|
|
// It returns the vector (array [x, y]) from the first wall element to the center
|
|
|
|
|
// So if used to preset the center in an instance of the fortress class use the negative values (I think)
|
|
|
|
|
function getWallCenter(alignment)
|
|
|
|
|
{
|
|
|
|
|
var x = 0;
|
|
|
|
@ -440,19 +349,29 @@ function getWallCenter(alignment)
|
|
|
|
|
return center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the length of a wall used by placeIrregularPolygonalWall
|
|
|
|
|
// NOTE: Does not support bending wall elements like corners!
|
|
|
|
|
function getWallLength(wall, style)
|
|
|
|
|
{
|
|
|
|
|
var length = 0;
|
|
|
|
|
for (var i = 0; i < wall.length; i++)
|
|
|
|
|
{
|
|
|
|
|
length += wallStyles[style][wall[i]].width;
|
|
|
|
|
}
|
|
|
|
|
return length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////
|
|
|
|
|
// Define the different wall placer functions
|
|
|
|
|
/////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Place simple wall starting with the first wall element placed at startX/startY
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// orientation: 0 means 'outside' or 'front' of the wall is right (positive X) like placeObject
|
|
|
|
|
// It will then be build towards top (positive Y) if no bending wall elements like corners are used
|
|
|
|
|
// Raising orientation means the wall is rotated counter-clockwise like placeObject
|
|
|
|
|
// It will then be build towards top (positive Y) if no bending wall elements like corners are used
|
|
|
|
|
// Raising orientation means the wall is rotated counter-clockwise like placeObject
|
|
|
|
|
function placeWall(startX, startY, wall, style, playerId, orientation)
|
|
|
|
|
{
|
|
|
|
|
var AM = getWallAlignment(startX, startY, wall, style, orientation);
|
|
|
|
@ -463,11 +382,9 @@ function placeWall(startX, startY, wall, style, playerId, orientation)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Place a fortress (mainly a closed wall build like placeWall) with the center at centerX/centerY
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// Should always start with the main entrance (like 'entry' or 'gate') to get the orientation right (like placeObject)
|
|
|
|
|
function placeCustomFortress(centerX, centerY, fortress, style, playerId, orientation, scipGetCenter)
|
|
|
|
|
{
|
|
|
|
@ -475,7 +392,7 @@ function placeCustomFortress(centerX, centerY, fortress, style, playerId, orient
|
|
|
|
|
{
|
|
|
|
|
var alignment = getWallAlignment(0, 0, fortress.wall, style);
|
|
|
|
|
var center = getWallCenter(alignment);
|
|
|
|
|
var startX = centerX - center[0] * cos(orientation) - center[1] * sin(orientation);
|
|
|
|
|
var startX = centerX - center[0] * cos(orientation) + center[1] * sin(orientation);
|
|
|
|
|
var startY = centerY - center[1] * cos(orientation) - center[0] * sin(orientation);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -491,11 +408,9 @@ function placeFortress(centerX, centerY, type, style, playerId, orientation, sci
|
|
|
|
|
placeCustomFortress(centerX, centerY, fortressTypes[type], style, playerId, orientation, scipGetCenter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Place a linear wall of repeatant wall elements given in the argument wallPart from startX/startY to targetX/targetY
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// startX: x coordinate of the beginning of the wall
|
|
|
|
|
// startY: y coordinate of the beginning of the wall
|
|
|
|
|
// targetX: x coordinate of the ending of the wall
|
|
|
|
@ -512,7 +427,13 @@ function placeLinearWall(startX, startY, targetX, targetY, wallPart, style, play
|
|
|
|
|
wallPart = (wallPart || ['wall']);
|
|
|
|
|
style = (style || 'palisades');
|
|
|
|
|
playerId = (playerId || 0);
|
|
|
|
|
endWithFirst = (endWithFirst || true);
|
|
|
|
|
// endWithFirst = (endWithFirst || true);
|
|
|
|
|
endWithFirst = typeof endWithFirst == 'undefined' ? true : endWithFirst;
|
|
|
|
|
log("endWithFirst = " + endWithFirst);
|
|
|
|
|
// Check arguments
|
|
|
|
|
for (var elementIndex = 0; elementIndex < wallPart.length; elementIndex++)
|
|
|
|
|
if (wallStyles[style][wallPart[elementIndex]].bending != 0)
|
|
|
|
|
warn("Bending is not supported by placeLinearWall but a bending wall element is used: " + wallPart[elementIndex] + " -> wallStyles[style][wallPart[elementIndex]].entity");
|
|
|
|
|
// Setup number of wall parts
|
|
|
|
|
var totalLength = getDistance(startX, startY, targetX, targetY);
|
|
|
|
|
var wallPartLength = 0;
|
|
|
|
@ -563,13 +484,12 @@ function placeLinearWall(startX, startY, targetX, targetY, wallPart, style, play
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Place a circular wall of repeatant wall elements given in the argument wallPart arround centerX/centerY with the given radius
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// The wall is not necessarily closed depending on the optional argument maxAngle (better name?)
|
|
|
|
|
// NOTE: Don't use wall elements with bending like corners!
|
|
|
|
|
// Todo: add eccentricity
|
|
|
|
|
function placeCircularWall(centerX, centerY, radius, wallPart, style, playerId, orientation, maxAngle, endWithFirst, maxBendOff)
|
|
|
|
|
{
|
|
|
|
|
// Setup optional arguments to the default
|
|
|
|
@ -590,8 +510,12 @@ function placeCircularWall(centerX, centerY, radius, wallPart, style, playerId,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
maxBendOff = (maxBendOff || 0);
|
|
|
|
|
// Check arguments
|
|
|
|
|
if (maxBendOff > PI/2 || maxBendOff < 0)
|
|
|
|
|
warn('placeCircularWall maxBendOff sould satisfy 0 < maxBendOff < PI/2 (~1.5) but it is: ' + maxBendOff);
|
|
|
|
|
for (var elementIndex = 0; elementIndex < wallPart.length; elementIndex++)
|
|
|
|
|
if (wallStyles[style][wallPart[elementIndex]].bending != 0)
|
|
|
|
|
warn("Bending is not supported by placeCircularWall but a bending wall element is used: " + wallPart[elementIndex]);
|
|
|
|
|
// Setup number of wall parts
|
|
|
|
|
var totalLength = maxAngle * radius;
|
|
|
|
|
var wallPartLength = 0;
|
|
|
|
@ -652,3 +576,218 @@ function placeCircularWall(centerX, centerY, radius, wallPart, style, playerId,
|
|
|
|
|
placeObject(placeX, placeY, wallEle.entity, playerId, placeAngle + wallEle.angle);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Place a polygonal wall of repeatant wall elements given in the argument wallPart arround centerX/centerY with the given radius
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// NOTE: Don't use wall elements with bending like corners!
|
|
|
|
|
// TODO: Check some arguments
|
|
|
|
|
// TODO: Add eccentricity and irregularity (how far the corners can differ from a regulare convex poygon)
|
|
|
|
|
function placePolygonalWall(centerX, centerY, radius, wallPart, cornerWallElement, style, playerId, orientation, numCorners, skipFirstWall)
|
|
|
|
|
{
|
|
|
|
|
// Setup optional arguments to the default
|
|
|
|
|
wallPart = (wallPart || ['wall']);
|
|
|
|
|
cornerWallElement = (cornerWallElement || 'tower'); // Don't use wide elements for this. Not supported well...
|
|
|
|
|
style = (style || 'palisades');
|
|
|
|
|
playerId = (playerId || 0);
|
|
|
|
|
orientation = (orientation || 0);
|
|
|
|
|
numCorners = (numCorners || 8);
|
|
|
|
|
skipFirstWall = (skipFirstWall || false);
|
|
|
|
|
// Setup angles
|
|
|
|
|
var angleAdd = 2*PI/numCorners;
|
|
|
|
|
var angleStart = orientation - angleAdd/2;
|
|
|
|
|
// Setup corners
|
|
|
|
|
var corners = [];
|
|
|
|
|
for (var i = 0; i < numCorners; i++)
|
|
|
|
|
corners.push([centerX + radius*cos(angleStart + i*angleAdd), centerY + radius*sin(angleStart + i*angleAdd)]);
|
|
|
|
|
// Place Corners and walls
|
|
|
|
|
for (var i = 0; i < numCorners; i++)
|
|
|
|
|
{
|
|
|
|
|
var angleToCorner = getAngle(corners[i][0], corners[i][1], centerX, centerY);
|
|
|
|
|
placeObject(corners[i][0], corners[i][1], wallStyles[style][cornerWallElement].entity, playerId, angleToCorner);
|
|
|
|
|
if (!(skipFirstWall && i == 0))
|
|
|
|
|
{
|
|
|
|
|
placeLinearWall(
|
|
|
|
|
// Adjustment to the corner element width (approximately)
|
|
|
|
|
corners[i][0] + wallStyles[style][cornerWallElement].width/2 * sin(angleToCorner + angleAdd/2), // startX
|
|
|
|
|
corners[i][1] - wallStyles[style][cornerWallElement].width/2 * cos(angleToCorner + angleAdd/2), // startY
|
|
|
|
|
corners[(i+1)%numCorners][0] - wallStyles[style][cornerWallElement].width/2 * sin(angleToCorner + angleAdd/2), // targetX
|
|
|
|
|
corners[(i+1)%numCorners][1] + wallStyles[style][cornerWallElement].width/2 * cos(angleToCorner + angleAdd/2), // targetY
|
|
|
|
|
wallPart, style, playerId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Place an irregular polygonal wall of some wall parts to choose from arround centerX/centerY with the given radius
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// NOTE: Under construction!!!
|
|
|
|
|
// NOTE: wallPartList is put to the end because it's hardest to set
|
|
|
|
|
// NOTE: Don't use wall elements with bending like corners!
|
|
|
|
|
// TODO: Check some arguments
|
|
|
|
|
// TODO: Add eccentricity and irregularity (how far the corners can differ from a regulare convex poygon)
|
|
|
|
|
function placeIrregularPolygonalWall(centerX, centerY, radius, cornerWallElement, style, playerId, orientation, numCorners, irregularity, skipFirstWall, wallPartsAssortment)
|
|
|
|
|
{
|
|
|
|
|
// Generating a generic wall part assortment with each wall part including 1 gate enlengthend by walls and towers
|
|
|
|
|
// NOTE: It might be a good idea to write an own function for that...
|
|
|
|
|
var defaultWallPartsAssortment = [['wallShort'], ['wall'], ['wallLong'], ['gate', 'tower', 'wallShort']];
|
|
|
|
|
var centeredWallPart = ['gate']; // NOTE: Since gates are not functional yet entrys are used instead...
|
|
|
|
|
var extandingWallPartAssortment = [['tower', 'wallLong'], ['tower', 'wall']];
|
|
|
|
|
defaultWallPartsAssortment.push(centeredWallPart)
|
|
|
|
|
for (var i = 0; i < extandingWallPartAssortment.length; i++)
|
|
|
|
|
{
|
|
|
|
|
var wallPart = centeredWallPart;
|
|
|
|
|
for (var j = 0; j < radius; j++)
|
|
|
|
|
{
|
|
|
|
|
if (j%2 == 0)
|
|
|
|
|
wallPart = wallPart.concat(extandingWallPartAssortment[i]);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
extandingWallPartAssortment[i].reverse();
|
|
|
|
|
wallPart = extandingWallPartAssortment[i].concat(wallPart);
|
|
|
|
|
extandingWallPartAssortment[i].reverse();
|
|
|
|
|
}
|
|
|
|
|
defaultWallPartsAssortment.push(wallPart);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Setup optional arguments to the default
|
|
|
|
|
wallPartsAssortment = (wallPartsAssortment || defaultWallPartsAssortment);
|
|
|
|
|
cornerWallElement = (cornerWallElement || 'tower'); // Don't use wide elements for this. Not supported well...
|
|
|
|
|
style = (style || 'palisades');
|
|
|
|
|
playerId = (playerId || 0);
|
|
|
|
|
orientation = (orientation || 0);
|
|
|
|
|
numCorners = (numCorners || randInt(5, 7));
|
|
|
|
|
irregularity = (irregularity || 0.5);
|
|
|
|
|
skipFirstWall = (skipFirstWall || false);
|
|
|
|
|
// Setup angles
|
|
|
|
|
var angleToCover = 2*PI;
|
|
|
|
|
var angleAddList = [];
|
|
|
|
|
for (var i = 0; i < numCorners; i++)
|
|
|
|
|
{
|
|
|
|
|
// Randomize covered angles. Variety scales down with raising angle though...
|
|
|
|
|
angleAddList.push(angleToCover/(numCorners-i) * (1 + randFloat(-irregularity, irregularity)));
|
|
|
|
|
angleToCover -= angleAddList[angleAddList.length - 1];
|
|
|
|
|
}
|
|
|
|
|
// Setup corners
|
|
|
|
|
var corners = [];
|
|
|
|
|
var angleActual = orientation - angleAddList[0]/2;
|
|
|
|
|
for (var i = 0; i < numCorners; i++)
|
|
|
|
|
{
|
|
|
|
|
corners.push([centerX + radius*cos(angleActual), centerY + radius*sin(angleActual)]);
|
|
|
|
|
if (i < numCorners - 1)
|
|
|
|
|
angleActual += angleAddList[i+1]
|
|
|
|
|
}
|
|
|
|
|
// Setup best wall parts for the different walls (a bit confusing naming...)
|
|
|
|
|
var wallPartLengths = [];
|
|
|
|
|
var maxWallPartLength = 0;
|
|
|
|
|
for (var partIndex = 0; partIndex < wallPartsAssortment.length; partIndex++)
|
|
|
|
|
{
|
|
|
|
|
wallPartLengths.push(getWallLength(wallPartsAssortment[partIndex], style));
|
|
|
|
|
log("wallPartLengths = " + wallPartLengths);
|
|
|
|
|
if (wallPartLengths[partIndex] > maxWallPartLength)
|
|
|
|
|
maxWallPartLength = wallPartLengths[partIndex];
|
|
|
|
|
}
|
|
|
|
|
var wallPartList = []; // This is the list of the wall parts to use for the walls between the corners, not to confuse with wallPartsAssortment!
|
|
|
|
|
for (var i = 0; i < numCorners; i++)
|
|
|
|
|
{
|
|
|
|
|
var bestWallPart = []; // This is a simpel wall part not a wallPartsAssortment!
|
|
|
|
|
var bestWallLength = 99999999;
|
|
|
|
|
// NOTE: This is not exsactly like the length the wall will be in the end. Has to be tweeked...
|
|
|
|
|
var wallLength = getDistance(corners[i][0], corners[i][1], corners[(i+1)%numCorners][0], corners[(i+1)%numCorners][1])
|
|
|
|
|
var numWallParts = ceil(wallLength/maxWallPartLength);
|
|
|
|
|
log("numWallParts = " + numWallParts);
|
|
|
|
|
log("wallLength = " + wallLength);
|
|
|
|
|
for (var partIndex = 0; partIndex < wallPartsAssortment.length; partIndex++)
|
|
|
|
|
{
|
|
|
|
|
if (numWallParts*wallPartLengths[partIndex] < bestWallLength && numWallParts*wallPartLengths[partIndex] > wallLength)
|
|
|
|
|
{
|
|
|
|
|
bestWallPart = wallPartsAssortment[partIndex];
|
|
|
|
|
bestWallLength = numWallParts*wallPartLengths[partIndex];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
wallPartList.push(bestWallPart)
|
|
|
|
|
log("bestWallLength = " + bestWallLength);
|
|
|
|
|
log("bestWallPart = " + bestWallPart);
|
|
|
|
|
}
|
|
|
|
|
log("getWallLength(['wall', 'gate'], style) = " + getWallLength(['wall', 'gate'], style));
|
|
|
|
|
log("wallPartList = " + wallPartList);
|
|
|
|
|
// Place Corners and walls
|
|
|
|
|
for (var i = 0; i < numCorners; i++)
|
|
|
|
|
{
|
|
|
|
|
log("wallPartList[" + i + "] = " + wallPartList[i]);
|
|
|
|
|
var angleToCorner = getAngle(corners[i][0], corners[i][1], centerX, centerY);
|
|
|
|
|
placeObject(corners[i][0], corners[i][1], wallStyles[style][cornerWallElement].entity, playerId, angleToCorner);
|
|
|
|
|
if (!(skipFirstWall && i == 0))
|
|
|
|
|
{
|
|
|
|
|
placeLinearWall(
|
|
|
|
|
// Adjustment to the corner element width (approximately)
|
|
|
|
|
corners[i][0] + wallStyles[style][cornerWallElement].width/2 * sin(angleToCorner + angleAddList[i]/2), // startX
|
|
|
|
|
corners[i][1] - wallStyles[style][cornerWallElement].width/2 * cos(angleToCorner + angleAddList[i]/2), // startY
|
|
|
|
|
corners[(i+1)%numCorners][0] - wallStyles[style][cornerWallElement].width/2 * sin(angleToCorner + angleAddList[(i+1)%numCorners]/2), // targetX
|
|
|
|
|
corners[(i+1)%numCorners][1] + wallStyles[style][cornerWallElement].width/2 * cos(angleToCorner + angleAddList[(i+1)%numCorners]/2), // targetY
|
|
|
|
|
wallPartList[i], style, playerId, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Just a test function, USE WITH CARE!
|
|
|
|
|
// radius: A float seting the aproximate radius of the fortress
|
|
|
|
|
// maxBendOff: Optional, The maximum random bending offset of the wall elements NOTE: If maxBendOff > PI/2 the wall might never close!!!
|
|
|
|
|
// wallPart: Optional, An array of wall element string, example: ["tower", "wall"] NOTE: Don't use wall elements with bending!!!
|
|
|
|
|
function placeGenericFortress(centerX, centerY, radius, playerId, wallPart, style, maxBendOff)
|
|
|
|
|
{
|
|
|
|
|
if (wallPart == undefined)
|
|
|
|
|
wallPart = ['tower', 'wall', 'tower', 'entry', 'tower', 'wall'];
|
|
|
|
|
if (maxBendOff > PI/2 || maxBendOff < 0)
|
|
|
|
|
warn("setGenericFortress maxBendOff sould satisfy 0 < maxBendOff < PI/2 (~1.5) but it is: " + maxBendOff);
|
|
|
|
|
if (maxBendOff === undefined)
|
|
|
|
|
maxBendOff = 0;
|
|
|
|
|
var wallLength = 0;
|
|
|
|
|
for (var eleIndex = 0; eleIndex < wallPart.length; eleIndex++)
|
|
|
|
|
{
|
|
|
|
|
wallLength += wallStyles[style][wallPart[eleIndex]].width
|
|
|
|
|
}
|
|
|
|
|
if (wallLength > 2*PI*radius || wallLength <= 0)
|
|
|
|
|
warn("setGenericFortress: sum of the width of wall's elements should satisfy 0 < total length < 2*PI*radius but: radius = " + radius + ", wallPart = " + wallPart + " with total length of " + wallLength);
|
|
|
|
|
|
|
|
|
|
var minEleWidth = 1000000; // Assuming the smallest element is about as wide as deep.
|
|
|
|
|
for (var eleIndex = 0; eleIndex < wallPart.length; eleIndex++)
|
|
|
|
|
{
|
|
|
|
|
eleWidth = wallStyles[style][wallPart[eleIndex]].width;
|
|
|
|
|
if (eleWidth < minEleWidth)
|
|
|
|
|
minEleWidth = eleWidth;
|
|
|
|
|
}
|
|
|
|
|
var widthSafty = minEleWidth/4; // Can be done better...
|
|
|
|
|
|
|
|
|
|
var x = radius;
|
|
|
|
|
var y = 0;
|
|
|
|
|
var angle = 0;
|
|
|
|
|
var targetX = radius;
|
|
|
|
|
var targetY = 0;
|
|
|
|
|
var targetReached = false;
|
|
|
|
|
var eleIndex = 0;
|
|
|
|
|
while (targetReached == false)
|
|
|
|
|
{
|
|
|
|
|
var wallElement = wallStyles[style][wallPart[eleIndex % wallPart.length]];
|
|
|
|
|
var eleWidth = wallElement.width - widthSafty;
|
|
|
|
|
// Stabalized bendOff
|
|
|
|
|
var actualRadius = getDistance(centerX, centerY, centerX + x, centerY + y);
|
|
|
|
|
var bendOff = randFloat(-maxBendOff*radius/actualRadius, maxBendOff*actualRadius/radius);
|
|
|
|
|
// Element width in radians
|
|
|
|
|
var eleAngleWidth = eleWidth*cos(bendOff) / radius; // A/L = da/dl -> da = A * dl / L -> da = 2*PI * eleWidth / (2*PI * radius) -> da = eleWidth/radius
|
|
|
|
|
var eleAngle = angle + eleAngleWidth/2 + bendOff;
|
|
|
|
|
var placeX = x - eleWidth/2 * sin(eleAngle);
|
|
|
|
|
var placeY = y + eleWidth/2 * cos(eleAngle);
|
|
|
|
|
if (wallElement.entity)
|
|
|
|
|
placeObject(centerX + placeX, centerY + placeY, wallElement.entity, playerId, eleAngle + wallElement.angle);
|
|
|
|
|
x = placeX - eleWidth/2 * sin(eleAngle);
|
|
|
|
|
y = placeY + eleWidth/2 * cos(eleAngle);
|
|
|
|
|
angle += eleAngleWidth;
|
|
|
|
|
if (eleIndex % wallPart.length == 0 && eleIndex > wallPart.length && (getDistance(x, y, targetX, targetY) < wallLength || angle > 2*PI))
|
|
|
|
|
targetReached = true;
|
|
|
|
|
eleIndex++;
|
|
|
|
|
// if (eleIndex == 10)
|
|
|
|
|
// break;
|
|
|
|
|
}
|
|
|
|
|
placeLinearWall(centerX + x, centerY + y, centerX + targetX, centerY + targetY, ['wall', 'tower'], style, playerId, true);
|
|
|
|
|
}
|
|
|
|
|