Ticket #1449: rms_wall_pack2012-6-9.diff

File rms_wall_pack2012-6-9.diff, 60.9 KB (added by FeXoR, 12 years ago)

SVN diff file for all changes

  • data/mods/public/maps/random/fortress.js

     
    155155    createArea(placer,[new TerrainPainter(tRoad), paintClass(clPlayer)]);
    156156   
    157157    // Place custom fortress
    158     if (civ == "celt" || civ == "iber")
     158    if (civ == "brit" || civ == "celt" || civ == "gaul" || civ == "iber")
    159159    {
    160160        var wall = ['entryTower', 'wall', 'wall',
    161161            'cornerIn', 'wall', 'barracks', 'wall', 'gate', 'wall', 'house', 'wall',
  • data/mods/public/maps/random/rmgen/misc.js

     
    6868        }
    6969    }   
    7070}
     71
    7172//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    7273//rndRiver is a fuction that creates random values useful for making a jagged river.
    7374//
     
    193194        if (iberWall == 'towers')
    194195            placePolygonalWall(fx, fz, 15, ['entry'], 'tower', civ, playerid, angle, 7);
    195196        else
    196         {
    197             placeGenericFortress(fx, fz, 20/*radius*/, playerid, ['tower', 'wall', 'tower', 'entry', 'tower', 'wall'], civ, PI/6/*angle offset (0 to PI/4)*/)
    198         }
     197            placeGenericFortress(fx, fz, 20/*radius*/, playerid);
    199198    }
    200199}
    201200
  • data/mods/public/maps/random/rmgen/wall_builder.js

     
    33////////////////////////////////////////////////////////////////////
    44
    55// To do:
    6 // Rename wall elements to fit he entity names so that entity = 'structures/' + 'civ + '_' + wallElement.type in the common case
    7 // Add roman army camp to style palisades and add upgraded default palisade fortress types matching civ default fortresses
    8 // Add further wall elements cornerHalfIn, cornerHalfOut and adjust default fortress types to better fit in the octagonal territory of a civil center
    9 // Add civil center, corral, farmstead, field, market, mill, temple
     6// Check if all wall placement methods work with wall elements with entity === undefined
     7// Rename wall elements to fit he entity names so that entity = 'structures/' + 'civ + '_' + wallElement.type in the common case (as far as possible)
     8// Perhaps add roman army camp to style palisades and add upgraded default palisade fortress types matching civ default fortresses
     9// perhaps add further wall elements cornerHalfIn, cornerHalfOut and adjust default fortress types to better fit in the octagonal territory of a civil center
     10// Perhaps swap angle and width in WallElement class(?) definition
    1011// Adjust default fortress types
    11 // Add wall style 'roads'
    12 // Add trsures to 'others'
     12// Add trsures to wall style 'others'
    1313// Adjust documentation
    1414// ?Use available civ-type wall elements rather than palisades: Remove 'endLeft' and 'endRight' as default wall elements and adjust default palisade fortress types?
    1515// ?Remove endRight, endLeft and adjust generic fortress types palisades?
     
    1717// ?Readjust placement angle for wall elements with bending when used in linear/circular walls by their bending?
    1818
    1919
    20 ///////////////////////////////
    21 // WallElement class definition
    22 ///////////////////////////////
    23 
    24 // argument type: Descriptive string, example: 'wall'. NOTE: Not really needed. Mainly for custom wall elements and to get the wall element type in code.
    25 // argument entity: Optional. Template string to be placed, example: 'structures/cart_wall'. Default is undefined (No entity placed)
    26 // argument angle: Optional. Placement angle so that 'outside' is 'right' (towards positive X like a unit placed with angle 0). Default is 0 (0*PI)
    27 // argument width: Optional. The width it lengthens the wall, width because it's the needed space in a right angle to 'outside'. Default is 0
    28 // argument indent: Optional. The indentation means its drawn inside (positive values) or pushed outwards (negative values). Default is 0
    29 // NOTE: Bending is only used for fortresses and custom walls. Linear/circular walls walls use no/generic bending
    30 // argument bending: Optional. How the direction of the wall is changed after this element, positive is bending 'in' (counter clockwise like entity placement)
     20//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     21//  WallElement class definition
     22//
     23//  type: Descriptive string, example: 'wall'. NOTE: Not really needed. Mainly for custom wall elements and to get the wall element type in code.
     24//  entity: Optional. Template string to be placed, example: 'structures/cart_wall'. Default is undefined (No entity placed)
     25//  angle: Optional. Placement angle so that 'outside' is 'right' (towards positive X like a unit placed with angle 0). Default is 0 (0*PI)
     26//  width: Optional. The width it lengthens the wall, width because it's the needed space in a right angle to 'outside'. Default is 0
     27//  indent: Optional. The indentation means its drawn inside (positive values) or pushed outwards (negative values). Default is 0
     28//  bending: Optional. How the direction of the wall is changed after this element, positive is bending 'in' (counter clockwise like entity placement)
     29//
     30//  NOTE: Bending is only used for fortresses and custom walls. Linear/circular walls walls use no/generic bending
     31//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    3132function WallElement(type, entity, angle, width, indent, bending)
    3233{
    3334    // NOTE: Not all wall elements have a symetry. So there's an direction 'outside' (towards right/positive X by default)
     
    6465    this.bending = (bending !== undefined) ? bending : 0*PI;
    6566}
    6667
    67 
    68 ////////////////////////////
    69 // Fortress class definition
    70 ////////////////////////////
    71 
    72 // A list would do for symetric fortresses but if 'getCenter' don't do sufficient the center can be set manually
    73 // argument type: Descriptive string, example: 'tiny'. Not really needed (WallTool.wallTypes['type string'] is used). Mainly for custom wall elements.
    74 // argument wall: Optional. Array of wall element strings. Can be set afterwards. Default is an epty array.
    75     // Example: ['entrance', 'wall', 'cornerIn', 'wall', 'gate', 'wall', 'entrance', 'wall', 'cornerIn', 'wall', 'gate', 'wall', 'cornerIn', 'wall']
    76 // argument center: Optional. Array of 2 floats determinig the vector from the center to the 1st wall element. Can be set afterwards. Default is [0, 0]. (REALLY???)
    77     // NOTE: The center will be recalculated when WallTool.setFortress is called. To avoid this set WallTool.calculateCenter to false.
     68///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     69//  Fortress class definition
     70//
     71//  A list would do for symetric fortresses but if 'getCenter' don't do sufficient the center can be set manually
     72//
     73//  type: Descriptive string, example: 'tiny'. Not really needed (WallTool.wallTypes['type string'] is used). Mainly for custom wall elements.
     74//  wall: Optional. Array of wall element strings. Can be set afterwards. Default is an epty array.
     75//      Example: ['entrance', 'wall', 'cornerIn', 'wall', 'gate', 'wall', 'entrance', 'wall', 'cornerIn', 'wall', 'gate', 'wall', 'cornerIn', 'wall']
     76//  center: Optional. Array of 2 floats determinig the vector from the center to the 1st wall element. Can be set afterwards. Default is [0, 0]. (REALLY???)
     77//
     78//  NOTE: The center will be recalculated when WallTool.setFortress is called. To avoid this set WallTool.calculateCenter to false.
     79////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    7880function Fortress(type, wall, center)
    7981{
    8082    this.type = type; // Only usefull to get the type of the actual fortress (by 'WallTool.fortress.type')
     
    8385}
    8486
    8587
    86 ///////////////////////////////////////////////
    87 // Setup data structure for default wall styles
    88 ///////////////////////////////////////////////
    89 
    90 // A wall style is an associative array with all wall elements of that style in it associated with the wall element type string.
    91 // 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'...
     88////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     89//  wallStyles data structure for default wall styles
     90//
     91//  A wall style is an associative array with all wall elements of that style in it associated with the wall element type string
     92//  wallStyles holds all the wall styles within an associative array with the civ string or another descriptive strings as key
     93//  Examples: "athen", "rome_siege", "palisades", "fence", "road"
     94////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    9295var wallStyles = {};
    9396
    9497// Generic civ dependent wall style definition. 'rome_siege' needs some tweek...
    95 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};
    96 for (var style in scaleByCiv)
     98var wallScaleByType = {'athen' : 1.5, 'brit' : 1.5, 'cart' : 1.8, 'celt' : 1.5, 'gaul' : 1.5, 'hele' : 1.5, 'iber' : 1.5, 'mace' : 1.5, 'pers' : 1.5, 'rome' : 1.5, 'spart' : 1.5, 'rome_siege' : 1.5};
     99for (var style in wallScaleByType)
    97100{
    98101    var civ = style;
    99102    if (style == 'rome_siege')
    100103        civ = 'rome';
    101104    wallStyles[style] = {};
    102105    // Default wall elements
    103     wallStyles[style]['tower'] = new WallElement('tower', 'structures/' + style + '_wall_tower', PI, scaleByCiv[style]);
    104     wallStyles[style]['endLeft'] = new WallElement('endLeft', 'structures/' + style + '_wall_tower', PI, scaleByCiv[style]); // Same as tower. To be compatible with palisades...
    105     wallStyles[style]['endRight'] = new WallElement('endRight', 'structures/' + style + '_wall_tower', PI, scaleByCiv[style]); // Same as tower. To be compatible with palisades...
    106     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
    107     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
    108     wallStyles[style]['wallShort'] = new WallElement('wallShort', 'structures/' + style + '_wall_short', 0*PI, 2*scaleByCiv[style]);
    109     wallStyles[style]['wall'] = new WallElement('wall', 'structures/' + style + '_wall_medium', 0*PI, 4*scaleByCiv[style]);
    110     wallStyles[style]['wallLong'] = new WallElement('wallLong', 'structures/' + style + '_wall_long', 0*PI, 6*scaleByCiv[style]);
     106    wallStyles[style]['tower'] = new WallElement('tower', 'structures/' + style + '_wall_tower', PI, wallScaleByType[style]);
     107    wallStyles[style]['endLeft'] = new WallElement('endLeft', 'structures/' + style + '_wall_tower', PI, wallScaleByType[style]); // Same as tower. To be compatible with palisades...
     108    wallStyles[style]['endRight'] = new WallElement('endRight', 'structures/' + style + '_wall_tower', PI, wallScaleByType[style]); // Same as tower. To be compatible with palisades...
     109    wallStyles[style]['cornerIn'] = new WallElement('cornerIn', 'structures/' + style + '_wall_tower', 5*PI/4, 0, 0.35*wallScaleByType[style], PI/2); // 2^0.5 / 4 ~= 0.35 ~= 1/3
     110    wallStyles[style]['cornerOut'] = new WallElement('cornerOut', 'structures/' + style + '_wall_tower', 3*PI/4, 0.71*wallScaleByType[style], 0, -PI/2); // // 2^0.5 / 2 ~= 0.71 ~= 2/3
     111    wallStyles[style]['wallShort'] = new WallElement('wallShort', 'structures/' + style + '_wall_short', 0*PI, 2*wallScaleByType[style]);
     112    wallStyles[style]['wall'] = new WallElement('wall', 'structures/' + style + '_wall_medium', 0*PI, 4*wallScaleByType[style]);
     113    wallStyles[style]['wallMedium'] = new WallElement('wall', 'structures/' + style + '_wall_medium', 0*PI, 4*wallScaleByType[style]);
     114    wallStyles[style]['wallLong'] = new WallElement('wallLong', 'structures/' + style + '_wall_long', 0*PI, 6*wallScaleByType[style]);
    111115    // Gate and entrance wall elements
    112116    if (style == 'cart')
    113         var gateWidth = 3.5*scaleByCiv[style];
    114     else if (style == 'celt')
    115         var gateWidth = 4*scaleByCiv[style];
     117        var gateWidth = 3.5*wallScaleByType[style];
     118    else if (style == "brit" || style == "celt" || style == "gaul")
     119        var gateWidth = 4*wallScaleByType[style];
    116120    // else if (style == 'iber')
    117         // var gateWidth = 5.5*scaleByCiv[style];
     121        // var gateWidth = 5.5*wallScaleByType[style];
    118122    else
    119         var gateWidth = 6*scaleByCiv[style];
     123        var gateWidth = 6*wallScaleByType[style];
    120124    wallStyles[style]['gate'] = new WallElement('gate', 'structures/' + style + '_wall_gate', 0*PI, gateWidth);
    121125    wallStyles[style]['entry'] = new WallElement('entry', undefined, 0*PI, gateWidth);
    122     if (civ == 'iber') // Adjust iberians to have no upkeep at entries with a tower for convinience ATM, may be changed
    123         wallStyles[style]['entryTower'] = new WallElement('entryTower', 'structures/' + civ + '_wall_tower', PI, gateWidth, -4*scaleByCiv[style]);
    124     else
    125         wallStyles[style]['entryTower'] = new WallElement('entryTower', 'structures/' + civ + '_defense_tower', PI, gateWidth, -4*scaleByCiv[style]);
    126     wallStyles[style]['entryFort'] = new WallElement('entryFort', 'structures/' + civ + '_fortress', 0*PI, 8*scaleByCiv[style], 6*scaleByCiv[style]);
     126    wallStyles[style]['entryTower'] = new WallElement('entryTower', 'structures/' + civ + '_defense_tower', PI, gateWidth, -4*wallScaleByType[style]);
     127    wallStyles[style]['entryFort'] = new WallElement('entryFort', 'structures/' + civ + '_fortress', 0*PI, 8*wallScaleByType[style], 6*wallScaleByType[style]);
    127128    // Defensive wall elements with 0 width outside the wall
    128     wallStyles[style]['outpost'] = new WallElement('outpost', 'structures/' + civ + '_outpost', PI, 0, -4*scaleByCiv[style]);
    129     wallStyles[style]['defenseTower'] = new WallElement('defenseTower', 'structures/' + civ + '_defenseTower', PI, 0, -4*scaleByCiv[style]);
     129    wallStyles[style]['outpost'] = new WallElement('outpost', 'structures/' + civ + '_outpost', PI, 0, -4*wallScaleByType[style]);
     130    wallStyles[style]['defenseTower'] = new WallElement('defenseTower', 'structures/' + civ + '_defenseTower', PI, 0, -4*wallScaleByType[style]);
    130131    // Base buildings wall elements with 0 width inside the wall
    131     wallStyles[style]['barracks'] = new WallElement('barracks', 'structures/' + civ + '_barracks', PI, 0, 4.5*scaleByCiv[style]);
    132     wallStyles[style]['civilCentre'] = new WallElement('civilCentre', 'structures/' + civ + '_civil_centre', PI, 0, 4.5*scaleByCiv[style]);
    133     wallStyles[style]['farmstead'] = new WallElement('farmstead', 'structures/' + civ + '_farmstead', PI, 0, 4.5*scaleByCiv[style]);
    134     wallStyles[style]['field'] = new WallElement('field', 'structures/' + civ + '_field', PI, 0, 4.5*scaleByCiv[style]);
    135     wallStyles[style]['fortress'] = new WallElement('fortress', 'structures/' + civ + '_fortress', PI, 0, 4.5*scaleByCiv[style]);
    136     wallStyles[style]['house'] = new WallElement('house', 'structures/' + civ + '_house', PI, 0, 4.5*scaleByCiv[style]);
    137     wallStyles[style]['market'] = new WallElement('market', 'structures/' + civ + '_market', PI, 0, 4.5*scaleByCiv[style]);
    138     wallStyles[style]['mill'] = new WallElement('mill', 'structures/' + civ + '_mill', PI, 0, 4.5*scaleByCiv[style]);
    139     wallStyles[style]['temple'] = new WallElement('temple', 'structures/' + civ + '_temple', PI, 0, 4.5*scaleByCiv[style]);
     132    wallStyles[style]['barracks'] = new WallElement('barracks', 'structures/' + civ + '_barracks', PI, 0, 4.5*wallScaleByType[style]);
     133    wallStyles[style]['civilCentre'] = new WallElement('civilCentre', 'structures/' + civ + '_civil_centre', PI, 0, 4.5*wallScaleByType[style]);
     134    wallStyles[style]['farmstead'] = new WallElement('farmstead', 'structures/' + civ + '_farmstead', PI, 0, 4.5*wallScaleByType[style]);
     135    wallStyles[style]['field'] = new WallElement('field', 'structures/' + civ + '_field', PI, 0, 4.5*wallScaleByType[style]);
     136    wallStyles[style]['fortress'] = new WallElement('fortress', 'structures/' + civ + '_fortress', PI, 0, 4.5*wallScaleByType[style]);
     137    wallStyles[style]['house'] = new WallElement('house', 'structures/' + civ + '_house', PI, 0, 4.5*wallScaleByType[style]);
     138    wallStyles[style]['market'] = new WallElement('market', 'structures/' + civ + '_market', PI, 0, 4.5*wallScaleByType[style]);
     139    wallStyles[style]['mill'] = new WallElement('mill', 'structures/' + civ + '_mill', PI, 0, 4.5*wallScaleByType[style]);
     140    wallStyles[style]['temple'] = new WallElement('temple', 'structures/' + civ + '_temple', PI, 0, 4.5*wallScaleByType[style]);
    140141    // Generic space/gap wall elements
    141     wallStyles[style]['space1'] = new WallElement('space1', undefined, 0*PI, scaleByCiv[style]);
    142     wallStyles[style]['space2'] = new WallElement('space2', undefined, 0*PI, 2*scaleByCiv[style]);
    143     wallStyles[style]['space3'] = new WallElement('space3', undefined, 0*PI, 3*scaleByCiv[style]);
    144     wallStyles[style]['space4'] = new WallElement('space4', undefined, 0*PI, 4*scaleByCiv[style]);
     142    wallStyles[style]['space1'] = new WallElement('space1', undefined, 0*PI, wallScaleByType[style]);
     143    wallStyles[style]['space2'] = new WallElement('space2', undefined, 0*PI, 2*wallScaleByType[style]);
     144    wallStyles[style]['space3'] = new WallElement('space3', undefined, 0*PI, 3*wallScaleByType[style]);
     145    wallStyles[style]['space4'] = new WallElement('space4', undefined, 0*PI, 4*wallScaleByType[style]);
    145146}
    146 
    147147// Add wall fortresses for all generic styles
    148148wallStyles['athen']['wallFort'] = new WallElement('wallFort', 'structures/athen_fortress', 2*PI/2 /* PI/2 */, 5.1 /* 5.6 */, 1.9 /* 1.9 */);
     149wallStyles['brit']['wallFort'] = new WallElement('wallFort', 'structures/brit_fortress', PI, 2.8);
    149150wallStyles['cart']['wallFort'] = new WallElement('wallFort', 'structures/cart_fortress', PI, 5.1, 1.6);
    150151wallStyles['celt']['wallFort'] = new WallElement('wallFort', 'structures/celt_fortress_g', PI, 4.2, 1.5);
     152wallStyles['gaul']['wallFort'] = new WallElement('wallFort', 'structures/gaul_fortress', PI, 4.2, 1.5);
    151153wallStyles['hele']['wallFort'] = new WallElement('wallFort', 'structures/hele_fortress', 2*PI/2 /* PI/2 */, 5.1 /* 5.6 */, 1.9 /* 1.9 */);
    152154wallStyles['iber']['wallFort'] = new WallElement('wallFort', 'structures/iber_fortress', PI, 5, 0.2);
    153155wallStyles['mace']['wallFort'] = new WallElement('wallFort', 'structures/mace_fortress', 2*PI/2 /* PI/2 */, 5.1 /* 5.6 */, 1.9 /* 1.9 */);
     
    158160wallStyles['rome_siege']['wallFort'] = new WallElement('wallFort', 'structures/rome_army_camp', PI, 7.2, 2);
    159161wallStyles['rome_siege']['entryFort'] = new WallElement('entryFort', 'structures/rome_army_camp', PI, 12, 7);
    160162wallStyles['rome_siege']['house'] = new WallElement('house', 'structures/rome_tent', PI, 0, 4);
     163// Add pseudo "theb" wall style (No actual entities available)
     164wallStyles["theb"] = deepcopy(wallStyles["hele"]);
    161165
    162166// Add special wall styles not well to implement generic (and to show how custom styles can be added)
    163167
    164 // Add special wall style 'palisades'
     168// Add wall style 'palisades'
     169wallScaleByType['palisades'] = 0.55;
    165170wallStyles['palisades'] = {};
    166171wallStyles['palisades']['wall'] = new WallElement('wall', 'other/palisades_rocks_medium', 0*PI, 2.3);
     172wallStyles['palisades']['wallMedium'] = new WallElement('wall', 'other/palisades_rocks_medium', 0*PI, 2.3);
    167173wallStyles['palisades']['wallLong'] = new WallElement('wall', 'other/palisades_rocks_long', 0*PI, 3.5);
    168174wallStyles['palisades']['wallShort'] = new WallElement('wall', 'other/palisades_rocks_short', 0*PI, 1.2);
    169175wallStyles['palisades']['tower'] = new WallElement('tower', 'other/palisades_rocks_tower', -PI/2, 0.7);
    170176wallStyles['palisades']['wallFort'] = new WallElement('wallFort', 'other/palisades_rocks_fort', PI, 1.7);
    171 wallStyles['palisades']['gate'] = new WallElement('gate', 'other/palisades_rocks_gate', 0*PI, 3.6);
     177wallStyles['palisades']['gate'] = new WallElement('gate', 'other/palisades_rocks_gate', PI, 3.6);
    172178wallStyles['palisades']['entry'] = new WallElement('entry', undefined, wallStyles['palisades']['gate'].angle, wallStyles['palisades']['gate'].width);
    173179wallStyles['palisades']['entryTower'] = new WallElement('entryTower', 'other/palisades_rocks_watchtower', 0*PI, wallStyles['palisades']['gate'].width, -3);
    174180wallStyles['palisades']['entryFort'] = new WallElement('entryFort', 'other/palisades_rocks_fort', PI, 6, 3);
     
    181187wallStyles['palisades']['endLeft'] = new WallElement('endLeft', 'other/palisades_rocks_end', PI/2, 0.2);
    182188
    183189// Add special wall style 'road'
     190// NOTE: This is not a wall style in the common sense. Use with care!
     191wallStyles['road'] = {};
     192wallStyles['road']['short'] = new WallElement('road', "actor|props/special/eyecandy/road_temperate_short.xml", PI/2, 4.5);
     193wallStyles['road']['long'] = new WallElement('road', "actor|props/special/eyecandy/road_temperate_long.xml", PI/2, 9.5);
     194wallStyles['road']['cornerLeft'] = new WallElement('road', "actor|props/special/eyecandy/road_temperate_corner.xml", -PI/2, 4.5-2*1.25, 1.25, PI/2); // Correct width by -2*indent to fit xStraicht/corner
     195wallStyles['road']['cornerRight'] = new WallElement('road', "actor|props/special/eyecandy/road_temperate_corner.xml", 0*PI, 4.5-2*1.25, -1.25, -PI/2); // Correct width by -2*indent to fit xStraicht/corner
     196wallStyles['road']['curveLeft'] = new WallElement('road', "actor|props/special/eyecandy/road_temperate_curve_small.xml", -PI/2, 4.5+2*0.2, -0.2, PI/2); // Correct width by -2*indent to fit xStraicht/corner
     197wallStyles['road']['curveRight'] = new WallElement('road', "actor|props/special/eyecandy/road_temperate_curve_small.xml", 0*PI, 4.5+2*0.2, 0.2, -PI/2); // Correct width by -2*indent to fit xStraicht/corner
     198wallStyles['road']['start'] = new WallElement('road', "actor|props/special/eyecandy/road_temperate_end.xml", PI/2, 2);
     199wallStyles['road']['end'] = new WallElement('road', "actor|props/special/eyecandy/road_temperate_end.xml", -PI/2, 2);
     200wallStyles['road']['xStraight'] = new WallElement('road', "actor|props/special/eyecandy/road_temperate_intersect_x.xml", 0*PI, 4.5);
     201wallStyles['road']['xLeft'] = new WallElement('road', "actor|props/special/eyecandy/road_temperate_intersect_x.xml", 0*PI, 4.5, 0, PI/2);
     202wallStyles['road']['xRight'] = new WallElement('road', "actor|props/special/eyecandy/road_temperate_intersect_x.xml", 0*PI, 4.5, 0, -PI/2);
     203wallStyles['road']['tLeft'] = new WallElement('road', "actor|props/special/eyecandy/road_temperate_intersect_T.xml", PI, 4.5, 1.25);
     204wallStyles['road']['tRight'] = new WallElement('road', "actor|props/special/eyecandy/road_temperate_intersect_T.xml", 0*PI, 4.5, -1.25);
    184205
    185206// Add special wall element collection 'other'
    186207// NOTE: This is not a wall style in the common sense. Use with care!
    187208wallStyles['other'] = {};
    188209wallStyles['other']['fence'] = new WallElement('fence', 'other/fence_long', -PI/2, 3.1);
     210wallStyles['other']['fence_medium'] = new WallElement('fence', 'other/fence_long', -PI/2, 3.1);
    189211wallStyles['other']['fence_short'] = new WallElement('fence_short', 'other/fence_short', -PI/2, 1.5);
    190212wallStyles['other']['fence_stone'] = new WallElement('fence_stone', 'other/fence_stone', -PI/2, 2.5);
    191213wallStyles['other']['palisade'] = new WallElement('palisade', 'other/palisades_rocks_short', 0, 1.2);
     
    206228wallStyles['other']['cornerOut'] = new WallElement('cornerOut', undefined, 0, 0, 0, -PI/2);
    207229
    208230
    209 ///////////////////////////////////////////////////////
    210 // Setup data structure for some default fortress types
    211 ///////////////////////////////////////////////////////
    212 
    213 // A fortress type is just an instance of the fortress class with actually something in it.
    214 // fortressTypes holds all the fortressess within an associative array while a fortress is associated with a descriptive string maching the map sizes, example: 'tiny', 'giant'
     231////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     232//  fortressTypes data structure for some default fortress types
     233//
     234//  A fortress type is just an instance of the fortress class with actually something in it
     235//  fortressTypes holds all the fortressess within an associative array with a descriptive string as key (e.g. maching the map size)
     236//  Eexamples: "tiny', "veryLarge"
     237////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    215238var fortressTypes = {};
    216239// Setup some default fortress types
    217240// Add fortress type 'tiny'
     
    248271    'cornerOut', 'wall', 'outpost', 'wall', 'cornerIn', 'wall', 'outpost', 'wall', 'endRight'];
    249272fortressTypes['giant'].wall = wallPart.concat(wallPart, wallPart, wallPart);
    250273
    251 // Add (some) iberian civ bonus fortress (The civ can still be set, just an uncommon default fortress)
    252 var wall = ['gate', 'tower', 'wall', 'cornerIn', 'wallLong', 'tower',
    253     'gate', 'tower', 'wallLong', 'cornerIn', 'wall', 'tower',
    254     'gate', 'wall', 'cornerIn', 'wall', 'cornerOut', 'wall', 'cornerIn', 'wallLong', 'tower',
    255     'gate', 'tower', 'wallLong', 'cornerIn', 'wall', 'tower', 'wall', 'cornerIn', 'wall'];
    256 fortressTypes['iberCivBonus'] = new Fortress('iberCivBonus', wall);
    257 var wall = ['gate', 'tower', 'wall', 'cornerIn', 'wall', 'cornerOut', 'wall', 'cornerIn', 'wallLong', 'tower',
    258     'gate', 'tower', 'wallLong', 'cornerIn', 'wall', 'tower', 'wall', 'cornerIn', 'wall', 'cornerOut',
    259     'gate', 'tower', 'wall', 'cornerIn', 'wallLong', 'tower',
    260     'gate', 'tower', 'wallLong', 'cornerIn', 'wall', 'tower'];
    261 fortressTypes['iberCivBonus2'] = new Fortress('iberCivBonus2', wall);
    262 var wall = ['gate', 'tower', 'wall', 'cornerOut', 'wallShort', 'cornerIn', 'wall', 'cornerIn', 'wallLong', 'cornerIn', 'wallShort', 'cornerOut', 'wall', 'tower',
    263     'gate', 'tower', 'wallLong', 'cornerIn', 'wallLong', 'cornerIn', 'wallShort', 'cornerOut',
    264     'gate', 'tower', 'wall', 'cornerIn', 'wall', 'cornerOut', 'wallShort', 'cornerIn', 'wall', 'tower',
    265     'gate', 'tower', 'wallShort', 'cornerIn', 'wall', 'tower', 'wallShort', 'tower'];
    266 fortressTypes['iberCivBonus3'] = new Fortress('iberCivBonus3', wall);
    267 
    268 
    269274// Setup some semi default fortresses for 'palisades' style
    270275var fortressTypeKeys = ['tiny', 'small', 'medium', 'normal', 'large', 'veryLarge', 'giant'];
    271276for (var i = 0; i < fortressTypeKeys.length; i++)
     
    276281    var fillTowersBetween = ['wall', 'endLeft', 'endRight', 'cornerIn', 'cornerOut'];
    277282    for (var j = 0; j < oldWall.length; j++)
    278283    {
    279         fortressTypes[newKey].wall.push(oldWall[j]); // Only works if the first element is an entry or gate (not in fillTowersBetween)
     284        fortressTypes[newKey].wall.push(oldWall[j]); // Only works if the first element is not in fillTowersBetween (e.g. entry or gate like it should be)
    280285        if (j+1 < oldWall.length)
    281286            if (fillTowersBetween.indexOf(oldWall[j]) > -1 && fillTowersBetween.indexOf(oldWall[j+1]) > -1) // ... > -1 means 'exists' here
    282287                fortressTypes[newKey].wall.push('tower');
    283288    }
    284289}
    285290
     291// Add some "fortress types" for roads (will only work with style "road")
     292// ["start", "short", "xRight", "xLeft", "cornerLeft", "xStraight", "long", "xLeft", "xRight", "cornerRight", "tRight", "tLeft", "xRight", "xLeft", "curveLeft", "xStraight", "curveRight", "end"];
     293var wall = ["short", "curveLeft", "short", "curveLeft", "short", "curveLeft", "short", "curveLeft"];
     294fortressTypes['road01'] = new Fortress('road01', wall);
     295var wall = ["short", "cornerLeft", "short", "cornerLeft", "short", "cornerLeft", "short", "cornerLeft"];
     296fortressTypes['road02'] = new Fortress('road02', wall);
     297var wall = ["xStraight", "curveLeft", "xStraight", "curveLeft", "xStraight", "curveLeft", "xStraight", "curveLeft"];
     298fortressTypes['road03'] = new Fortress('road03', wall);
     299var wall = ["start", "curveLeft", "tRight", "cornerLeft", "tRight", "curveRight", "short", "xRight", "curveLeft", "xRight", "short", "cornerLeft", "tRight", "short",
     300    "curveLeft", "short", "tRight", "cornerLeft", "short", "xRight", "curveLeft", "xRight", "short", "curveRight", "tRight", "cornerLeft", "tRight", "curveLeft", "end"];
     301fortressTypes['road04'] = new Fortress('road04', wall);
     302var wall = ["start", "tLeft", "short", "xRight",
     303    "curveLeft", "xRight", "tRight", "cornerLeft", "tRight",
     304    "curveLeft", "short", "tRight", "cornerLeft", "xRight",
     305    "cornerLeft", "xRight", "short", "tRight", "curveLeft", "end"];
     306fortressTypes['road05'] = new Fortress('road05', wall);
    286307
    287 ///////////////////////////////////////////////////////////////////////////////
    288 // Define some helper functions: getWallAlignment, getWallCenter, getWallLength
    289 ///////////////////////////////////////////////////////////////////////////////
    290308
    291 // Get alignment of a wall
    292 // Returns a list of lists of most arguments needed to place the different wall elements for a given wall
    293 // Placing the first wall element at startX/startY placed with angle given by orientation
    294 // An alignement can be used to get the center of a 'wall' (more likely used for closed walls like fortresses) with the getWallCenter function
     309///////////////////////////////
     310// Define some helper functions
     311///////////////////////////////
     312
     313/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     314//  getWallAlignment
     315//
     316//  Returns a list of lists of most arguments needed to place the different wall elements for a given wall
     317//  Placing the first wall element at startX/startY placed with angle given by orientation
     318//  An alignement can be used to get the center of a 'wall' (more likely used for fortresses) with the getWallCenter function
     319/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    295320function getWallAlignment(startX, startY, wall, style, orientation)
    296321{
    297     orientation = (orientation !== undefined) ? orientation : 0*PI;
    298     var alignment = []
     322    orientation = (orientation || 0*PI);
     323    var alignment = [];
    299324    var wallX = startX;
    300325    var wallY = startY;
    301326    for (var i = 0; i < wall.length; i++)
     
    325350                wallX += element.indent * cos(orientation);
    326351                wallY += element.indent * sin(orientation);
    327352            }
    328             // Set the next coordinates of the next element in the wall (meaning without indentation adjustment)
     353            // Set the next coordinates of the next element in the wall without indentation adjustment
    329354            wallX -= distance * sin(orientation);
    330355            wallY += distance * cos(orientation);
    331356        }
     
    333358    return alignment;
    334359}
    335360
    336 // Get the center of a wall (mainly usefull for closed walls like fortresses)
    337 // Center calculation works like getting the center of mass assuming all wall elements have the same 'waight'
    338 // It returns the vector (array [x, y]) from the first wall element to the center
     361//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     362//  getWallCenter
     363//
     364//  Center calculation works like getting the center of mass assuming all wall elements have the same 'waight'
     365//  It returns the vector (array [x, y]) from the first wall element to the center
     366//  Used to get the center of fortresses by default
     367//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    339368function getWallCenter(alignment)
    340369{
    341370    var x = 0;
     
    349378    return center;
    350379}
    351380
    352 // Get the length of a wall used by placeIrregularPolygonalWall
    353 // NOTE: Does not support bending wall elements like corners!
     381//////////////////////////////////////////////////////////////////
     382//  getWallLength
     383//
     384//  NOTE: Does not support bending wall elements like corners!
     385//  e.g. used by placeIrregularPolygonalWall
     386//////////////////////////////////////////////////////////////////
    354387function getWallLength(wall, style)
    355388{
    356389    var length = 0;
     
    366399// Define the different wall placer functions
    367400/////////////////////////////////////////////
    368401
    369 /////////////////////////////////////////////////////////////////////////////////
    370 // Place simple wall starting with the first wall element placed at startX/startY
    371 /////////////////////////////////////////////////////////////////////////////////
    372 // orientation: 0 means 'outside' or 'front' of the wall is right (positive X) like placeObject
    373 // It will then be build towards top (positive Y) if no bending wall elements like corners are used
    374 // Raising orientation means the wall is rotated counter-clockwise like placeObject
     402/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     403//  placeWall
     404//
     405//  Places a wall with wall elements attached to another like determined by WallElement properties.
     406//
     407//  startX, startY  Where the first wall element should be placed
     408//  wall            Array of wall element type strings. Example: ["endLeft", "wallLong", "tower", "wallLong", "endRight"]
     409//  style           Optional. Wall style string. Default is the civ of the given player, "palisades" for gaia
     410//  playerId        Optional. Number of the player the wall will be placed for. Default is 0 (gaia)
     411//  orientation     Optional. Angle the first wall element is placed. Default is 0
     412//                  0 means 'outside' or 'front' of the wall is right (positive X) like placeObject
     413//                  It will then be build towards top/positive Y (if no bending wall elements like corners are used)
     414//                  Raising orientation means the wall is rotated counter-clockwise like placeObject
     415/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    375416function placeWall(startX, startY, wall, style, playerId, orientation)
    376417{
     418    // Setup optional arguments
     419    playerId = (playerId || 0);
     420    if (playerId == 0)
     421        style = (style || "palisades");
     422    else
     423        style = (style || g_MapSettings.PlayerData[playerId-1].Civ);
     424    orientation = (orientation || 0);
     425    // Get wall alignment
    377426    var AM = getWallAlignment(startX, startY, wall, style, orientation);
     427    // Place the wall
    378428    for (var iWall = 0; iWall < wall.length; iWall++)
    379429    {
    380430        if (AM[iWall][2] !== undefined)
     
    382432    }
    383433}
    384434
    385 //////////////////////////////////////////////////////////////////////////////////////////////////
    386 // Place a fortress (mainly a closed wall build like placeWall) with the center at centerX/centerY
    387 //////////////////////////////////////////////////////////////////////////////////////////////////
    388 // Should always start with the main entrance (like 'entry' or 'gate') to get the orientation right (like placeObject)
     435/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     436//  placeCustomFortress
     437//
     438//  Place a fortress (mainly a closed wall build like placeWall) centered at centerX/centerY (if scipGetCenter is not set otherwise)
     439//  The fortress wall should always start with the main entrance (like 'entry' or 'gate') to get the orientation right (like placeObject)
     440//
     441//  fortress       An instance of Fortress with a wall defined
     442//  style          Optional. Wall style string. Default is the civ of the given player, "palisades" for gaia
     443//  playerId       Optional. Number of the player the wall will be placed for. Default is 0 (gaia)
     444//  orientation    Optional. Angle the first wall element (should be a gate or entrance) is placed. Default is 0
     445//  scipGetCenter  Optional. If true it places the first wall element at centerX/centerY. Default is false
     446/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    389447function placeCustomFortress(centerX, centerY, fortress, style, playerId, orientation, scipGetCenter)
    390448{
     449    // Setup optional arguments
     450    fortress = (fortress || fortressTypes["tiny"]);
     451    playerId = (playerId || 0);
     452    if (playerId == 0)
     453        style = (style || "palisades");
     454    else
     455        style = (style || g_MapSettings.PlayerData[playerId-1].Civ);
     456    orientation = (orientation || 0);
     457    scipGetCenter = (scipGetCenter || false);
     458    // Place centered fortress if scipGetCenter == false/0/undefined/... (default)
    391459    if (!scipGetCenter)
    392460    {
    393461        var alignment = getWallAlignment(0, 0, fortress.wall, style);
     
    395463        var startX = centerX - center[0] * cos(orientation) + center[1] * sin(orientation);
    396464        var startY = centerY - center[1] * cos(orientation) - center[0] * sin(orientation);
    397465    }
     466    // Place fortress with the first wall element placed at centerX/centerY if scipGetCenter == true in any way
    398467    else
    399468    {
    400469        var startX = centerX + fortress.center[0];
     
    403472    placeWall(startX, startY, fortress.wall, style, playerId, orientation)
    404473}
    405474
     475///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     476//  placeFortress
     477//
     478//  Like placeCustomFortress just it takes type (a fortress type string, has to be in fortressTypes) instead of an instance of Fortress
     479///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    406480function placeFortress(centerX, centerY, type, style, playerId, orientation, scipGetCenter)
    407481{
     482    // Setup optional arguments
     483    type = (type || "tiny");
     484    playerId = (playerId || 0);
     485    if (playerId == 0)
     486        style = (style || "palisades");
     487    else
     488        style = (style || g_MapSettings.PlayerData[playerId-1].Civ);
     489    orientation = (orientation || 0);
     490    scipGetCenter = (scipGetCenter || false);
     491    // Call placeCustomFortress with the given arguments
    408492    placeCustomFortress(centerX, centerY, fortressTypes[type], style, playerId, orientation, scipGetCenter);
    409493}
    410494
    411 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    412 // Place a linear wall of repeatant wall elements given in the argument wallPart from startX/startY to targetX/targetY
    413 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    414 // startX: x coordinate of the beginning of the wall
    415 // startY: y coordinate of the beginning of the wall
    416 // targetX: x coordinate of the ending of the wall
    417 // targetY: y coordinate of the ending of the wall
    418 // NOTE: Start and target coordinates are exact (besides the scale offset) meaning the wall will begin/end at the given coordinates (not the first/last entity is placed there)
    419 // wallPart: Optional. An array of wall element type strings (see WallElement.type). Default is ['wall']
    420 // NOTE: Don't use wall elements with bending like corners!
    421 // style: Optional. An wall style string (like defined in the 'wallStyles' dictionary). Default is 'palisades'
    422 // playerId: Optional. The walls owners player ID (like in the function 'placeObject' so 0 is gaia, 1 is the first player), Default is 0 (gaia)
    423 // endWithFirst: Optional. A boolean value. If true the 1st wall element in the wallPart array will finalize the wall. Default is true
     495//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     496//  placeLinearWall
     497//
     498//  Places a straight wall from a given coordinate to an other repeatant using the wall parts.
     499//
     500//  startX/startY    Coordinate of the approximate beginning of the wall (Not the place of the first wall element)
     501//  targetX/targetY  Coordinate of the approximate ending of the wall (Not the place of the last wall element)
     502//  wallPart         Optional. An array of NON-BENDING wall element type strings. Default is ["tower", "wallLong"]
     503//  style            Optional. Wall style string. Default is the civ of the given player, "palisades" for gaia
     504//  playerId         Optional. Integer number of the player. Default is 0 (gaia)
     505//  endWithFirst     Optional. A boolean value. If true the 1st wall element in the wallPart array will finalize the wall. Default is true
     506//
     507//  TODO: Maybe add angle offset for more generic looking?
     508//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    424509function placeLinearWall(startX, startY, targetX, targetY, wallPart, style, playerId, endWithFirst)
    425510{
    426511    // Setup optional arguments to the default
    427     wallPart = (wallPart || ['wall']);
    428     style = (style || 'palisades');
     512    wallPart = (wallPart || ["tower", "wallLong"]);
    429513    playerId = (playerId || 0);
    430     // endWithFirst = (endWithFirst || true);
     514    if (playerId == 0)
     515        style = (style || "palisades");
     516    else
     517        style = (style || g_MapSettings.PlayerData[playerId-1].Civ);
    431518    endWithFirst = typeof endWithFirst == 'undefined' ? true : endWithFirst;
    432519    // Check arguments
    433520    for (var elementIndex = 0; elementIndex < wallPart.length; elementIndex++)
     
    483570    }
    484571}
    485572
    486 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    487 // Place a circular wall of repeatant wall elements given in the argument wallPart arround centerX/centerY with the given radius
    488 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    489 // The wall is not necessarily closed depending on the optional argument maxAngle (better name?)
    490 // NOTE: Don't use wall elements with bending like corners!
    491 // Todo: add eccentricity
     573/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     574//  placeCircularWall
     575//
     576//  Place a circular wall of repeatant wall elements given in the argument wallPart arround centerX/centerY with the given radius
     577//
     578//  The wall is not necessarily closed depending on the optional argument maxAngle (better name?)
     579//  NOTE: Don't use wall elements with bending like corners!
     580//  TODO: Perhaps add eccentricity and maxBendOff functionality (untill now an unused argument)
     581/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    492582function placeCircularWall(centerX, centerY, radius, wallPart, style, playerId, orientation, maxAngle, endWithFirst, maxBendOff)
    493583{
    494584    // Setup optional arguments to the default
    495585    wallPart = (wallPart || ['wall']);
    496     style = (style || 'palisades');
    497586    playerId = (playerId || 0);
     587    if (playerId == 0)
     588        style = (style || "palisades");
     589    else
     590        style = (style || g_MapSettings.PlayerData[playerId-1].Civ);
    498591    orientation = (orientation || 0);
    499592    maxAngle = (maxAngle || 2*PI);
    500593    if (endWithFirst === undefined)
     
    577670}
    578671
    579672/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    580 // Place a polygonal wall of repeatant wall elements given in the argument wallPart arround centerX/centerY with the given radius
     673//  placePolygonalWall
     674//
     675//  Place a polygonal wall of repeatant wall elements given in the argument wallPart arround centerX/centerY with the given radius
     676//
     677//  NOTE: Don't use wall elements with bending like corners!
     678//  TODO: Check some arguments
     679//  TODO: Add eccentricity and perhaps make it just call placeIrregularPolygonalWall with irregularity = 0
    581680/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    582 // NOTE: Don't use wall elements with bending like corners!
    583 // TODO: Check some arguments
    584 // TODO: Add eccentricity and irregularity (how far the corners can differ from a regulare convex poygon)
    585681function placePolygonalWall(centerX, centerY, radius, wallPart, cornerWallElement, style, playerId, orientation, numCorners, skipFirstWall)
    586682{
    587683    // Setup optional arguments to the default
    588684    wallPart = (wallPart || ['wall']);
    589685    cornerWallElement = (cornerWallElement || 'tower'); // Don't use wide elements for this. Not supported well...
    590     style = (style || 'palisades');
    591686    playerId = (playerId || 0);
     687    if (playerId == 0)
     688        style = (style || "palisades");
     689    else
     690        style = (style || g_MapSettings.PlayerData[playerId-1].Civ);
    592691    orientation = (orientation || 0);
    593692    numCorners = (numCorners || 8);
    594693    skipFirstWall = (skipFirstWall || false);
     
    618717}
    619718
    620719////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    621 // Place an irregular polygonal wall of some wall parts to choose from arround centerX/centerY with the given radius
     720//  placeIrregularPolygonalWall
     721//
     722//  Place an irregular polygonal wall of some wall parts to choose from arround centerX/centerY with the given radius
     723//
     724//  NOTE: wallPartList is put to the end because it's hardest to set
     725//  NOTE: Don't use wall elements with bending like corners!
     726//  TODO: Check some arguments
     727//  TODO: Perhaps add eccentricity
    622728////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    623 // NOTE: Under construction!!!
    624 // NOTE: wallPartList is put to the end because it's hardest to set
    625 // NOTE: Don't use wall elements with bending like corners!
    626 // TODO: Check some arguments
    627 // TODO: Add eccentricity and irregularity (how far the corners can differ from a regulare convex poygon)
    628729function placeIrregularPolygonalWall(centerX, centerY, radius, cornerWallElement, style, playerId, orientation, numCorners, irregularity, skipFirstWall, wallPartsAssortment)
    629730{
     731    // Setup optional arguments
     732    playerId = (playerId || 0);
     733    if (playerId == 0)
     734        style = (style || "palisades");
     735    else
     736        style = (style || g_MapSettings.PlayerData[playerId-1].Civ);
    630737    // Generating a generic wall part assortment with each wall part including 1 gate enlengthend by walls and towers
    631738    // NOTE: It might be a good idea to write an own function for that...
    632739    var defaultWallPartsAssortment = [['wallShort'], ['wall'], ['wallLong'], ['gate', 'tower', 'wallShort']];
     
    721828    }
    722829}
    723830
    724 // Just a test function, USE WITH CARE!
    725 // radius: A float seting the aproximate radius of the fortress
    726 // maxBendOff: Optional, The maximum random bending offset of the wall elements NOTE: If maxBendOff > PI/2 the wall might never close!!!
    727 // wallPart: Optional, An array of wall element string, example: ["tower", "wall"] NOTE: Don't use wall elements with bending!!!
    728 function placeGenericFortress(centerX, centerY, radius, playerId, wallPart, style, maxBendOff)
     831//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     832//  placeGenericFortress
     833//
     834//  Places a generic fortress with towers at the edges connected with long walls and gates (entries untill gates work)
     835//
     836//  This is the default Iberian civ bonus starting wall
     837//
     838//  radius         The approximate radius of the wall to be placed
     839//  playerId       Optional. Integer number of the player. Default is 0 (gaia)
     840//  style          Optional. Wall style string. Default is the civ of the given player, "palisades" for gaia
     841//  irregularity   Optional. Float between 0 (circle) and 1 (very spiky), default is 1/2
     842//  gateOccurence  Optional. Integer number, every n-th walls will be a gate instead. Default is 3
     843//  maxTrys        Optional. How often the function tries to find a better fitting shape at max. Default is 100
     844//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     845function placeGenericFortress(centerX, centerY, radius, playerId, style, irregularity, gateOccurence, maxTrys)
    729846{
    730     if (wallPart == undefined)
    731         wallPart = ['tower', 'wall', 'tower', 'entry', 'tower', 'wall'];
    732     if (maxBendOff > PI/2 || maxBendOff < 0)
    733         warn("setGenericFortress maxBendOff sould satisfy 0 < maxBendOff < PI/2 (~1.5) but it is: " + maxBendOff);
    734     if (maxBendOff === undefined)
    735         maxBendOff = 0;
    736     var wallLength = 0;
    737     for (var eleIndex = 0; eleIndex < wallPart.length; eleIndex++)
     847    // Setup optional arguments
     848    radius = (radius || 20);
     849    playerId = (playerId || 0);
     850    if (playerId == 0)
     851        style = (style || "palisades");
     852    else
     853        style = (style || g_MapSettings.PlayerData[playerId-1].Civ);
     854    irregularity = (irregularity || 1/2);
     855    gateOccurence = (gateOccurence || 3);
     856    maxTrys = (maxTrys || 100);
     857    // Setup some vars
     858    var startAngle = randFloat(0, 2*PI);
     859    var actualOffX = radius*cos(startAngle);
     860    var actualOffY = radius*sin(startAngle);
     861    var actualAngle = startAngle;
     862    var pointDistance = wallStyles[style]["wallLong"].width + wallStyles[style]["tower"].width;
     863    // Searching for a well fitting point derivation
     864    var tries = 0;
     865    var bestPointDerivation = undefined;
     866    var minOverlap = 1000;
     867    var overlap = undefined;
     868    while (tries < maxTrys && minOverlap > wallStyles[style]["tower"].width / 10)
    738869    {
    739         wallLength += wallStyles[style][wallPart[eleIndex]].width
     870        var pointDerivation = [];
     871        var distanceToTarget = 1000;
     872        var targetReached = false;
     873        while (!targetReached)
     874        {
     875            var indent = randFloat(-irregularity*pointDistance, irregularity*pointDistance);
     876            var tmpAngle = getAngle(actualOffX, actualOffY,
     877                (radius + indent)*cos(actualAngle + (pointDistance / radius)),
     878                (radius + indent)*sin(actualAngle + (pointDistance / radius)));
     879            actualOffX += pointDistance*cos(tmpAngle);
     880            actualOffY += pointDistance*sin(tmpAngle);
     881            actualAngle = getAngle(0, 0, actualOffX, actualOffY);
     882            pointDerivation.push([actualOffX, actualOffY]);
     883            distanceToTarget = getDistance(actualOffX, actualOffY, pointDerivation[0][0], pointDerivation[0][1]);
     884            if ( pointDerivation.length > 3 && distanceToTarget < pointDistance) // Could be done better...
     885            {
     886                targetReached = true;
     887                overlap = pointDistance - getDistance(pointDerivation[pointDerivation.length - 1][0], pointDerivation[pointDerivation.length - 1][1], pointDerivation[0][0], pointDerivation[0][1]);
     888                if (overlap < minOverlap)
     889                {
     890                    minOverlap = overlap;
     891                    bestPointDerivation = pointDerivation;
     892                }
     893            }
     894        }
     895        tries++;
    740896    }
    741     if (wallLength > 2*PI*radius || wallLength <= 0)
    742         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);
    743    
    744     var minEleWidth = 1000000; // Assuming the smallest element is about as wide as deep.
    745     for (var eleIndex = 0; eleIndex < wallPart.length; eleIndex++)
     897    log("placeGenericFortress: Reduced overlap to " + minOverlap + " after " + tries + " tries");
     898    // Place wall
     899    for (var pointIndex = 0; pointIndex < bestPointDerivation.length; pointIndex++)
    746900    {
    747         eleWidth = wallStyles[style][wallPart[eleIndex]].width;
    748         if (eleWidth < minEleWidth)
    749             minEleWidth = eleWidth;
     901        var startX = centerX + bestPointDerivation[pointIndex][0];
     902        var startY = centerY + bestPointDerivation[pointIndex][1];
     903        var targetX = centerX + bestPointDerivation[(pointIndex + 1) % bestPointDerivation.length][0];
     904        var targetY = centerY + bestPointDerivation[(pointIndex + 1) % bestPointDerivation.length][1];
     905        var angle = getAngle(startX, startY, targetX, targetY);
     906        var wallElement = "wallLong";
     907        if ((pointIndex + 1) % gateOccurence == 0)
     908            wallElement = "entry"; // Has to be changed to "gate" if gates work...
     909        if (wallStyles[style][wallElement].entity)
     910        {
     911            placeObject(startX + (getDistance(startX, startY, targetX, targetY)/2)*cos(angle), // placeX
     912                startY + (getDistance(startX, startY, targetX, targetY)/2)*sin(angle), // placeY
     913                wallStyles[style][wallElement].entity, playerId, angle - PI/2 + wallStyles[style][wallElement].angle);
     914        }
     915        // Place tower
     916        var startX = centerX + bestPointDerivation[(pointIndex + bestPointDerivation.length - 1) % bestPointDerivation.length][0];
     917        var startY = centerY + bestPointDerivation[(pointIndex + bestPointDerivation.length - 1) % bestPointDerivation.length][1];
     918        var angle = getAngle(startX, startY, targetX, targetY);
     919        placeObject(centerX + bestPointDerivation[pointIndex][0], centerY + bestPointDerivation[pointIndex][1], wallStyles[style]["tower"].entity, playerId, angle - PI/2 + wallStyles[style]["tower"].angle);
    750920    }
    751     var widthSafty = minEleWidth/4; // Can be done better...
    752    
     921}
     922
     923//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     924//  placeOrganicFortress
     925//
     926//  Place an generic 'organic' looking wall of repeatant wall elements given by wallPart roughly arround centerX/centerY with roughly the given radius
     927//  NOTE: This is the old/obsolete Iberian civ bonus starting wall. Remove/rename if the new one (above) is suficient (well, I think it is...)
     928//
     929//  radius: A float seting the aproximate radius of the fortress
     930//  maxBendOff: Optional, The maximum random bending offset of the wall elements
     931//  NOTE: If maxBendOff > PI/3 the wall might not circumvent the center, if > PI/2 the wall might wind up in an infinite loop!!!
     932//  wallPart: Optional, An array of wall element string, example: ["tower", "wall"]
     933//  NOTE: Don't use wall elements with bending like corners!
     934//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     935function placeOrganicFortress(centerX, centerY, radius, playerId, wallPart, style, maxBendOff)
     936{
     937    // Setup optional arguments to the default
     938    if (wallPart === undefined)
     939        wallPart = ['tower', 'wall', 'tower', 'entry', 'tower', 'wall'];
     940    if (maxBendOff === undefined)
     941        maxBendOff = 0;
     942    // Check arguments for sane values
     943    if (maxBendOff > PI/3 || maxBendOff < 0)
     944        warn("placeOrganicFortress maxBendOff sould satisfy 0 < maxBendOff < PI/3 (~1) to ensure stability but it is: " + maxBendOff);
     945    // Check wall part length against shortest theoretical total wall length (circle perimeter)
     946    var wallPartLength = getWallLength(wallPart, style);
     947    if (wallPartLength > PI*radius || wallPartLength <= 0)
     948        warn("placeOrganicFortress: Given wall part is longer than half the circle perimeter of given radius: Half circle perimeter ~= " + round(PI*radius) +", wallPart total length ~= " + round(wallPartLength));
     949    // Setting up some variables
    753950    var x = radius;
    754951    var y = 0;
    755952    var angle = 0;
     
    757954    var targetY = 0;
    758955    var targetReached = false;
    759956    var eleIndex = 0;
     957    // Start the evil while loope ^^
    760958    while (targetReached == false)
    761959    {
    762960        var wallElement = wallStyles[style][wallPart[eleIndex % wallPart.length]];
    763         var eleWidth = wallElement.width - widthSafty;
    764         // Stabalized bendOff
     961        var eleWidth = wallElement.width; // Reducing this a bit to avoid gaps might be good
     962        // Stabalized bendOff. TODO: Ensure positive eleAngleWidth!!!
    765963        var actualRadius = getDistance(centerX, centerY, centerX + x, centerY + y);
    766964        var bendOff = randFloat(-maxBendOff*radius/actualRadius, maxBendOff*actualRadius/radius);
    767965        // Element width in radians
     
    774972        x = placeX - eleWidth/2 * sin(eleAngle);
    775973        y = placeY + eleWidth/2 * cos(eleAngle);
    776974        angle += eleAngleWidth;
    777         if (eleIndex % wallPart.length == 0 && eleIndex > wallPart.length && (getDistance(x, y, targetX, targetY) < wallLength || angle > 2*PI))
     975        if (eleIndex % wallPart.length == 0 && eleIndex > wallPart.length && (getDistance(x, y, targetX, targetY) < wallPartLength || angle > 2*PI))
    778976            targetReached = true;
    779977        eleIndex++;
    780         // if (eleIndex == 10)
    781             // break;
    782978    }
    783     placeLinearWall(centerX + x, centerY + y, centerX + targetX, centerY + targetY, ['wall', 'tower'], style, playerId, true);
     979    // Close wall with simple linear wall
     980    if (getDistance(centerX + x, centerY + y, centerX + targetX, centerY + targetY) > wallStyles[style]['wallLong'].width)
     981        placeLinearWall(centerX + x, centerY + y, centerX + targetX, centerY + targetY, ['wall', 'tower'], style, playerId, true);
    784982}
  • data/mods/public/maps/random/wall_demo.js

     
    6363var actualY = distToMapBorder;
    6464// Wall styles are chosen by strings so the civ strings got by g_MapSettings.PlayerData[playerId - 1].Civ can be used
    6565// Other styles may be present as well but besides the civ styles only 'palisades' includes all wall element types (yet)
    66 const wallStyleList = ['athen', 'cart', 'celt', 'hele', 'iber', 'mace', 'pers', 'rome', 'spart', 'rome_siege', 'palisades'];
     66const wallStyleList = ["athen", "brit", "cart", "celt", "gaul", "hele", "iber", "mace", "pers", "rome", "spart", "rome_siege", "palisades"];
    6767
    6868
    6969////////////////////////////////////////
     
    111111for (var styleIndex = 0; styleIndex < wallStyleList.length; styleIndex++)
    112112{
    113113    var centerX = actualX + radius + styleIndex * buildableMapSize/wallStyleList.length; // X coordinate of the center of the wall circle
    114     var playerID = 0; // Player ID of the player owning the wall, 0 is Gaia, 1 is the first player (default blue), ...
     114    var playerId = 0; // Player ID of the player owning the wall, 0 is Gaia, 1 is the first player (default blue), ...
    115115    var wallPart = ['tower', 'wall', 'house']; // List of wall elements the wall will be build of. Optional, default id ['wall']
    116116    var style = wallStyleList[styleIndex]; // The wall's style like 'cart', 'celt', 'hele', 'iber', 'pers', 'rome', 'romeSiege' or 'palisades'
    117117    var maxAngle = PI/2 * (styleIndex%3 + 2); // How far the wall should circumvent the center
    118     placeCircularWall(centerX, centerY, radius, wallPart, style, playerID, orientation, maxAngle); // Actually placing the wall
     118    placeCircularWall(centerX, centerY, radius, wallPart, style, playerId, orientation, maxAngle); // Actually placing the wall
    119119    placeObject(centerX, centerY, 'other/obelisk', 0, 0*PI); // Place visual marker to see the center of the wall circle
    120120    orientation += PI/16; // Increasing orientation to see how rotation works (like for object placement)
    121121}
     
    132132for (var styleIndex = 0; styleIndex < wallStyleList.length; styleIndex++)
    133133{
    134134    var centerX = actualX + radius + styleIndex * buildableMapSize/wallStyleList.length; // X coordinate of the center of the wall circle
    135     var playerID = 0; // Player ID of the player owning the wall, 0 is Gaia, 1 is the first player (default blue), ...
     135    var playerId = 0; // Player ID of the player owning the wall, 0 is Gaia, 1 is the first player (default blue), ...
    136136    var cornerWallElement = 'tower'; // With wall element type will be uset for the corners of the polygon
    137137    var wallPart = ['wall', 'tower']; // List of wall elements the wall will be build of. Optional, default id ['wall']
    138138    var style = wallStyleList[styleIndex]; // The wall's style like 'cart', 'celt', 'hele', 'iber', 'pers', 'rome', 'romeSiege' or 'palisades'
    139139    var numCorners = (styleIndex)%6 + 3; // How many corners the plogon will have
    140140    var skipFirstWall = true; // If the wall should be open towards orientation
    141     placePolygonalWall(centerX, centerY, radius, wallPart, cornerWallElement, style, playerID, orientation, numCorners, skipFirstWall);
     141    placePolygonalWall(centerX, centerY, radius, wallPart, cornerWallElement, style, playerId, orientation, numCorners, skipFirstWall);
    142142    placeObject(centerX, centerY, 'other/obelisk', 0, 0*PI); // Place visual marker to see the center of the wall circle
    143143    orientation += PI/16; // Increasing orientation to see how rotation works (like for object placement)
    144144}
     
    159159        var startY = actualY; // Y coordinate the wall will start from
    160160        var endX = actualX + (styleIndex * numWallsPerStyle + wallIndex) * distToOtherWalls; // X coordinate the wall will end
    161161        var endY = actualY + (wallIndex + 1) * maxWallLength/numWallsPerStyle; // Y coordinate the wall will end
    162         var playerID = 0; // Player ID of the player owning the wall, 0 is Gaia, 1 is the first player (default blue), ...
     162        var playerId = 0; // Player ID of the player owning the wall, 0 is Gaia, 1 is the first player (default blue), ...
    163163        var wallPart = ['tower', 'wall']; // List of wall elements the wall will be build of
    164164        var style = wallStyleList[styleIndex]; // The wall's style like 'cart', 'celt', 'hele', 'iber', 'pers', 'rome', 'romeSiege' or 'palisades'
    165         placeLinearWall(startX, startY, endX, endY, wallPart, style, playerID, false); // Actually placing the wall
     165        placeLinearWall(startX, startY, endX, endY, wallPart, style, playerId); // Actually placing the wall
    166166        // placeObject(startX, startY, 'other/obelisk', 0, 0*PI); // Place visual marker to see where exsactly the wall begins
    167167        // placeObject(endX, endY, 'other/obelisk', 0, 0*PI); // Place visual marker to see where exsactly the wall ends
    168168    }