Ticket #1311: wall_builder_update2.diff

File wall_builder_update2.diff, 93.6 KB (added by FeXoR, 12 years ago)
  • binaries/data/mods/public/maps/random/deep_forest.js

     
    5454var mapCenterZ = mapRadius;
    5555
    5656// Setup players and bases
    57 var fortresses = false;
    5857var numPlayers = getNumPlayers();
    5958var baseRadius = 20;
    60 if (fortresses == true)
    61     baseRadius = 30;
    6259var minPlayerRadius = min(mapRadius-1.5*baseRadius, 5*mapRadius/8);
    6360var maxPlayerRadius = min(mapRadius-baseRadius, 3*mapRadius/4);
    6461const BUILDING_ANlE = -PI/4;
     
    7774var pathSucsessRadius = baseRadius/2;
    7875var pathAngleOff = PI/2;
    7976var pathWidth = 5; // This is not really the path's sickness in tiles but the number of tiles in the clumbs of the path
    80 if (fortresses == true)
    81     pathSucsessRadius = baseRadius;;
    8277
    8378// Setup additional resources
    8479var resourceRadius = 2*mapRadius/3; // 3*mapRadius/8;
     
    10499    var placer = new ClumpPlacer(2*baseRadius*baseRadius, 2/3, 1/8, 10, x, z);
    105100    var painter = [new LayeredPainter([terrainBaseBorder, terrainBase], [baseRadius/4]), paintClass(clPlayer)];
    106101    createArea(placer, painter);
    107     // Place fortresses
    108     if (fortresses == true)
    109     {
    110         // Place fortresses
    111         new wallTool(civ, "small").place(x, z, i+1, BUILDING_ANlE);
    112         // if (civ == "iber")
    113             // new wallTool("iber").setGenericFortress(x, z, i+1, 20, PI/6);
    114     };
    115102    // Place starting resources
    116103    var distToSL = 10;
    117104    var resStartAngle = playerAngle[i] + PI;
     
    123110        var placeZ = z + distToSL*sin(resStartAngle + rIndex*resAddAngle + angleOff);
    124111        placeObject(placeX, placeZ, startingResourcees[rIndex], 0, randFloat(0, 2*PI));
    125112        addToClass(round(placeX), round(placeZ), clBaseResource);
    126     };
    127 };
     113    }
     114}
    128115
    129116RMS.SetProgress(10);
    130117
     
    190177            {
    191178                x += round(cos(angle + randFloat(-pathAngleOff, pathAngleOff)));
    192179                z += round(sin(angle + randFloat(-pathAngleOff, pathAngleOff)));
    193             };
     180            }
    194181            if (getDistance(x, z, targetX, targetZ) < pathSucsessRadius)
    195182                targetReached = true;
    196183            tries++;
    197184
    198         };
    199     };
    200 };
     185        }
     186    }
     187}
    201188
    202189RMS.SetProgress(50);
    203190
     
    216203        var placer = new ClumpPlacer(40, 1/2, 1/8, 1, placeX, placeZ);
    217204        var painter = [new LayeredPainter([terrainHillBorder, terrainHill], [1]), new ElevationPainter(1+randFloat()), paintClass(clHill)];
    218205        createArea(placer, painter);
    219     };
    220 };
     206    }
     207}
    221208
    222209RMS.SetProgress(60);
    223210
     
    255242                var placer = new ClumpPlacer(1, 1.0, 1.0, 1, x, z);
    256243                var painter = [new TerrainPainter(terrainWood), new ElevationPainter(randFloat()), paintClass(clForest)];
    257244                createArea(placer, painter, avoidClasses(clPath, 2, clHill, 1));
    258             };
    259         };
     245            }
     246        }
    260247        // General hight map
    261248        var hVarMiddleHill = mapSize/64 * (1+cos(3*PI/2 * radius/mapRadius));
    262249        var hVarHills = 5*(1+sin(x/10)*sin(z/10));
    263250        setHeight(x, z, getHeight(x, z) + hVarMiddleHill + hVarHills + 1);
    264     };
    265 };
     251    }
     252}
    266253
    267254RMS.SetProgress(95);
    268255
    269 // Test linear wall
    270 // new wallTool("palisades").placeLinearWall(mapCenterX, mapCenterZ, playerStartLocX[0], playerStartLocZ[0], 0, ["tower", "wall"])
    271256
    272 
    273257// Export map data
    274258ExportMap();
  • binaries/data/mods/public/maps/random/fortress.js

     
    153153    // Base texture
    154154    var placer = new ClumpPlacer(PI*baseRadius*baseRadius/4, 1/2, 1/8, 10, playerX[i], playerZ[i]);
    155155    createArea(placer,[new TerrainPainter(tRoad), paintClass(clPlayer)]);
    156     // Place fortresses
    157     // new wallTool(civ, "medium").place(x, z, i+1, buildAngle);
    158156   
    159     // Place fortresses Spahbod (custom fortress method, standart for this case but no function "setFortress" implemented yet)
    160     var fType = new fortress('Spahbod'+civ);
     157    // Place custom fortress
    161158    if (civ == "celt" || civ == "iber")
    162159    {
    163         fType.wall = ['entry', 'wall', 'wall',
     160        var wall = ['entryTower', 'wall', 'wall',
    164161            'cornerIn', 'wall', 'barracks', 'wall', 'gate', 'wall', 'house', 'wall',
    165             'cornerIn', 'wall', 'house', 'wall', 'entry', 'wall', 'house', 'wall',
     162            'cornerIn', 'wall', 'house', 'wall', 'entryTower', 'wall', 'house', 'wall',
    166163            'cornerIn', 'wall', 'house', 'wall', 'gate', 'wall', 'house', 'wall',
    167164            'cornerIn', 'wall', 'house', 'wall'];
    168165    }
    169166    else
    170167    {
    171         fType.wall = ['entry', 'wall', 'wall',
     168        var wall = ['entryTower', 'wall', 'wall',
    172169            'cornerIn', 'wall', 'barracks', 'wall', 'gate', 'wall', 'wall',
    173             'cornerIn', 'wall', 'house', 'wall', 'entry', 'wall', 'wall',
     170            'cornerIn', 'wall', 'house', 'wall', 'entryTower', 'wall', 'wall',
    174171            'cornerIn', 'wall', 'house', 'wall', 'gate', 'wall', 'wall',
    175172            'cornerIn', 'wall', 'house', 'wall'];
    176     };
    177     var fort = new wallTool(civ);
    178     fort.setFortress(fType);
    179     fort.place(playerX[i], playerZ[i], i+1, BUILDING_ANGlE);
     173    }
     174    placeCustomFortress(playerX[i], playerZ[i], new Fortress("Spahbod", wall), civ, i+1, BUILDING_ANGlE);
     175}
    180176
    181 };
    182 
    183177// create lakes
    184178log("Creating lakes...");
    185179var numLakes = round(scaleByMapSize(1,4) * numPlayers);
     
    459453);
    460454
    461455// Export map data
    462 ExportMap();
    463  No newline at end of file
     456ExportMap();
  • binaries/data/mods/public/maps/random/rmgen/wall_builder.js

     
    1 // Functionality to create walls and fortresses
    2 // Wall object
    3 function wallElement(type)
     1////////////////////////////////////////////////////////////////////
     2// This file contains functionality to place walls on random maps //
     3////////////////////////////////////////////////////////////////////
     4
     5// To do:
     6// Add some more checks and warnings for example if wall elements with bending are used for linear/circular wall placement
     7// Add some more documentation
     8// Add further wall elements cornerHalfIn, cornerHalfOut and adjust default fortress types
     9// Add wall style 'roads'
     10// Add trsures to 'others'
     11
     12
     13///////////////////////////////
     14// WallElement class definition
     15///////////////////////////////
     16
     17// argument type: Descriptive string, example: 'wall'. NOTE: Not really needed. Mainly for custom wall elements and to get the wall element type in code.
     18// argument entity: Optional. Template string to be placed, example: 'structures/cart_wall'. Default is undefined (No entity placed)
     19// 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)
     20// 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
     21// argument indent: Optional. The indentation means its drawn inside (positive values) or pushed outwards (negative values). Default is 0
     22// NOTE: Bending is only used for fortresses and custom walls. Linear/circular walls walls use no/generic bending
     23// argument bending: Optional. How the direction of the wall is changed after this element, positive is bending 'in' (counter clockwise like entity placement)
     24function WallElement(type, entity, angle, width, indent, bending)
    425{
    5     // NOTE: Not all wall elements have a symetry. So there's an direction 'outside' (towards top/positive Z by default)
    6     // In this sense 'right'/'left' means right/left of you when you stand upon the wall and look 'outside'
    7     // The wall is build towards 'right' so the next wall element will be placed right of the previous one
    8     // In this sense the wall's direction is right meaning the 'bending' of a corner is used for the element following the corner
    9     // With 'inside' and 'outside' defined as above, corners bend 'in'/'out' meaning placemant angle is increased/decreased (circlewise like building placement)
    10     this.type = type; // Descriptive string for easy to add wall styles. Not really needed (wallTool.wallTypes['type string'] is used)
    11     // Wall type documentation:
    12     // wall: A blocking straight wall element that mainly lengthens the wall, self-explanatory
    13     // tower: A blocking straight wall element with damage potential that slightly lengthens the wall, exsample: wall tower, palisade tower(No attack?)
    14     // wallFort: A blocking straight wall element with massive damage potential that lengthens the wall, exsample: fortress, palisade fort
    15         // NOTE: Not really needed but for palisades, I don't find it tragic that palisades are much less powerfull
    16     // outpost: A zero-length wall element without bending far indented so it stands outside the wall, exsample: outpost, defense tower, watchtower
    17     // house: A zero-length wall element without bending far indented so it stands inside the wall, exsample: house, hut, longhouse
    18     // gate: A blocking straight wall element with passability determined by owner, example: gate
    19     // entry: A non-blocking straight wall element represented by a single indented template, example: defense tower, wall tower, outpost, watchtower, nothing
    20     // wideEntry: A non-blocking straight wall element represented by a single indented template, example: fortress? a unit?
    21         // NOTE: Not really needed...
    22     // endRight: A straight wall element that (only) visually ends the wall to the right (e.g. left of entrys), example: wall tower, palisade ending
    23     // endLeft: A straight wall element that (only) visually ends the wall to the left (e.g. right of entrys), example: wall tower, palisade ending
    24     // cornerIn: A wall element bending the wall PI/2 (90°) 'inside' (see above), example: wall tower, palisade curve
    25     // cornerOut: A wall element bending the wall PI/2 (90°) 'outside' (see above), example: wall tower, palisade curve (placed the other way arround)
    26     // barracks: Adding in progress...
    27     this.entity = undefined; // Template (string) that will represent the wall element, example: "other/palisades_rocks_straight"
    28     this.angle = -PI/2; // Placement angle so that 'outside' is 'top' (directs towards positive z, like buildings)
    29     this.width = 0; // The width it lengthens the wall, width because it's the needed space in a right angle to 'outside'
    30     this.indent = 0; // The indentation means its drawn inside (positive values) or pressed outwards (negative values)
    31     this.bending = 0*PI; // How the angle of the wall is changed by this element for the following element, positive is bending 'in'
    32 };
     26    // NOTE: Not all wall elements have a symetry. So there's an direction 'outside' (towards right/positive X by default)
     27    // In this sense 'left'/'right' means left/right of you when you stand upon the wall and look 'outside'
     28    // The wall is build towards 'left' so the next wall element will be placed left of the previous one (towards positive Y by default)
     29    // In this sense the wall's direction is left meaning the 'bending' of a corner is used for the element following the corner
     30    // With 'inside' and 'outside' defined as above, corners bend 'in'/'out' meaning placemant angle is increased/decreased (counter clockwise like object placement)
     31    this.type = type;
     32    // Wall element type documentation:
     33    // Enlengthening straight blocking (mainly left/right symetric) wall elements (Walls and wall fortifications)
     34        // 'wall': A blocking straight wall element that mainly lengthens the wall, self-explanatory
     35        // 'wallShort': self-explanatory. NOTE: Not implemented yet, waiting for finalized templates...
     36        // 'wallLong': self-explanatory. NOTE: Not implemented yet, waiting for finalized templates...
     37        // 'tower': A blocking straight wall element with damage potential (but for palisades) that slightly lengthens the wall, exsample: wall tower, palisade tower(No attack)
     38        // 'wallFort': A blocking straight wall element with massive damage potential that lengthens the wall, exsample: fortress, palisade fort
     39    // Enlengthening straight non/custom blocking (mainly left/right symetric) wall elements (Gates and entrys)
     40        // 'gate': A blocking straight wall element with passability determined by owner, example: gate (Functionality not yet implemented)
     41        // 'entry': A wall element like the gate but without an actual template or just a flag/column/obelisk
     42        // 'entryTower': A non-blocking straight wall element represented by a single (maybe indented) template, example: defense tower, wall tower, outpost, watchtower
     43        // 'entryFort': A non-blocking straight wall element represented by a single (maybe indented) template, example: fortress, palisade fort
     44    // Enlengthening straight blocking non-left/right-symetric wall elements (Wall endings/closings)
     45        // 'endLeft': A straight wall element that (only visually) finalizes the wall to the left (e.g. right of entrys), example: wall tower, palisade ending
     46        // 'endRight': A straight wall element that (only visually) finalizes the wall to the right (e.g. left of entrys), example: wall tower, palisade ending
     47    // Bending wall elements (Wall corners)
     48        // 'cornerIn': A wall element bending the wall by PI/2 'inside' (left, +, see above), example: wall tower, palisade curve
     49        // 'cornerOut': A wall element bending the wall by PI/2 'outside' (right, -, see above), example: wall tower, palisade curve
     50        // 'cornerHalfIn': A wall element bending the wall by PI/4 'inside' (left, +, see above), example: wall tower, palisade curve. NOTE: Not yet implemented
     51        // 'cornerHalfOut': A wall element bending the wall by PI/4 'outside' (right, -, see above), example: wall tower, palisade curve. NOTE: Not yet implemented
     52    // Zero length straight indented (mainly left/right symetric) wall elements (Outposts/watchtowers and non-defensive base structures)
     53        // 'outpost': A zero-length wall element without bending far indented so it stands outside the wall, exsample: outpost, defense tower, watchtower
     54        // 'house': A zero-length wall element without bending far indented so it stands inside the wall that grants population bonus, exsample: house, hut, longhouse
     55        // 'barracks': A zero-length wall element without bending far indented so it stands inside the wall that grants unit production, exsample: barracks, tavern, ...
     56    this.entity = entity;
     57    this.angle = (angle !== undefined) ? angle : 0*PI;
     58    this.width = (width !== undefined) ? width : 0;
     59    this.indent = (indent !== undefined) ? indent : 0;
     60    this.bending = (bending !== undefined) ? bending : 0*PI;
     61}
    3362
    34 // Fortress object. A list would do for symetric fortresses but if 'getCenter' don't do sufficient the center can be set manually.
    35 function fortress(type)
     63////////////////////////////
     64// Fortress class definition
     65////////////////////////////
     66
     67// A list would do for symetric fortresses but if 'getCenter' don't do sufficient the center can be set manually
     68// argument type: Descriptive string, example: 'tiny'. Not really needed (WallTool.wallTypes['type string'] is used). Mainly for custom wall elements.
     69// argument wall: Optional. Array of wall element strings. Can be set afterwards. Default is an epty array.
     70    // Example: ['entrance', 'wall', 'cornerIn', 'wall', 'gate', 'wall', 'entrance', 'wall', 'cornerIn', 'wall', 'gate', 'wall', 'cornerIn', 'wall']
     71// 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???)
     72    // NOTE: The center will be recalculated when WallTool.setFortress is called. To avoid this set WallTool.calculateCenter to false.
     73function Fortress(type, wall, center)
    3674{
    37     this.type = type; // Only usefull to get the type of the actual fortress (by 'wallTool.fortress.type')
    38     this.wall = [];
     75    this.type = type; // Only usefull to get the type of the actual fortress (by 'WallTool.fortress.type')
     76    this.wall = (wall !== undefined) ? wall : [];
    3977    this.center = [0, 0]; // X/Z offset (in default orientation) from first wall element to center, perhaps should be the other way around...
    40     // NOTE: The 'angle' is not implemented yet!!!
    41     this.angle = 0; // Angle the first element has to be placed so that fortress orientation is with main entrance top (default), should always be 0 though.
    42 };
     78}
    4379
    44 // The wall tool
    45 function wallTool(style, fortressType)
    46 {
    47     // General setup
    48     this.angle = 0; // Not really needed, may be useful to rotate fortresses after set...
    49     this.wallTypes = {}; // An associative array including all wall elements associated with 'wallElement.type'.
    50     this.wall = []; // A list of strings (wall element types) for simple wall building
    51     this.center = [0, 0] // X/Z offset from first wall element to center, perhaps should be the other way around...
    52    
    53     // Presets needed for wall style
    54     this.wallStyles = {};
    55     this.style = "palisades"; // Not really needed, perhaps helpfull to check current style
    56     if (style !== undefined)
    57         this.style = style;
    58    
    59     // Presets needed for tortess types
    60     this.fortressTypes = {};
    61     this.fortress = false; // Not really needed, perhaps usefull for getting fortress type, should be renamed somehow but simply 'type' is not very descriptive and 'fortressType' may be mistaken as 'fortressTypes'
    62     if (fortressType !== undefined)
    63         this.fortress = fortressType;
    64     this.calculateCenter = true; // If setFortress(Type) shall recalculate the center
    65    
    66     // Adding wall styles
    67     // Wall style 'palisades'
    68     this.wallStyles["palisades"] = {};
    69     this.wallStyles["palisades"]["wall"] = new wallElement("wall");
    70     this.wallStyles["palisades"]["wall"].entity = "other/palisades_rocks_straight";
    71     this.wallStyles["palisades"]["wall"].angle = -PI/2;
    72     this.wallStyles["palisades"]["wall"].width = 2.5;
    73    
    74     this.wallStyles["palisades"]["tower"] = new wallElement("tower");
    75     this.wallStyles["palisades"]["tower"].entity = "other/palisades_rocks_tower";
    76     this.wallStyles["palisades"]["tower"].angle = -PI/2;
    77     this.wallStyles["palisades"]["tower"].width = 0.7;
    78    
    79     this.wallStyles["palisades"]["wallFort"] = new wallElement("wallFort");
    80     this.wallStyles["palisades"]["wallFort"].entity = "other/palisades_rocks_fort";
    81     this.wallStyles["palisades"]["wallFort"].angle = PI;
    82     this.wallStyles["palisades"]["wallFort"].width = 1.7;
    83    
    84     this.wallStyles["palisades"]["outpost"] = new wallElement("outpost");
    85     this.wallStyles["palisades"]["outpost"].entity = "other/palisades_rocks_outpost";
    86     this.wallStyles["palisades"]["outpost"].angle = PI;
    87     this.wallStyles["palisades"]["outpost"].indent = -2;
    88    
    89     this.wallStyles["palisades"]["house"] = new wallElement("house");
    90     this.wallStyles["palisades"]["house"].entity = "other/celt_hut";
    91     this.wallStyles["palisades"]["house"].angle = PI;
    92     this.wallStyles["palisades"]["house"].indent = 5;
    93    
    94     this.wallStyles["palisades"]["gate"] = new wallElement("gate");
    95     this.wallStyles["palisades"]["gate"].entity = "other/palisades_rocks_gate";
    96     this.wallStyles["palisades"]["gate"].angle = -PI/2;
    97     this.wallStyles["palisades"]["gate"].width = 3.6;
    98    
    99     this.wallStyles["palisades"]["entry"] = new wallElement("entry");
    100     this.wallStyles["palisades"]["entry"].entity = "other/palisades_rocks_watchtower";
    101     this.wallStyles["palisades"]["entry"].angle = 0*PI;
    102     this.wallStyles["palisades"]["entry"].width = 3.6;
    103     this.wallStyles["palisades"]["entry"].indent = -2;
    104    
    105     this.wallStyles["palisades"]["wideEntry"] = new wallElement("wideEntry");
    106     this.wallStyles["palisades"]["wideEntry"].entity = "other/palisades_rocks_fort";
    107     this.wallStyles["palisades"]["wideEntry"].angle = PI;
    108     this.wallStyles["palisades"]["wideEntry"].width = 6;
    109     this.wallStyles["palisades"]["wideEntry"].indent = -3;
    110    
    111     this.wallStyles["palisades"]["endRight"] = new wallElement("endRight");
    112     this.wallStyles["palisades"]["endRight"].entity = "other/palisades_rocks_end";
    113     this.wallStyles["palisades"]["endRight"].angle = -PI/2;
    114     this.wallStyles["palisades"]["endRight"].width = 0.2;
    115    
    116     this.wallStyles["palisades"]["endLeft"] = new wallElement("endLeft");
    117     this.wallStyles["palisades"]["endLeft"].entity = "other/palisades_rocks_end";
    118     this.wallStyles["palisades"]["endLeft"].angle = PI/2;
    119     this.wallStyles["palisades"]["endLeft"].width = 0.2;
    120    
    121     this.wallStyles["palisades"]["cornerIn"] = new wallElement("cornerIn");
    122     this.wallStyles["palisades"]["cornerIn"].entity = "other/palisades_rocks_curve";
    123     this.wallStyles["palisades"]["cornerIn"].angle = -PI/4;
    124     this.wallStyles["palisades"]["cornerIn"].width = 2.1;
    125     this.wallStyles["palisades"]["cornerIn"].indent = 0.7;
    126     this.wallStyles["palisades"]["cornerIn"].bending = PI/2;
    127    
    128     this.wallStyles["palisades"]["cornerOut"] = new wallElement("cornerOut");
    129     this.wallStyles["palisades"]["cornerOut"].entity = "other/palisades_rocks_curve";
    130     this.wallStyles["palisades"]["cornerOut"].angle = PI/4;
    131     this.wallStyles["palisades"]["cornerOut"].width = 2.1;
    132     this.wallStyles["palisades"]["cornerOut"].indent = -0.7;
    133     this.wallStyles["palisades"]["cornerOut"].bending = -PI/2;
    134    
    135     // Wall style 'cart'
    136     this.wallStyles["cart"] = {};
    137     this.wallStyles["cart"]["wall"] = new wallElement("wall");
    138     this.wallStyles["cart"]["wall"].entity = "structures/cart_wall";
    139     this.wallStyles["cart"]["wall"].angle = 0*PI;
    140     this.wallStyles["cart"]["wall"].width = 6.2;
    141    
    142     this.wallStyles["cart"]["tower"] = new wallElement("tower");
    143     this.wallStyles["cart"]["tower"].entity = "structures/cart_wall_tower";
    144     this.wallStyles["cart"]["tower"].angle = PI;
    145     this.wallStyles["cart"]["tower"].width = 2.7;
    146    
    147     this.wallStyles["cart"]["wallFort"] = new wallElement("wallFort");
    148     this.wallStyles["cart"]["wallFort"].entity = "structures/cart_fortress";
    149     this.wallStyles["cart"]["wallFort"].angle = PI;
    150     this.wallStyles["cart"]["wallFort"].width = 5.1;
    151     this.wallStyles["cart"]["wallFort"].indent = 1.6;
    152    
    153     this.wallStyles["cart"]["outpost"] = new wallElement("outpost");
    154     this.wallStyles["cart"]["outpost"].entity = "structures/cart_outpost";
    155     this.wallStyles["cart"]["outpost"].angle = PI;
    156     this.wallStyles["cart"]["outpost"].indent = -5;
    157    
    158     this.wallStyles["cart"]["house"] = new wallElement("house");
    159     this.wallStyles["cart"]["house"].entity = "structures/cart_house";
    160     this.wallStyles["cart"]["house"].angle = PI;
    161     this.wallStyles["cart"]["house"].indent = 7;
    162    
    163     this.wallStyles["cart"]["gate"] = new wallElement("gate");
    164     this.wallStyles["cart"]["gate"].entity = "structures/cart_wall_gate";
    165     this.wallStyles["cart"]["gate"].angle = 0*PI;
    166     this.wallStyles["cart"]["gate"].width = 6.2;
    167    
    168     this.wallStyles["cart"]["entry"] = new wallElement("entry");
    169     this.wallStyles["cart"]["entry"].entity = "structures/cart_defense_tower";
    170     this.wallStyles["cart"]["entry"].angle = PI;
    171     this.wallStyles["cart"]["entry"].width = 6.2;
    172     this.wallStyles["cart"]["entry"].indent = -5;
    173    
    174     this.wallStyles["cart"]["wideEntry"] = new wallElement("wideEntry");
    175     this.wallStyles["cart"]["wideEntry"].entity = "structures/cart_fortress";
    176     this.wallStyles["cart"]["wideEntry"].angle = PI;
    177     this.wallStyles["cart"]["wideEntry"].width = 12;
    178     this.wallStyles["cart"]["wideEntry"].indent = 7;
    179    
    180     this.wallStyles["cart"]["endRight"] = new wallElement("endRight");
    181     this.wallStyles["cart"]["endRight"].entity = "structures/cart_wall_tower";
    182     this.wallStyles["cart"]["endRight"].angle = PI;
    183     this.wallStyles["cart"]["endRight"].width = 2.7;
    184    
    185     this.wallStyles["cart"]["endLeft"] = new wallElement("endLeft");
    186     this.wallStyles["cart"]["endLeft"].entity = "structures/cart_wall_tower";
    187     this.wallStyles["cart"]["endLeft"].angle = PI;
    188     this.wallStyles["cart"]["endLeft"].width = 2.7;
    189    
    190     this.wallStyles["cart"]["cornerIn"] = new wallElement("cornerIn");
    191     this.wallStyles["cart"]["cornerIn"].entity = "structures/cart_wall_tower";
    192     this.wallStyles["cart"]["cornerIn"].angle = 5*PI/4;
    193     this.wallStyles["cart"]["cornerIn"].width = 0.1;
    194     this.wallStyles["cart"]["cornerIn"].indent = 0.9;
    195     this.wallStyles["cart"]["cornerIn"].bending = PI/2;
    196    
    197     this.wallStyles["cart"]["cornerOut"] = new wallElement("cornerOut");
    198     this.wallStyles["cart"]["cornerOut"].entity = "structures/cart_wall_tower";
    199     this.wallStyles["cart"]["cornerOut"].angle = 3*PI/4;
    200     this.wallStyles["cart"]["cornerOut"].width = 1.3; // 1.6
    201     this.wallStyles["cart"]["cornerOut"].bending = -PI/2;
    202    
    203     this.wallStyles["cart"]["barracks"] = new wallElement("barracks");
    204     this.wallStyles["cart"]["barracks"].entity = "structures/cart_barracks";
    205     this.wallStyles["cart"]["barracks"].angle = PI;
    206     this.wallStyles["cart"]["barracks"].indent = 7;
    207    
    208     // Wall style 'celt'
    209     this.wallStyles["celt"] = {};
    210     this.wallStyles["celt"]["wall"] = new wallElement("wall");
    211     this.wallStyles["celt"]["wall"].entity = "structures/celt_wall";
    212     this.wallStyles["celt"]["wall"].angle = 0*PI;
    213     this.wallStyles["celt"]["wall"].width = 5;
    214     this.wallStyles["celt"]["wall"].indent = 0.5;
    215    
    216     this.wallStyles["celt"]["tower"] = new wallElement("tower");
    217     this.wallStyles["celt"]["tower"].entity = "structures/celt_wall_tower";
    218     this.wallStyles["celt"]["tower"].angle = PI;
    219     this.wallStyles["celt"]["tower"].width = 0.7;
    220    
    221     this.wallStyles["celt"]["wallFort"] = new wallElement("wallFort");
    222     this.wallStyles["celt"]["wallFort"].entity = "structures/celt_fortress_g";
    223     this.wallStyles["celt"]["wallFort"].angle = PI;
    224     this.wallStyles["celt"]["wallFort"].width = 4.2;
    225     this.wallStyles["celt"]["wallFort"].indent = 2;
    226    
    227     this.wallStyles["celt"]["outpost"] = new wallElement("outpost");
    228     this.wallStyles["celt"]["outpost"].entity = "structures/celt_outpost";
    229     this.wallStyles["celt"]["outpost"].angle = PI;
    230     this.wallStyles["celt"]["outpost"].indent = -5;
    231    
    232     this.wallStyles["celt"]["house"] = new wallElement("house");
    233     this.wallStyles["celt"]["house"].entity = "structures/celt_house";
    234     this.wallStyles["celt"]["house"].angle = PI;
    235     this.wallStyles["celt"]["house"].indent = 5;
    236    
    237     this.wallStyles["celt"]["gate"] = new wallElement("gate");
    238     this.wallStyles["celt"]["gate"].entity = "structures/celt_wall_gate";
    239     this.wallStyles["celt"]["gate"].angle = 0*PI;
    240     this.wallStyles["celt"]["gate"].width = 3.2;
    241    
    242     this.wallStyles["celt"]["entry"] = new wallElement("entry");
    243     this.wallStyles["celt"]["entry"].entity = "structures/celt_defense_tower";
    244     this.wallStyles["celt"]["entry"].angle = PI;
    245     this.wallStyles["celt"]["entry"].width = 6;
    246     this.wallStyles["celt"]["entry"].indent = -5;
    247    
    248     this.wallStyles["celt"]["wideEntry"] = new wallElement("wideEntry");
    249     this.wallStyles["celt"]["wideEntry"].entity = "structures/celt_fortress_b";
    250     this.wallStyles["celt"]["wideEntry"].angle = PI;
    251     this.wallStyles["celt"]["wideEntry"].width = 12;
    252     this.wallStyles["celt"]["wideEntry"].indent = 7;
    253    
    254     this.wallStyles["celt"]["endRight"] = new wallElement("endRight");
    255     this.wallStyles["celt"]["endRight"].entity = "structures/celt_wall_tower";
    256     this.wallStyles["celt"]["endRight"].angle = PI;
    257     this.wallStyles["celt"]["endRight"].width = 0.7;
    258    
    259     this.wallStyles["celt"]["endLeft"] = new wallElement("endLeft");
    260     this.wallStyles["celt"]["endLeft"].entity = "structures/celt_wall_tower";
    261     this.wallStyles["celt"]["endLeft"].angle = PI;
    262     this.wallStyles["celt"]["endLeft"].width = 0.7;
    263    
    264     this.wallStyles["celt"]["cornerIn"] = new wallElement("cornerIn");
    265     this.wallStyles["celt"]["cornerIn"].entity = "structures/celt_wall_tower";
    266     this.wallStyles["celt"]["cornerIn"].angle = PI;
    267     this.wallStyles["celt"]["cornerIn"].width = 0.7;
    268     this.wallStyles["celt"]["cornerIn"].indent = 0;
    269     this.wallStyles["celt"]["cornerIn"].bending = PI/2;
    270    
    271     this.wallStyles["celt"]["cornerOut"] = new wallElement("cornerOut");
    272     this.wallStyles["celt"]["cornerOut"].entity = "structures/celt_wall_tower";
    273     this.wallStyles["celt"]["cornerOut"].angle = PI;
    274     this.wallStyles["celt"]["cornerOut"].width = 0.7;
    275     this.wallStyles["celt"]["cornerOut"].indent = 0;
    276     this.wallStyles["celt"]["cornerOut"].bending = -PI/2;
    277    
    278     this.wallStyles["celt"]["barracks"] = new wallElement("barracks");
    279     this.wallStyles["celt"]["barracks"].entity = "structures/celt_barracks";
    280     this.wallStyles["celt"]["barracks"].angle = PI;
    281     this.wallStyles["celt"]["barracks"].indent = 7;
    282    
    283     // Wall style 'hele'
    284     this.wallStyles["hele"] = {};
    285     this.wallStyles["hele"]["wall"] = new wallElement("wall");
    286     this.wallStyles["hele"]["wall"].entity = "structures/hele_wall";
    287     this.wallStyles["hele"]["wall"].angle = 0*PI;
    288     this.wallStyles["hele"]["wall"].width = 5.95;
    289    
    290     this.wallStyles["hele"]["tower"] = new wallElement("tower");
    291     this.wallStyles["hele"]["tower"].entity = "structures/hele_wall_tower";
    292     this.wallStyles["hele"]["tower"].angle = PI;
    293     this.wallStyles["hele"]["tower"].width = 1.5;
    294    
    295     this.wallStyles["hele"]["wallFort"] = new wallElement("wallFort");
    296     this.wallStyles["hele"]["wallFort"].entity = "structures/hele_fortress";
    297     this.wallStyles["hele"]["wallFort"].angle = 2*PI/2; // PI/2
    298     this.wallStyles["hele"]["wallFort"].width = 5.1; // 5.6
    299     this.wallStyles["hele"]["wallFort"].indent = 1.9; // 1.9
    300    
    301     this.wallStyles["hele"]["outpost"] = new wallElement("outpost");
    302     this.wallStyles["hele"]["outpost"].entity = "structures/hele_outpost";
    303     this.wallStyles["hele"]["outpost"].angle = PI;
    304     this.wallStyles["hele"]["outpost"].indent = -5;
    305    
    306     this.wallStyles["hele"]["house"] = new wallElement("house");
    307     this.wallStyles["hele"]["house"].entity = "structures/hele_house";
    308     this.wallStyles["hele"]["house"].angle = PI/2;
    309     this.wallStyles["hele"]["house"].indent = 6;
    310    
    311     this.wallStyles["hele"]["gate"] = new wallElement("gate");
    312     this.wallStyles["hele"]["gate"].entity = "structures/hele_wall_gate";
    313     this.wallStyles["hele"]["gate"].angle = 0*PI;
    314     this.wallStyles["hele"]["gate"].width = 9.1;
    315    
    316     this.wallStyles["hele"]["entry"] = new wallElement("entry");
    317     this.wallStyles["hele"]["entry"].entity = "structures/hele_defense_tower";
    318     this.wallStyles["hele"]["entry"].angle = PI;
    319     this.wallStyles["hele"]["entry"].width = 9.1;
    320     this.wallStyles["hele"]["entry"].indent = -4;
    321    
    322     this.wallStyles["hele"]["wideEntry"] = new wallElement("wideEntry");
    323     this.wallStyles["hele"]["wideEntry"].entity = "structures/hele_fortress";
    324     this.wallStyles["hele"]["wideEntry"].angle = 5*PI/2;
    325     this.wallStyles["hele"]["wideEntry"].width = 12;
    326     this.wallStyles["hele"]["wideEntry"].indent = 7;
    327    
    328     this.wallStyles["hele"]["endRight"] = new wallElement("endRight");
    329     this.wallStyles["hele"]["endRight"].entity = "structures/hele_wall_tower";
    330     this.wallStyles["hele"]["endRight"].angle = PI;
    331     this.wallStyles["hele"]["endRight"].width = 1.5;
    332    
    333     this.wallStyles["hele"]["endLeft"] = new wallElement("endLeft");
    334     this.wallStyles["hele"]["endLeft"].entity = "structures/hele_wall_tower";
    335     this.wallStyles["hele"]["endLeft"].angle = PI;
    336     this.wallStyles["hele"]["endLeft"].width = 1.5;
    337    
    338     this.wallStyles["hele"]["cornerIn"] = new wallElement("cornerIn");
    339     this.wallStyles["hele"]["cornerIn"].entity = "structures/hele_wall_tower";
    340     this.wallStyles["hele"]["cornerIn"].angle = 5*PI/4;
    341     this.wallStyles["hele"]["cornerIn"].width = 0;
    342     this.wallStyles["hele"]["cornerIn"].indent = 0.5;
    343     this.wallStyles["hele"]["cornerIn"].bending = PI/2;
    344    
    345     this.wallStyles["hele"]["cornerOut"] = new wallElement("cornerOut");
    346     this.wallStyles["hele"]["cornerOut"].entity = "structures/hele_wall_tower";
    347     this.wallStyles["hele"]["cornerOut"].angle = 3*PI/4;
    348     this.wallStyles["hele"]["cornerOut"].width = 1;
    349     this.wallStyles["hele"]["cornerOut"].bending = -PI/2;
    350    
    351     this.wallStyles["hele"]["barracks"] = new wallElement("barracks");
    352     this.wallStyles["hele"]["barracks"].entity = "structures/hele_barracks";
    353     this.wallStyles["hele"]["barracks"].angle = PI;
    354     this.wallStyles["hele"]["barracks"].indent = 6;
    355    
    356     // Wall style 'iber'
    357     this.wallStyles["iber"] = {};
    358     this.wallStyles["iber"]["wall"] = new wallElement("wall");
    359     this.wallStyles["iber"]["wall"].entity = "structures/iber_wall";
    360     this.wallStyles["iber"]["wall"].angle = 0*PI;
    361     this.wallStyles["iber"]["wall"].width = 6.9;
    362    
    363     this.wallStyles["iber"]["tower"] = new wallElement("tower");
    364     this.wallStyles["iber"]["tower"].entity = "structures/iber_wall_tower";
    365     this.wallStyles["iber"]["tower"].angle = PI;
    366     this.wallStyles["iber"]["tower"].width = 2.1;
    367    
    368     this.wallStyles["iber"]["wallFort"] = new wallElement("wallFort");
    369     this.wallStyles["iber"]["wallFort"].entity = "structures/iber_fortress";
    370     this.wallStyles["iber"]["wallFort"].angle = PI;
    371     this.wallStyles["iber"]["wallFort"].width = 4.5;
    372     this.wallStyles["iber"]["wallFort"].indent = 0.7;
    373    
    374     this.wallStyles["iber"]["outpost"] = new wallElement("outpost");
    375     this.wallStyles["iber"]["outpost"].entity = "structures/iber_outpost";
    376     this.wallStyles["iber"]["outpost"].angle = PI;
    377     this.wallStyles["iber"]["outpost"].indent = -5;
    378    
    379     this.wallStyles["iber"]["house"] = new wallElement("house");
    380     this.wallStyles["iber"]["house"].entity = "structures/iber_house";
    381     this.wallStyles["iber"]["house"].angle = PI;
    382     this.wallStyles["iber"]["house"].indent = 4;
    383    
    384     this.wallStyles["iber"]["gate"] = new wallElement("gate");
    385     this.wallStyles["iber"]["gate"].entity = "structures/iber_wall_gate";
    386     this.wallStyles["iber"]["gate"].angle = 0*PI;
    387     this.wallStyles["iber"]["gate"].width = 9.2;
    388    
    389     this.wallStyles["iber"]["entry"] = new wallElement("entry");
    390     this.wallStyles["iber"]["entry"].entity = "structures/iber_wall_tower";
    391     this.wallStyles["iber"]["entry"].angle = PI;
    392     this.wallStyles["iber"]["entry"].width = 6.9;
    393     this.wallStyles["iber"]["entry"].indent = -5;
    394    
    395     this.wallStyles["iber"]["wideEntry"] = new wallElement("wideEntry");
    396     this.wallStyles["iber"]["wideEntry"].entity = "structures/iber_fortress";
    397     this.wallStyles["iber"]["wideEntry"].angle = PI/2;
    398     this.wallStyles["iber"]["wideEntry"].width = 9.2;
    399     this.wallStyles["iber"]["wideEntry"].indent = 7;
    400    
    401     this.wallStyles["iber"]["endRight"] = new wallElement("endRight");
    402     this.wallStyles["iber"]["endRight"].entity = "structures/iber_wall_tower";
    403     this.wallStyles["iber"]["endRight"].angle = PI;
    404     this.wallStyles["iber"]["endRight"].width = 2.1;
    405    
    406     this.wallStyles["iber"]["endLeft"] = new wallElement("endLeft");
    407     this.wallStyles["iber"]["endLeft"].entity = "structures/iber_wall_tower";
    408     this.wallStyles["iber"]["endLeft"].angle = PI;
    409     this.wallStyles["iber"]["endLeft"].width = 2.1;
    410    
    411     this.wallStyles["iber"]["cornerIn"] = new wallElement("cornerIn");
    412     this.wallStyles["iber"]["cornerIn"].entity = "structures/iber_wall_tower";
    413     this.wallStyles["iber"]["cornerIn"].angle = PI;
    414     this.wallStyles["iber"]["cornerIn"].width = 2.1;
    415     this.wallStyles["iber"]["cornerIn"].bending = PI/2;
    416    
    417     this.wallStyles["iber"]["cornerIn2"] = new wallElement("cornerIn2");
    418     this.wallStyles["iber"]["cornerIn2"].entity = "structures/iber_defense_tower";
    419     this.wallStyles["iber"]["cornerIn2"].angle = 5*PI/4;
    420     this.wallStyles["iber"]["cornerIn2"].width = 1;
    421     this.wallStyles["iber"]["cornerIn2"].indent = 0.2;
    422     this.wallStyles["iber"]["cornerIn2"].bending = PI/2;
    423    
    424     this.wallStyles["iber"]["cornerIn3"] = new wallElement("cornerIn3");
    425     this.wallStyles["iber"]["cornerIn3"].entity = "structures/iber_wall_tower";
    426     this.wallStyles["iber"]["cornerIn3"].angle = 5*PI/4;
    427     this.wallStyles["iber"]["cornerIn3"].width = 0.3;
    428     this.wallStyles["iber"]["cornerIn3"].indent = 0.5;
    429     this.wallStyles["iber"]["cornerIn3"].bending = PI/2;
    430    
    431     this.wallStyles["iber"]["cornerOut"] = new wallElement("cornerOut");
    432     this.wallStyles["iber"]["cornerOut"].entity = "structures/iber_wall_tower";
    433     this.wallStyles["iber"]["cornerOut"].angle = 3*PI/4;
    434     this.wallStyles["iber"]["cornerOut"].width = 1.3;
    435     this.wallStyles["iber"]["cornerOut"].indent = 0;
    436     this.wallStyles["iber"]["cornerOut"].bending = -PI/2;
    437    
    438     this.wallStyles["iber"]["barracks"] = new wallElement("barracks");
    439     this.wallStyles["iber"]["barracks"].entity = "structures/iber_barracks";
    440     this.wallStyles["iber"]["barracks"].angle = PI;
    441     this.wallStyles["iber"]["barracks"].indent = 7;
    442    
    443     // Wall style 'pers'
    444     this.wallStyles["pers"] = {};
    445     this.wallStyles["pers"]["wall"] = new wallElement("wall");
    446     this.wallStyles["pers"]["wall"].entity = "structures/pers_wall";
    447     this.wallStyles["pers"]["wall"].angle = 0*PI;
    448     this.wallStyles["pers"]["wall"].width = 5.9;
    449    
    450     this.wallStyles["pers"]["tower"] = new wallElement("tower");
    451     this.wallStyles["pers"]["tower"].entity = "structures/pers_wall_tower";
    452     this.wallStyles["pers"]["tower"].angle = PI;
    453     this.wallStyles["pers"]["tower"].width = 1.7;
    454    
    455     this.wallStyles["pers"]["wallFort"] = new wallElement("wallFort");
    456     this.wallStyles["pers"]["wallFort"].entity = "structures/pers_fortress";
    457     this.wallStyles["pers"]["wallFort"].angle = PI;
    458     this.wallStyles["pers"]["wallFort"].width = 5.6; // 5.5
    459     this.wallStyles["pers"]["wallFort"].indent = 1.9; // 1.7
    460    
    461     this.wallStyles["pers"]["outpost"] = new wallElement("outpost");
    462     this.wallStyles["pers"]["outpost"].entity = "structures/pers_outpost";
    463     this.wallStyles["pers"]["outpost"].angle = PI;
    464     this.wallStyles["pers"]["outpost"].indent = -5;
    465    
    466     this.wallStyles["pers"]["house"] = new wallElement("house");
    467     this.wallStyles["pers"]["house"].entity = "structures/pers_house";
    468     this.wallStyles["pers"]["house"].angle = PI;
    469     this.wallStyles["pers"]["house"].indent = 6;
    470    
    471     this.wallStyles["pers"]["gate"] = new wallElement("gate");
    472     this.wallStyles["pers"]["gate"].entity = "structures/pers_wall_gate";
    473     this.wallStyles["pers"]["gate"].angle = 0*PI;
    474     this.wallStyles["pers"]["gate"].width = 6;
    475    
    476     this.wallStyles["pers"]["entry"] = new wallElement("entry");
    477     this.wallStyles["pers"]["entry"].entity = "structures/pers_defense_tower";
    478     this.wallStyles["pers"]["entry"].angle = PI;
    479     this.wallStyles["pers"]["entry"].width = 6;
    480     this.wallStyles["pers"]["entry"].indent = -4;
    481    
    482     this.wallStyles["pers"]["wideEntry"] = new wallElement("wideEntry");
    483     this.wallStyles["pers"]["wideEntry"].entity = "structures/pers_fortress";
    484     this.wallStyles["pers"]["wideEntry"].angle = PI;
    485     this.wallStyles["pers"]["wideEntry"].width = 12;
    486     this.wallStyles["pers"]["wideEntry"].indent = 7;
    487    
    488     this.wallStyles["pers"]["endRight"] = new wallElement("endRight");
    489     this.wallStyles["pers"]["endRight"].entity = "structures/pers_wall_tower";
    490     this.wallStyles["pers"]["endRight"].angle = PI;
    491     this.wallStyles["pers"]["endRight"].width = 1.7;
    492    
    493     this.wallStyles["pers"]["endLeft"] = new wallElement("endLeft");
    494     this.wallStyles["pers"]["endLeft"].entity = "structures/pers_wall_tower";
    495     this.wallStyles["pers"]["endLeft"].angle = PI;
    496     this.wallStyles["pers"]["endLeft"].width = 1.7;
    497    
    498     this.wallStyles["pers"]["cornerIn"] = new wallElement("cornerIn");
    499     this.wallStyles["pers"]["cornerIn"].entity = "structures/pers_wall_tower";
    500     this.wallStyles["pers"]["cornerIn"].angle = 5*PI/4;
    501     this.wallStyles["pers"]["cornerIn"].width = 0.2;
    502     this.wallStyles["pers"]["cornerIn"].indent = 0.5;
    503     this.wallStyles["pers"]["cornerIn"].bending = PI/2;
    504    
    505     this.wallStyles["pers"]["cornerOut"] = new wallElement("cornerOut");
    506     this.wallStyles["pers"]["cornerOut"].entity = "structures/pers_wall_tower";
    507     this.wallStyles["pers"]["cornerOut"].angle = 3*PI/4;
    508     this.wallStyles["pers"]["cornerOut"].width = 0.8;
    509     this.wallStyles["pers"]["cornerOut"].indent = 0;
    510     this.wallStyles["pers"]["cornerOut"].bending = -PI/2;
    511    
    512     this.wallStyles["pers"]["barracks"] = new wallElement("barracks");
    513     this.wallStyles["pers"]["barracks"].entity = "structures/pers_barracks";
    514     this.wallStyles["pers"]["barracks"].angle = PI;
    515     this.wallStyles["pers"]["barracks"].indent = 7;
    516    
    517     // Wall style 'rome'
    518     this.wallStyles["rome"] = {};
    519     this.wallStyles["rome"]["wall"] = new wallElement("wall");
    520     this.wallStyles["rome"]["wall"].entity = "structures/rome_wall";
    521     this.wallStyles["rome"]["wall"].angle = 0*PI;
    522     this.wallStyles["rome"]["wall"].width = 5.9;
    523    
    524     this.wallStyles["rome"]["tower"] = new wallElement("tower");
    525     this.wallStyles["rome"]["tower"].entity = "structures/rome_wall_tower";
    526     this.wallStyles["rome"]["tower"].angle = PI;
    527     this.wallStyles["rome"]["tower"].width = 2.1;
    528    
    529     this.wallStyles["rome"]["wallFort"] = new wallElement("wallFort");
    530     this.wallStyles["rome"]["wallFort"].entity = "structures/rome_fortress";
    531     this.wallStyles["rome"]["wallFort"].angle = PI;
    532     this.wallStyles["rome"]["wallFort"].width = 6.3;
    533     this.wallStyles["rome"]["wallFort"].indent = 2.1;
    534    
    535     this.wallStyles["rome"]["outpost"] = new wallElement("outpost");
    536     this.wallStyles["rome"]["outpost"].entity = "structures/rome_outpost";
    537     this.wallStyles["rome"]["outpost"].angle = PI;
    538     this.wallStyles["rome"]["outpost"].indent = -5;
    539    
    540     this.wallStyles["rome"]["house"] = new wallElement("house");
    541     this.wallStyles["rome"]["house"].entity = "structures/rome_house";
    542     this.wallStyles["rome"]["house"].angle = PI;
    543     this.wallStyles["rome"]["house"].indent = 7;
    544    
    545     this.wallStyles["rome"]["gate"] = new wallElement("gate");
    546     this.wallStyles["rome"]["gate"].entity = "structures/rome_wall_gate";
    547     this.wallStyles["rome"]["gate"].angle = 0*PI;
    548     this.wallStyles["rome"]["gate"].width = 5.9;
    549    
    550     this.wallStyles["rome"]["entry"] = new wallElement("entry");
    551     this.wallStyles["rome"]["entry"].entity = "structures/rome_defense_tower";
    552     this.wallStyles["rome"]["entry"].angle = PI;
    553     this.wallStyles["rome"]["entry"].width = 5.9;
    554     this.wallStyles["rome"]["entry"].indent = -4;
    555    
    556     this.wallStyles["rome"]["wideEntry"] = new wallElement("wideEntry");
    557     this.wallStyles["rome"]["wideEntry"].entity = "structures/rome_fortress";
    558     this.wallStyles["rome"]["wideEntry"].angle = PI;
    559     this.wallStyles["rome"]["wideEntry"].width = 12;
    560     this.wallStyles["rome"]["wideEntry"].indent = 7;
    561    
    562     this.wallStyles["rome"]["endRight"] = new wallElement("endRight");
    563     this.wallStyles["rome"]["endRight"].entity = "structures/rome_wall_tower";
    564     this.wallStyles["rome"]["endRight"].angle = PI;
    565     this.wallStyles["rome"]["endRight"].width = 2.1;
    566    
    567     this.wallStyles["rome"]["endLeft"] = new wallElement("endLeft");
    568     this.wallStyles["rome"]["endLeft"].entity = "structures/rome_wall_tower";
    569     this.wallStyles["rome"]["endLeft"].angle = PI;
    570     this.wallStyles["rome"]["endLeft"].width = 2.1;
    571    
    572     this.wallStyles["rome"]["cornerIn"] = new wallElement("cornerIn");
    573     this.wallStyles["rome"]["cornerIn"].entity = "structures/rome_wall_tower";
    574     this.wallStyles["rome"]["cornerIn"].angle = 5*PI/4;
    575     this.wallStyles["rome"]["cornerIn"].width = 0;
    576     this.wallStyles["rome"]["cornerIn"].indent = 0.7;
    577     this.wallStyles["rome"]["cornerIn"].bending = PI/2;
    578    
    579     this.wallStyles["rome"]["cornerOut"] = new wallElement("cornerOut");
    580     this.wallStyles["rome"]["cornerOut"].entity = "structures/rome_wall_tower";
    581     this.wallStyles["rome"]["cornerOut"].angle = 3*PI/4;
    582     this.wallStyles["rome"]["cornerOut"].width = 1.1; // 1.4
    583     this.wallStyles["rome"]["cornerOut"].indent = 0;
    584     this.wallStyles["rome"]["cornerOut"].bending = -PI/2;
    585    
    586     this.wallStyles["rome"]["barracks"] = new wallElement("barracks");
    587     this.wallStyles["rome"]["barracks"].entity = "structures/rome_barracks";
    588     this.wallStyles["rome"]["barracks"].angle = PI;
    589     this.wallStyles["rome"]["barracks"].indent = 6;
    590    
    591     // Setup some default fortress types
    592     // General default fortress types
    593     this.fortressTypes["tiny"] = new fortress("tiny");
    594     var wallPart = ['entry', 'endLeft', 'wall', 'cornerIn', 'wall', 'endRight'];
    595     var parts = 4;
    596     for (var part = 0; part < parts; part++)
    597     {
    598         for (var wallIndex = 0; wallIndex < wallPart.length; wallIndex++)
    599             this.fortressTypes["tiny"].wall.push(wallPart[wallIndex])
    600     };
    601    
    602     this.fortressTypes["small"] = new fortress("small");
    603     var wallPart = ['entry', 'endLeft', 'wall', 'tower', 'wall',
    604         'cornerIn', 'wall', 'tower', 'wall', 'endRight'];
    605     var parts = 4;
    606     for (var part = 0; part < parts; part++)
    607     {
    608         for (var wallIndex = 0; wallIndex < wallPart.length; wallIndex++)
    609             this.fortressTypes["small"].wall.push(wallPart[wallIndex])
    610     };
    611    
    612     this.fortressTypes["medium"] = new fortress("medium");
    613     var wallPart = ['entry', 'endLeft', 'wall', 'tower', 'wall', 'cornerIn', 'wall',
    614         'cornerOut', 'wall', 'cornerIn', 'wall', 'tower', 'wall', 'endRight'];
    615     var parts = 4;
    616     for (var part = 0; part < parts; part++)
    617     {
    618         for (var wallIndex = 0; wallIndex < wallPart.length; wallIndex++)
    619             this.fortressTypes["medium"].wall.push(wallPart[wallIndex])
    620     };
    621    
    622     this.fortressTypes["normal"] = new fortress("normal");
    623     var wallPart = ['entry', 'endLeft', 'wall', 'tower', 'wall', 'outpost', 'wall', 'cornerIn', 'wall',
    624         'cornerOut', 'wall', 'cornerIn', 'wall', 'outpost', 'wall', 'tower', 'wall', 'endRight'];
    625     var parts = 4;
    626     for (var part = 0; part < parts; part++)
    627     {
    628         for (var wallIndex = 0; wallIndex < wallPart.length; wallIndex++)
    629             this.fortressTypes["normal"].wall.push(wallPart[wallIndex])
    630     };
    631    
    632     this.fortressTypes["large"] = new fortress("large");
    633     var wallPart = ['entry', 'endLeft', 'wall', 'tower', 'wall', 'outpost', 'wall', 'cornerIn', 'wall', 'tower', 'wall',
    634         'cornerOut', 'wall', 'tower', 'wall', 'cornerIn', 'wall', 'outpost', 'wall', 'tower', 'wall', 'endRight'];
    635     var parts = 4;
    636     for (var part = 0; part < parts; part++)
    637     {
    638         for (var wallIndex = 0; wallIndex < wallPart.length; wallIndex++)
    639             this.fortressTypes["large"].wall.push(wallPart[wallIndex])
    640     };
    641    
    642     this.fortressTypes["very large"] = new fortress("very large");
    643     var wallPart = ['entry', 'endLeft', 'wall', 'tower', 'wall', 'outpost', 'wall',
    644         'tower', 'gate', 'tower', 'wall', 'cornerIn', 'wall', 'tower', 'wall',
    645         'cornerOut', 'wall', 'tower', 'wall', 'cornerIn', 'wall', 'tower', 'gate',
    646         'tower', 'wall', 'outpost', 'wall', 'tower', 'wall', 'endRight'];
    647     var parts = 4;
    648     for (var part = 0; part < parts; part++)
    649     {
    650         for (var wallIndex = 0; wallIndex < wallPart.length; wallIndex++)
    651             this.fortressTypes["very large"].wall.push(wallPart[wallIndex])
    652     };
    653    
    654     this.fortressTypes["giant"] = new fortress("giant");
    655     var wallPart = ['entry', 'endLeft', 'wall', 'tower', 'wall', 'outpost', 'wall', 'tower',
    656         'gate', 'tower', 'wall', 'cornerIn', 'wall', 'outpost', 'wall', 'tower', 'wall',
    657         'cornerOut', 'wall', 'tower', 'wall', 'outpost', 'wall', 'cornerIn', 'wall', 'tower',
    658         'gate', 'tower', 'wall', 'outpost', 'wall', 'tower', 'wall', 'endRight'];
    659     var parts = 4;
    660     for (var part = 0; part < parts; part++)
    661     {
    662         for (var wallIndex = 0; wallIndex < wallPart.length; wallIndex++)
    663             this.fortressTypes["giant"].wall.push(wallPart[wallIndex])
    664     };
    665    
    666     this.fortressTypes["demo"] = new fortress("demo");
    667     var wallPart = ['entry', 'endLeft', 'wall', 'tower', 'wall', 'wallFort', 'wall', 'tower', 'gate', 'tower', 'wall', 'outpost',
    668         'wall', 'cornerIn', 'wall', 'outpost', 'wall', 'endRight', 'wideEntry', 'endLeft', 'wall', 'tower', 'wall',
    669         'cornerOut', 'wall', 'tower', 'wall', 'endRight', 'wideEntry', 'endLeft', 'wall', 'outpost', 'wall', 'cornerIn',
    670         'wall', 'outpost', 'wall', 'tower', 'gate', 'tower', 'wall', 'wallFort', 'wall', 'tower', 'wall', 'endRight'];
    671     var parts = 4;
    672     for (var part = 0; part < parts; part++)
    673     {
    674         for (var wallIndex = 0; wallIndex < wallPart.length; wallIndex++)
    675             this.fortressTypes["demo"].wall.push(wallPart[wallIndex])
    676     };
    677    
    678     // Default civ dependent fortresses for Spahbod
    679     this.fortressTypes["cartSB"] = new fortress("cartSB");
    680     this.fortressTypes["cartSB"].wall = ['entry', 'wall', 'wall',
    681         'cornerIn', 'wall', 'barracks', 'wall', 'gate', 'wall', 'wall',
    682         'cornerIn', 'wall', 'house', 'wall', 'entry', 'wall', 'wall',
    683         'cornerIn', 'wall', 'house', 'wall', 'gate', 'wall', 'wall',
    684         'cornerIn', 'wall', 'house', 'wall'];
    685     this.fortressTypes["celtSB"] = new fortress("celtSB");
    686     this.fortressTypes["celtSB"].wall = ['entry', 'wall', 'wall',
    687         'cornerIn', 'wall', 'barracks', 'wall', 'gate', 'wall', 'house', 'wall',
    688         'cornerIn', 'wall', 'house', 'wall', 'entry', 'wall', 'house', 'wall',
    689         'cornerIn', 'wall', 'house', 'wall', 'gate', 'wall', 'house', 'wall',
    690         'cornerIn', 'wall', 'house', 'wall'];
    691     this.fortressTypes["iberSB"] = this.fortressTypes["celtSB"];
    692     this.fortressTypes["heleSB"] = this.fortressTypes["cartSB"];
    693     this.fortressTypes["persSB"] = this.fortressTypes["cartSB"];
    694     this.fortressTypes["romeSB"] = this.fortressTypes["cartSB"];
    695    
    696     // Setup style
    697     this.setStyle(this.style);
    698    
    699     // Setup fortress type if preasent
    700     if (this.fortress !== false && this.fortress !== undefined)
    701         this.setFortressType(this.fortress);
    702 };
    70380
    704 wallTool.prototype.setStyle = function(style)
     81////////////////////////////////////////////////////
     82// Setup data structure for some default wall styles
     83////////////////////////////////////////////////////
     84
     85// A wall style is an associative array with all wall elements of that style in it associated with the wall element type string.
     86// 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'...
     87var wallStyles = {};
     88// Add civilisation wall style 'cart'
     89wallStyles['cart'] = {};
     90wallStyles['cart']['wall'] = new WallElement('wall', 'structures/cart_wall', 0*PI, 6.2);
     91wallStyles['cart']['tower'] = new WallElement('tower', 'structures/cart_wall_tower', PI, 2.7);
     92wallStyles['cart']['wallFort'] = new WallElement('wallFort', 'structures/cart_fortress', PI, 5.1, 1.6);
     93wallStyles['cart']['gate'] = new WallElement('gate', 'structures/cart_wall_gate', 0*PI, 6.2);
     94wallStyles['cart']['entry'] = new WallElement('entry', undefined, wallStyles['cart']['gate'].angle, wallStyles['cart']['gate'].width);
     95wallStyles['cart']['entryTower'] = new WallElement('entryTower', 'structures/cart_defense_tower', PI, 6.2, -5);
     96wallStyles['cart']['entryFort'] = new WallElement('entryFort', 'structures/cart_fortress', PI, 12, 7);
     97wallStyles['cart']['endRight'] = new WallElement('endRight', wallStyles['cart']['tower'].entity, wallStyles['cart']['tower'].angle, wallStyles['cart']['tower'].width);
     98wallStyles['cart']['endLeft'] = new WallElement('endLeft', wallStyles['cart']['tower'].entity, wallStyles['cart']['tower'].angle, wallStyles['cart']['tower'].width);
     99wallStyles['cart']['cornerIn'] = new WallElement('cornerIn', 'structures/cart_wall_tower', 5*PI/4, 0, 0.8, PI/2);
     100wallStyles['cart']['cornerOut'] = new WallElement('cornerOut', 'structures/cart_wall_tower', 3*PI/4, 1.3 /*1.6*/, 0, -PI/2);
     101wallStyles['cart']['outpost'] = new WallElement('outpost', 'structures/cart_outpost', PI, 0, -5);
     102wallStyles['cart']['house'] = new WallElement('house', 'structures/cart_house', PI, 0, 7);
     103wallStyles['cart']['barracks'] = new WallElement('barracks', 'structures/cart_barracks', PI, 0, 7);
     104// Add civilisation wall style 'celt'
     105wallStyles['celt'] = {};
     106wallStyles['celt']['wall'] = new WallElement('wall', 'structures/celt_wall', 0*PI, 5.9);
     107wallStyles['celt']['tower'] = new WallElement('tower', 'structures/celt_wall_tower', PI, 1.9);
     108wallStyles['celt']['wallFort'] = new WallElement('wallFort', 'structures/celt_fortress_g', PI, 4.2, 1.5);
     109wallStyles['celt']['gate'] = new WallElement('gate', 'structures/celt_wall_gate', 0*PI, 5.6);
     110wallStyles['celt']['entry'] = new WallElement('entry', undefined, wallStyles['celt']['gate'].angle, wallStyles['celt']['gate'].width);
     111wallStyles['celt']['entryTower'] = new WallElement('entryTower', 'structures/celt_defense_tower', PI, 6, -5);
     112wallStyles['celt']['entryFort'] = new WallElement('entryFort', 'structures/celt_fortress_b', PI, 8, 5);
     113wallStyles['celt']['endRight'] = new WallElement('endRight', wallStyles['celt']['tower'].entity, wallStyles['celt']['tower'].angle, wallStyles['celt']['tower'].width);
     114wallStyles['celt']['endLeft'] = new WallElement('endLeft', wallStyles['celt']['tower'].entity, wallStyles['celt']['tower'].angle, wallStyles['celt']['tower'].width);
     115wallStyles['celt']['cornerIn'] = new WallElement('cornerIn', 'structures/celt_wall_tower', 5*PI/4, 0, 0.7, PI/2);
     116wallStyles['celt']['cornerOut'] = new WallElement('cornerOut', 'structures/celt_wall_tower', 3*PI/4, 1.3, 0, -PI/2);
     117wallStyles['celt']['outpost'] = new WallElement('outpost', 'structures/celt_outpost', PI, 0, -5);
     118wallStyles['celt']['house'] = new WallElement('house', 'structures/celt_house', PI, 0, 3);
     119wallStyles['celt']['barracks'] = new WallElement('barracks', 'structures/celt_barracks', PI, 0, 7);
     120// Add civilisation wall style 'hele'
     121wallStyles['hele'] = {};
     122wallStyles['hele']['wall'] = new WallElement('wall', 'structures/hele_wall', 0*PI, 5.95);
     123wallStyles['hele']['tower'] = new WallElement('tower', 'structures/hele_wall_tower', PI, 1.5);
     124wallStyles['hele']['wallFort'] = new WallElement('wallFort', 'structures/hele_fortress', 2*PI/2 /* PI/2 */, 5.1 /* 5.6 */, 1.9 /* 1.9 */);
     125wallStyles['hele']['gate'] = new WallElement('gate', 'structures/hele_wall_gate', 0*PI, 9.1);
     126wallStyles['hele']['entry'] = new WallElement('entry', undefined, wallStyles['hele']['gate'].angle, wallStyles['hele']['gate'].width);
     127wallStyles['hele']['entryTower'] = new WallElement('entry', 'structures/hele_defense_tower', PI, 9.1, -5);
     128wallStyles['hele']['entryFort'] = new WallElement('entryFort', 'structures/hele_fortress', 5*PI/2, 12, 7);
     129wallStyles['hele']['endRight'] = new WallElement('endRight', wallStyles['hele']['tower'].entity, wallStyles['hele']['tower'].angle, wallStyles['hele']['tower'].width);
     130wallStyles['hele']['endLeft'] = new WallElement('endLeft', wallStyles['hele']['tower'].entity, wallStyles['hele']['tower'].angle, wallStyles['hele']['tower'].width);
     131wallStyles['hele']['cornerIn'] = new WallElement('cornerIn', 'structures/hele_wall_tower', 5*PI/4, 0, 0.5, PI/2);
     132wallStyles['hele']['cornerOut'] = new WallElement('cornerOut', 'structures/hele_wall_tower', 3*PI/4, 1, 0, -PI/2);
     133wallStyles['hele']['outpost'] = new WallElement('outpost', 'structures/hele_outpost', PI, 0, -5);
     134wallStyles['hele']['house'] = new WallElement('house', 'structures/hele_house', 3*PI/2, 0, 6);
     135wallStyles['hele']['barracks'] = new WallElement('barracks', 'structures/hele_barracks', PI, 0, 6);
     136// Add civilisation wall style 'iber'
     137wallStyles['iber'] = {};
     138wallStyles['iber']['wall'] = new WallElement('wall', 'structures/iber_wall', 0*PI, 6);
     139wallStyles['iber']['tower'] = new WallElement('tower', 'structures/iber_wall_tower', PI, 1.7);
     140wallStyles['iber']['wallFort'] = new WallElement('wallFort', 'structures/iber_fortress', PI, 4.6, 0.7);
     141wallStyles['iber']['gate'] = new WallElement('gate', 'structures/iber_wall_gate', 0*PI, 7.9);
     142wallStyles['iber']['entry'] = new WallElement('entry', undefined, wallStyles['iber']['gate'].angle, wallStyles['iber']['gate'].width);
     143wallStyles['iber']['entryTower'] = new WallElement('entryTower', 'structures/iber_wall_tower', PI, 6.9, -5);
     144wallStyles['iber']['entryFort'] = new WallElement('entryFort', 'structures/iber_fortress', PI/2, 12, 7);
     145wallStyles['iber']['endRight'] = new WallElement('endRight', wallStyles['iber']['tower'].entity, wallStyles['iber']['tower'].angle, wallStyles['iber']['tower'].width);
     146wallStyles['iber']['endLeft'] = new WallElement('endLeft', wallStyles['iber']['tower'].entity, wallStyles['iber']['tower'].angle, wallStyles['iber']['tower'].width);
     147wallStyles['iber']['cornerIn'] = new WallElement('cornerIn', 'structures/iber_wall_tower', 5*PI/4, 1.7, 0, PI/2);
     148wallStyles['iber']['cornerOut'] = new WallElement('cornerOut', 'structures/iber_wall_tower', 3*PI/4, 1.7, 0, -PI/2);
     149wallStyles['iber']['outpost'] = new WallElement('outpost', 'structures/iber_outpost', PI, 0, -5);
     150wallStyles['iber']['house'] = new WallElement('house', 'structures/iber_house', PI, 0, 4);
     151wallStyles['iber']['barracks'] = new WallElement('barracks', 'structures/iber_barracks', PI, 0, 7);
     152// Add civilisation wall style 'pers'
     153wallStyles['pers'] = {};
     154wallStyles['pers']['wall'] = new WallElement('wall', 'structures/pers_wall', 0*PI, 5.9);
     155wallStyles['pers']['tower'] = new WallElement('tower', 'structures/pers_wall_tower', PI, 1.7);
     156wallStyles['pers']['wallFort'] = new WallElement('wallFort', 'structures/pers_fortress', PI, 5.6/*5.5*/, 1.9/*1.7*/);
     157wallStyles['pers']['gate'] = new WallElement('gate', 'structures/pers_wall_gate', 0*PI, 6);
     158wallStyles['pers']['entry'] = new WallElement('entry', undefined, wallStyles['pers']['gate'].angle, wallStyles['pers']['gate'].width);
     159wallStyles['pers']['entryTower'] = new WallElement('entry', 'structures/pers_defense_tower', PI, 6, -5);
     160wallStyles['pers']['entryFort'] = new WallElement('entryFort', 'structures/pers_fortress', PI, 12, 7);
     161wallStyles['pers']['endRight'] = new WallElement('endRight', wallStyles['pers']['tower'].entity, wallStyles['pers']['tower'].angle, wallStyles['pers']['tower'].width);
     162wallStyles['pers']['endLeft'] = new WallElement('endLeft', wallStyles['pers']['tower'].entity, wallStyles['pers']['tower'].angle, wallStyles['pers']['tower'].width);
     163wallStyles['pers']['cornerIn'] = new WallElement('cornerIn', 'structures/pers_wall_tower', 5*PI/4, 0.2, 0.5, PI/2);
     164wallStyles['pers']['cornerOut'] = new WallElement('cornerOut', 'structures/pers_wall_tower', 3*PI/4, 0.8, 0, -PI/2);
     165wallStyles['pers']['outpost'] = new WallElement('outpost', 'structures/pers_outpost', PI, 0, -5);
     166wallStyles['pers']['house'] = new WallElement('house', 'structures/pers_house', PI, 0, 6);
     167wallStyles['pers']['barracks'] = new WallElement('barracks', 'structures/pers_barracks', PI, 0, 7);
     168// Add civilisation wall style 'rome'
     169wallStyles['rome'] = {};
     170wallStyles['rome']['wall'] = new WallElement('wall', 'structures/rome_wall', 0*PI, 5.9);
     171wallStyles['rome']['tower'] = new WallElement('tower', 'structures/rome_wall_tower', PI, 2.1);
     172wallStyles['rome']['wallFort'] = new WallElement('wallFort', 'structures/rome_fortress', PI, 6.3, 2.1);
     173wallStyles['rome']['gate'] = new WallElement('gate', 'structures/rome_wall_gate', 0*PI, 5.9);
     174wallStyles['rome']['entry'] = new WallElement('entry', undefined, wallStyles['rome']['gate'].angle, wallStyles['rome']['gate'].width);
     175wallStyles['rome']['entryTower'] = new WallElement('entryTower', 'structures/rome_defense_tower', PI, 5.9, -5);
     176wallStyles['rome']['entryFort'] = new WallElement('entryFort', 'structures/rome_fortress', PI, 12, 7);
     177wallStyles['rome']['endRight'] = new WallElement('endRight', wallStyles['rome']['tower'].entity, wallStyles['rome']['tower'].angle, wallStyles['rome']['tower'].width);
     178wallStyles['rome']['endLeft'] = new WallElement('endLeft', wallStyles['rome']['tower'].entity, wallStyles['rome']['tower'].angle, wallStyles['rome']['tower'].width);
     179wallStyles['rome']['cornerIn'] = new WallElement('cornerIn', 'structures/rome_wall_tower', 5*PI/4, 0, 0.7, PI/2);
     180wallStyles['rome']['cornerOut'] = new WallElement('cornerOut', 'structures/rome_wall_tower', 3*PI/4, 1.1, 0, -PI/2);
     181wallStyles['rome']['outpost'] = new WallElement('outpost', 'structures/rome_outpost', PI, 0, -5);
     182wallStyles['rome']['house'] = new WallElement('house', 'structures/rome_house', PI, 0, 7);
     183wallStyles['rome']['barracks'] = new WallElement('barracks', 'structures/rome_barracks', PI, 0, 6);
     184// Add special wall style 'romeSiege'
     185wallStyles['romeSiege'] = {};
     186wallStyles['romeSiege']['wall'] = new WallElement('wall', 'structures/rome_siege_wall', 0*PI, 6.2);
     187wallStyles['romeSiege']['tower'] = new WallElement('tower', 'structures/rome_siege_wall_tower', PI, 0);
     188wallStyles['romeSiege']['wallFort'] = new WallElement('wallFort', 'structures/rome_army_camp', PI, 7.2, 2);
     189wallStyles['romeSiege']['gate'] = new WallElement('gate', 'structures/rome_siege_wall_gate', 0*PI, 5.9);
     190wallStyles['romeSiege']['entry'] = new WallElement('entry', undefined, wallStyles['romeSiege']['gate'].angle, wallStyles['romeSiege']['gate'].width);
     191wallStyles['romeSiege']['entryTower'] = new WallElement('entryTower', 'structures/rome_defense_tower', PI, 5.9, -4);
     192wallStyles['romeSiege']['entryFort'] = new WallElement('entryFort', 'structures/rome_army_camp', PI, 12, 7);
     193wallStyles['romeSiege']['endRight'] = new WallElement('endRight', wallStyles['romeSiege']['tower'].entity, wallStyles['romeSiege']['tower'].angle, wallStyles['romeSiege']['tower'].width);
     194wallStyles['romeSiege']['endLeft'] = new WallElement('endLeft', wallStyles['romeSiege']['tower'].entity, wallStyles['romeSiege']['tower'].angle, wallStyles['romeSiege']['tower'].width);
     195wallStyles['romeSiege']['cornerIn'] = new WallElement('cornerIn', 'structures/rome_defense_tower', 5*PI/4, 0.1, 0.3, PI/2);
     196wallStyles['romeSiege']['cornerIn2'] = new WallElement('cornerIn2', undefined, 5*PI/4, -1.6, 0, PI/2); // Grafic glitch
     197wallStyles['romeSiege']['cornerOut'] = new WallElement('cornerOut', 'structures/rome_siege_wall_tower', 3*PI/4, 1.4, -0.2, -PI/2);
     198wallStyles['romeSiege']['outpost'] = new WallElement('outpost', 'structures/rome_outpost', PI, 0, -5);
     199wallStyles['romeSiege']['house'] = new WallElement('house', 'structures/rome_tent', PI, 0, 4);
     200wallStyles['romeSiege']['barracks'] = new WallElement('barracks', 'structures/rome_barracks', PI, 0, 6);
     201// Add special wall style 'palisades'
     202wallStyles['palisades'] = {};
     203wallStyles['palisades']['wall'] = new WallElement('wall', 'other/palisades_rocks_straight', -PI/2, 2.5);
     204wallStyles['palisades']['tower'] = new WallElement('tower', 'other/palisades_rocks_tower', -PI/2, 0.7);
     205wallStyles['palisades']['wallFort'] = new WallElement('wallFort', 'other/palisades_rocks_fort', PI, 1.7);
     206wallStyles['palisades']['gate'] = new WallElement('gate', 'other/palisades_rocks_gate', 0*PI, 3.6);
     207wallStyles['palisades']['entry'] = new WallElement('entry', undefined, wallStyles['palisades']['gate'].angle, wallStyles['palisades']['gate'].width);
     208wallStyles['palisades']['entryTower'] = new WallElement('entryTower', 'other/palisades_rocks_watchtower', 0*PI, 3.6, -2);
     209wallStyles['palisades']['entryFort'] = new WallElement('entryFort', 'other/palisades_rocks_fort', PI, 6, 3);
     210wallStyles['palisades']['endRight'] = new WallElement('endRight', 'other/palisades_rocks_end', -PI/2, 0.2);
     211wallStyles['palisades']['endLeft'] = new WallElement('endLeft', 'other/palisades_rocks_end', PI/2, 0.2);
     212wallStyles['palisades']['cornerIn'] = new WallElement('cornerIn', 'other/palisades_rocks_curve', 3*PI/4, 2.1, 0.7, PI/2);
     213wallStyles['palisades']['cornerOut'] = new WallElement('cornerOut', 'other/palisades_rocks_curve', 5*PI/4, 2.1, -0.7, -PI/2);
     214wallStyles['palisades']['outpost'] = new WallElement('outpost', 'other/palisades_rocks_outpost', PI, 0, -2);
     215wallStyles['palisades']['house'] = new WallElement('house', 'other/celt_hut', PI, 0, 5);
     216wallStyles['palisades']['barracks'] = new WallElement('barracks', 'other/celt_tavern', PI, 0, 5);
     217// Add special wall style 'road'
     218// Add special wall element collection 'other'
     219// NOTE: This is not a wall style in the common sense. Use with care!
     220wallStyles['other'] = {};
     221wallStyles['other']['fence'] = new WallElement('fence', 'other/fence_long', -PI/2, 3.1);
     222wallStyles['other']['fence_short'] = new WallElement('fence_short', 'other/fence_short', -PI/2, 1.5);
     223wallStyles['other']['fence_stone'] = new WallElement('fence_stone', 'other/fence_stone', -PI/2, 2.5);
     224wallStyles['other']['palisade'] = new WallElement('palisade', 'other/palisades_rocks_short', 0, 1.2);
     225wallStyles['other']['column'] = new WallElement('column', 'other/column_doric', 0, 1);
     226wallStyles['other']['obelisk'] = new WallElement('obelisk', 'other/obelisk', 0, 2);
     227wallStyles['other']['spike'] = new WallElement('spike', 'other/palisades_angle_spike', -PI/2, 1);
     228wallStyles['other']['bench'] = new WallElement('bench', 'other/bench', PI/2, 1.5);
     229wallStyles['other']['benchForTable'] = new WallElement('benchForTable', 'other/bench', 0, 0.5);
     230wallStyles['other']['table'] = new WallElement('table', 'other/table_rectangle', 0, 1);
     231wallStyles['other']['table_square'] = new WallElement('table_square', 'other/table_square', PI/2, 1);
     232wallStyles['other']['flag'] = new WallElement('flag', 'special/rallypoint', PI, 1);
     233wallStyles['other']['standing_stone'] = new WallElement('standing_stone', 'gaia/special_ruins_standing_stone', PI, 1);
     234wallStyles['other']['settlement'] = new WallElement('settlement', 'gaia/special_settlement', PI, 6);
     235wallStyles['other']['gap'] = new WallElement('gap', undefined, 0, 2);
     236wallStyles['other']['gapSmall'] = new WallElement('gapSmall', undefined, 0, 1);
     237wallStyles['other']['gapLarge'] = new WallElement('gapLarge', undefined, 0, 4);
     238wallStyles['other']['cornerIn'] = new WallElement('cornerIn', undefined, 0, 0, 0, PI/2);
     239wallStyles['other']['cornerOut'] = new WallElement('cornerOut', undefined, 0, 0, 0, -PI/2);
     240
     241
     242///////////////////////////////////////////////////////
     243// Setup data structure for some default fortress types
     244///////////////////////////////////////////////////////
     245
     246// A fortress type is just an instance of the fortress class with actually something in it.
     247// 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'
     248var fortressTypes = {};
     249// Setup some default fortress types
     250// Add fortress type 'tiny'
     251fortressTypes['tiny'] = new Fortress('tiny');
     252var wallPart = ['entry', 'endLeft', 'wall', 'cornerIn', 'wall', 'endRight'];
     253fortressTypes['tiny'].wall = wallPart.concat(wallPart, wallPart, wallPart);
     254// Add fortress type 'small'
     255fortressTypes['small'] = new Fortress('small');
     256var wallPart = ['entry', 'endLeft', 'wall', 'outpost', 'wall',
     257    'cornerIn', 'wall', 'outpost', 'wall', 'endRight'];
     258fortressTypes['small'].wall = wallPart.concat(wallPart, wallPart, wallPart);
     259// Add fortress type 'medium'
     260fortressTypes['medium'] = new Fortress('medium');
     261var wallPart = ['entry', 'endLeft', 'wall', 'tower', 'wall',
     262    'cornerIn', 'wall', 'tower', 'wall', 'endRight'];
     263fortressTypes['medium'].wall = wallPart.concat(wallPart, wallPart, wallPart);
     264// Add fortress type 'normal'
     265fortressTypes['normal'] = new Fortress('normal');
     266var wallPart = ['entry', 'endLeft', 'wall', 'outpost', 'wall', 'cornerIn', 'wall',
     267    'cornerOut', 'wall', 'cornerIn', 'wall', 'outpost', 'wall', 'endRight'];
     268fortressTypes['normal'].wall = wallPart.concat(wallPart, wallPart, wallPart);
     269// Add fortress type 'large'
     270fortressTypes['large'] = new Fortress('large');
     271var wallPart = ['entry', 'endLeft', 'wall', 'tower', 'wall', 'cornerIn', 'wall',
     272    'cornerOut', 'wall', 'cornerIn', 'wall', 'tower', 'wall', 'endRight'];
     273fortressTypes['large'].wall = wallPart.concat(wallPart, wallPart, wallPart);
     274// Add fortress type 'veryLarge'
     275fortressTypes['veryLarge'] = new Fortress('veryLarge');
     276var wallPart = ['entry', 'endLeft', 'wall', 'outpost', 'wall', 'cornerIn', 'wall', 'outpost', 'wall',
     277    'cornerOut', 'wall', 'outpost', 'wall', 'cornerIn', 'wall', 'outpost', 'wall', 'endRight'];
     278fortressTypes['veryLarge'].wall = wallPart.concat(wallPart, wallPart, wallPart);
     279// Add fortress type 'giant'
     280fortressTypes['giant'] = new Fortress('giant');
     281var wallPart = ['entry', 'endLeft', 'wall', 'tower', 'wall', 'cornerIn', 'wall', 'tower', 'wall',
     282    'cornerOut', 'wall', 'tower', 'wall', 'cornerIn', 'wall', 'tower', 'wall', 'endRight'];
     283fortressTypes['giant'].wall = wallPart.concat(wallPart, wallPart, wallPart);
     284
     285// Setup some semi default fortresses for 'palisades' style
     286var fortressTypeKeys = ['tiny', 'small', 'medium', 'normal', 'large', 'veryLarge', 'giant'];
     287for (var i = 0; i < fortressTypeKeys.length; i++)
    705288{
    706     if (style in this.wallStyles)
     289    var newKey = fortressTypeKeys[i] + 'Palisades';
     290    var oldWall = fortressTypes[fortressTypeKeys[i]].wall;
     291    fortressTypes[newKey] = new Fortress(newKey, []); // [] just to make sure it's an array though it's an array by default
     292    var fillTowersBetween = ['wall', 'endLeft', 'endRight', 'cornerIn', 'cornerOut'];
     293    for (var j = 0; j < oldWall.length; j++)
    707294    {
    708         this.style = style;
    709         this.wallTypes = this.wallStyles[style];
     295        fortressTypes[newKey].wall.push(oldWall[j]); // Only works if the first element is an entry or gate (not in fillTowersBetween)
     296        if (j+1 < oldWall.length)
     297            if (fillTowersBetween.indexOf(oldWall[j]) > -1 && fillTowersBetween.indexOf(oldWall[j+1]) > -1) // ... > -1 means 'exists' here
     298                fortressTypes[newKey].wall.push('tower');
    710299    }
    711     else
    712     {
    713         warn("Wall style '" + style + "' not found, falling back to 'palisades'...");
    714         this.style = 'palisades';
    715         this.wallTypes = this.wallStyles['palisades'];
    716     };
    717 };
     300}
    718301
    719 wallTool.prototype.getAlignment = function(startX, startZ, orientation)
     302
     303//////////////////////////////////////////////////////////////////
     304// Define the abstract getWallAlignment and getWallCenter function
     305//////////////////////////////////////////////////////////////////
     306
     307// Get alignment of a wall
     308// Returns a list of lists of most arguments needed to place the different wall elements for a given wall
     309// Placing the first wall element at startX/startY placed with angle given by orientation
     310// An alignement can be used to get the center of a 'wall' (more likely used for closed walls like fortresses) with the getWallCenter function
     311function getWallAlignment(startX, startY, wall, style, orientation)
    720312{
    721     if (startX == undefined)
    722         startX = 0;
    723     if (startZ == undefined)
    724         startZ = 0;
    725     if (orientation == undefined)
    726         orientation = 0;
    727     var wallAlignment = [];
    728     var outside = orientation;
    729     var wallX = startX - this.center[1]*sin(orientation) - this.center[0]*cos(orientation);
    730     var wallZ = startZ - this.center[1]*cos(orientation) + this.center[0]*sin(orientation);
    731     for (var iWall = 0; iWall < this.wall.length; iWall++)
     313    orientation = (orientation !== undefined) ? orientation : 0*PI;
     314    var alignment = []
     315    var wallX = startX;
     316    var wallY = startY;
     317    for (var i = 0; i < wall.length; i++)
    732318    {
    733         var element = this.wallTypes[this.wall[iWall]];
    734         var x = wallX - element.indent*sin(outside);
    735         var z = wallZ - element.indent*cos(outside);
    736         wallAlignment.push([x, z, element.entity, outside + element.angle]);
    737         // Presets for the next element
    738         if (iWall + 1 < this.wall.length)
     319        if (wallStyles[style][wall[i]] === undefined)
     320            warn('No valid wall element: ' + wall[i]);
     321        var element = wallStyles[style][wall[i]]
     322        // Indentation
     323        var placeX = wallX - element.indent * cos(orientation);
     324        var placeY = wallY - element.indent * sin(orientation);
     325        // Add element alignment
     326        alignment.push([placeX, placeY, element.entity, orientation + element.angle]);
     327        // Preset vars for the next wall element
     328        if (i+1 < wall.length)
    739329        {
    740             outside += element.bending;
    741             var nextElement = this.wallTypes[this.wall[iWall + 1]];
     330            orientation += element.bending;
     331            if (wallStyles[style][wall[i+1]] === undefined)
     332                warn('No valid wall element: ' + wall[i+1]);
     333            var nextElement = wallStyles[style][wall[i+1]];
    742334            var distance = (element.width + nextElement.width)/2;
    743             // Indent corrections for corners
     335            // Corrections for elements with indent AND bending
    744336            if (element.bending !== 0 && element.indent !== 0)
    745337            {
    746                 // Indent correction of distance, not sure for non-right angles...
     338                // Indent correction to adjust distance
    747339                distance += element.indent*sin(element.bending);
    748                 // Indent correction of next normalized indentation
    749                 wallX += element.indent * sin(outside);
    750                 wallZ += element.indent * cos(outside);
    751             };
    752             wallX += distance * sin(outside + PI/2);
    753             wallZ += distance * cos(outside + PI/2);
    754         };
    755     };
    756     return wallAlignment
    757 };
     340                // Indent correction to normalize indentation
     341                wallX += element.indent * cos(orientation);
     342                wallY += element.indent * sin(orientation);
     343            }
     344            // Set the next coordinates of the next element in the wall (meaning without indentation adjustment)
     345            wallX -= distance * sin(orientation);
     346            wallY += distance * cos(orientation);
     347        }
     348    }
     349    return alignment;
     350}
    758351
    759 wallTool.prototype.getCenter = function(wallAlignment)
     352
     353/////////////////////////////////////////////////////////////////////////////
     354// Get the center of a wall (mainly usefull for closed walls like fortresses)
     355/////////////////////////////////////////////////////////////////////////////
     356
     357// Center calculation works like getting the center of mass assuming all wall elements have the same 'waight'
     358// It returns the vector (array [x, y]) from the first wall element to the center
     359// So if used to preset the center in an instance of the fortress class use the negative values (I think)
     360function getWallCenter(alignment)
    760361{
    761362    var x = 0;
    762     var z = 0;
    763     for (var iWall = 0; iWall < wallAlignment.length; iWall++)
     363    var y = 0;
     364    for (var i = 0; i < alignment.length; i++)
    764365    {
    765         x += wallAlignment[iWall][0]/wallAlignment.length;
    766         z += wallAlignment[iWall][1]/wallAlignment.length;
    767     };
    768     var output = [x, z];
    769     return output;
    770 };
     366        x += alignment[i][0]/alignment.length;
     367        y += alignment[i][1]/alignment.length;
     368    }
     369    var center = [x, y];
     370    return center;
     371}
    771372
    772 wallTool.prototype.setFortress = function(fortress)
     373
     374/////////////////////////////////////////////
     375// Define the different wall placer functions
     376/////////////////////////////////////////////
     377
     378
     379/////////////////////////////////////////////////////////////////////////////////
     380// Place simple wall starting with the first wall element placed at startX/startY
     381/////////////////////////////////////////////////////////////////////////////////
     382
     383// orientation: 0 means 'outside' or 'front' of the wall is right (positive X) like placeObject
     384//  It will then be build towards top (positive Y) if no bending wall elements like corners are used
     385//  Raising orientation means the wall is rotated counter-clockwise like placeObject
     386function placeWall(startX, startY, wall, style, playerId, orientation)
    773387{
    774     this.fortress = fortress.type;
    775     this.wall = fortress.wall;
    776     if (this.calculateCenter == true)
     388    var AM = getWallAlignment(startX, startY, wall, style, orientation);
     389    for (var iWall = 0; iWall < wall.length; iWall++)
    777390    {
    778         this.center = [0, 0];
    779         var AM = this.getAlignment(0, 0, 0*PI);
    780         var center = this.getCenter(AM);
    781         this.center = center;
     391        if (AM[iWall][2] !== undefined)
     392            placeObject(AM[iWall][0], AM[iWall][1], AM[iWall][2], playerId, AM[iWall][3]);
    782393    }
     394}
     395
     396
     397//////////////////////////////////////////////////////////////////////////////////////////////////
     398// Place a fortress (mainly a closed wall build like placeWall) with the center at centerX/centerY
     399//////////////////////////////////////////////////////////////////////////////////////////////////
     400
     401// Should always start with the main entrance (like 'entry' or 'gate') to get the orientation right (like placeObject)
     402function placeCustomFortress(centerX, centerY, fortress, style, playerId, orientation, scipGetCenter)
     403{
     404    if (!scipGetCenter)
     405    {
     406        var alignment = getWallAlignment(0, 0, fortress.wall, style);
     407        var center = getWallCenter(alignment);
     408        var startX = centerX - center[0] * cos(orientation) - center[1] * sin(orientation);
     409        var startY = centerY - center[1] * cos(orientation) - center[0] * sin(orientation);
     410    }
    783411    else
    784412    {
    785         this.center = this.fortress.center
    786     };
    787 };
     413        var startX = centerX + fortress.center[0];
     414        var startY = centerY + fortress.center[1];
     415    }
     416    placeWall(startX, startY, fortress.wall, style, playerId, orientation)
     417}
    788418
    789 wallTool.prototype.setFortressType = function(type)
     419function placeFortress(centerX, centerY, type, style, playerId, orientation, scipGetCenter)
    790420{
    791     if (type in this.fortressTypes)
     421    placeCustomFortress(centerX, centerY, fortressTypes[type], style, playerId, orientation, scipGetCenter);
     422}
     423
     424
     425//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     426// Place a linear wall of repeatant wall elements given in the argument wallPart from startX/startY to targetX/targetY
     427//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     428
     429// startX: x coordinate of the beginning of the wall
     430// startY: y coordinate of the beginning of the wall
     431// targetX: x coordinate of the ending of the wall
     432// targetY: y coordinate of the ending of the wall
     433// 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)
     434// wallPart: Optional. An array of wall element type strings (see WallElement.type). Default is ['wall']
     435// NOTE: Don't use wall elements with bending like corners!
     436// style: Optional. An wall style string (like defined in the 'wallStyles' dictionary). Default is 'palisades'
     437// 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)
     438// endWithFirst: Optional. A boolean value. If true the 1st wall element in the wallPart array will finalize the wall. Default is true
     439function placeLinearWall(startX, startY, targetX, targetY, wallPart, style, playerId, endWithFirst)
     440{
     441    // Setup optional arguments to the default
     442    wallPart = (wallPart || ['wall']);
     443    style = (style || 'palisades');
     444    playerId = (playerId || 0);
     445    endWithFirst = (endWithFirst || true);
     446    // Setup number of wall parts
     447    var totalLength = getDistance(startX, startY, targetX, targetY);
     448    var wallPartLength = 0;
     449    for (var elementIndex = 0; elementIndex < wallPart.length; elementIndex++)
     450        wallPartLength += wallStyles[style][wallPart[elementIndex]].width;
     451    var numParts = 0;
     452    if (endWithFirst == true)
     453        numParts = ceil((totalLength - wallStyles[style][wallPart[0]].width) / wallPartLength)
     454    else
     455        numParts = ceil(totalLength / wallPartLength);
     456    // Setup scale factor
     457    var scaleFactor = 1;
     458    if (endWithFirst == true)
     459        scaleFactor = totalLength / (numParts * wallPartLength + wallStyles[style][wallPart[0]].width)
     460    else
     461        scaleFactor = totalLength / (numParts * wallPartLength);
     462    // Setup angle
     463    var wallAngle = getAngle(startX, startY, targetX, targetY); // NOTE: function 'getAngle()' is about to be changed...
     464    var placeAngle = wallAngle - PI/2;
     465    // Place wall entities
     466    var x = startX;
     467    var y = startY;
     468    for (var partIndex = 0; partIndex < numParts; partIndex++)
    792469    {
    793         this.setFortress(this.fortressTypes[type]);
     470        for (var elementIndex = 0; elementIndex < wallPart.length; elementIndex++)
     471        {
     472            var wallEle = wallStyles[style][wallPart[elementIndex]];
     473            // Width correction
     474            x += scaleFactor * wallEle.width/2 * cos(wallAngle);
     475            y += scaleFactor * wallEle.width/2 * sin(wallAngle);
     476            // Indent correction
     477            var placeX = x - wallEle.indent * sin(wallAngle);
     478            var placeY = y + wallEle.indent * cos(wallAngle);
     479            // Placement
     480            if (wallEle.entity !== undefined)
     481                placeObject(placeX, placeY, wallEle.entity, playerId, placeAngle + wallEle.angle);
     482            x += scaleFactor * wallEle.width/2 * cos(wallAngle);
     483            y += scaleFactor * wallEle.width/2 * sin(wallAngle);
     484        }
    794485    }
    795     else
     486    if (endWithFirst == true)
    796487    {
    797         warn("Fortress type '" + type + "' not found, falling back to 'medium'");
    798         this.setFortress(this.fortressTypes["medium"]);
    799     };
    800 };
     488        var wallEle = wallStyles[style][wallPart[0]];
     489        x += scaleFactor * wallEle.width/2 * cos(wallAngle);
     490        y += scaleFactor * wallEle.width/2 * sin(wallAngle);
     491        if (wallEle.entity !== undefined)
     492            placeObject(x, y, wallEle.entity, playerId, placeAngle + wallEle.angle);
     493    }
     494}
    801495
    802 wallTool.prototype.place = function(startX, startZ, playerId, orientation)
     496
     497////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     498// Place a circular wall of repeatant wall elements given in the argument wallPart arround centerX/centerY with the given radius
     499////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     500
     501// The wall is not necessarily closed depending on the optional argument maxAngle (better name?)
     502// NOTE: Don't use wall elements with bending like corners!
     503function placeCircularWall(centerX, centerY, radius, wallPart, style, playerId, orientation, maxAngle, endWithFirst, maxBendOff)
    803504{
    804     var AM = this.getAlignment(startX, startZ, orientation);
    805     for (var iWall = 0; iWall < this.wall.length; iWall++)
     505    // Setup optional arguments to the default
     506    wallPart = (wallPart || ['wall']);
     507    style = (style || 'palisades');
     508    playerId = (playerId || 0);
     509    orientation = (orientation || 0);
     510    maxAngle = (maxAngle || 2*PI);
     511    if (endWithFirst === undefined)
    806512    {
    807         if (AM[iWall][2] !== undefined)
    808             placeObject(AM[iWall][0], AM[iWall][1], AM[iWall][2], playerId, AM[iWall][3]);
    809     };
    810 };
     513        if (maxAngle >= 2*PI - 0.001) // Can this be done better?
     514        {
     515            endWithFirst = false;
     516        }
     517        else
     518        {
     519            endWithFirst = true;
     520        }
     521    }
     522    maxBendOff = (maxBendOff || 0);
     523    if (maxBendOff > PI/2 || maxBendOff < 0)
     524        warn('placeCircularWall maxBendOff sould satisfy 0 < maxBendOff < PI/2 (~1.5) but it is: ' + maxBendOff);
     525    // Setup number of wall parts
     526    var totalLength = maxAngle * radius;
     527    var wallPartLength = 0;
     528    for (var elementIndex = 0; elementIndex < wallPart.length; elementIndex++)
     529        wallPartLength += wallStyles[style][wallPart[elementIndex]].width;
     530    var numParts = 0;
     531    if (endWithFirst == true)
     532    {
     533        numParts = ceil((totalLength - wallStyles[style][wallPart[0]].width) / wallPartLength);
     534    }
     535    else
     536    {
     537        numParts = ceil(totalLength / wallPartLength);
     538    }
     539    // Setup scale factor
     540    var scaleFactor = 1;
     541    if (endWithFirst == true)
     542        scaleFactor = totalLength / (numParts * wallPartLength + wallStyles[style][wallPart[0]].width)
     543    else
     544        scaleFactor = totalLength / (numParts * wallPartLength);
     545    // Place wall entities
     546    var actualAngle = orientation + (2*PI - maxAngle) / 2;
     547    var x = centerX + radius*cos(actualAngle);
     548    var y = centerY + radius*sin(actualAngle);
     549    for (var partIndex = 0; partIndex < numParts; partIndex++)
     550    {
     551        for (var elementIndex = 0; elementIndex < wallPart.length; elementIndex++)
     552        {
     553            var wallEle = wallStyles[style][wallPart[elementIndex]];
     554            // Width correction
     555            var addAngle = scaleFactor * wallEle.width / radius;
     556            var targetX = centerX + radius * cos(actualAngle + addAngle);
     557            var targetY = centerY + radius * sin(actualAngle + addAngle);
     558            var placeX = x + (targetX - x)/2;
     559            var placeY = y + (targetY - y)/2;
     560            var placeAngle = actualAngle + addAngle/2;
     561            // Indent correction
     562            placeX -= wallEle.indent * cos(placeAngle);
     563            placeY -= wallEle.indent * sin(placeAngle);
     564            // Placement
     565            if (wallEle.entity !== undefined)
     566                placeObject(placeX, placeY, wallEle.entity, playerId, placeAngle + wallEle.angle);
     567            // Prepare for the next wall element
     568            actualAngle += addAngle;
     569            x = centerX + radius*cos(actualAngle);
     570            y = centerY + radius*sin(actualAngle);
     571        }
     572    }
     573    if (endWithFirst == true)
     574    {
     575        var wallEle = wallStyles[style][wallPart[0]];
     576        var addAngle = scaleFactor * wallEle.width / radius;
     577        var targetX = centerX + radius * cos(actualAngle + addAngle);
     578        var targetY = centerY + radius * sin(actualAngle + addAngle);
     579        var placeX = x + (targetX - x)/2;
     580        var placeY = y + (targetY - y)/2;
     581        var placeAngle = actualAngle + addAngle/2;
     582        placeObject(placeX, placeY, wallEle.entity, playerId, placeAngle + wallEle.angle);
     583    }
     584}
  • binaries/data/mods/public/maps/random/wall_demo.js

     
     1RMS.LoadLibrary("rmgen");
     2
     3// initialize map
     4log("Initializing map...");
     5InitMap();
     6
     7
     8// General map setup
     9var mapSize = getMapSize();
     10var mapCenterX = mapSize/2;
     11var mapCenterY = mapSize/2;
     12const BUILDING_ANlE = -PI/4;
     13
     14
     15////////////////////////////////////////
     16// Demonstration code for wall placement
     17////////////////////////////////////////
     18
     19// Some general notes to the arguments:
     20
     21// First all the place functions take the coordinates needed to place the wall
     22// X and Y coordinate are taken in seperate arguments like in placeObject
     23// Their meaning differs for different placement methods but are mainly self explanatory
     24// placeLinearWall takes 4 arguments here (2 coordinates) for startX, startY, targetX and targetY
     25
     26// The next argument is always the 'wall' definition, an array of wall element type strings in most cases
     27// That looks like ['endLeft', 'wall', 'tower', 'wall', 'endRight', 'entry', 'endLeft', 'wall', 'tower', 'wall', 'endRight']
     28// For placeCircularWall and placeLinearWall only wall parts are needed like: ['tower', 'wall']
     29// They will automatically end with the first wall element if that makes sense (e.g. the wall is not closed)
     30// NOTE: They take further optional arguments to adjust this behaviour (See the wall_builder.js for that)
     31// placeFortress just takes a fortress type string that includes the wall definition
     32// The default fortress type strings are made for easy placement of predefined fortresses
     33// They are chosen like map sizes: 'tiny', 'small', 'medium', 'normal', 'large', 'veryLarge' and 'giant'
     34// NOTE: To place a custom fortress use placeCustomFortress instead
     35// It takes an instance of the Fortress class instead of the default fortress type strings
     36
     37// The next argument is always the wall style string
     38// Wall styles are chosen by strings so the civ strings got by g_MapSettings.PlayerData[playerId - 1].Civ can be used
     39// Other styles may be present as well but besides the civ styles only 'palisades' includes all wall element types (yet)
     40
     41// The next argument is always the index of the player that owns the wall.
     42// 0 is Gaia, 1 is Player 1 (default colour blue), 2 is Player 2 (default colour red), ...
     43
     44// The next argument is an angle defining the orientation of the wall
     45// placeLinearWall does not need an angle since it's defined by startX/Y and targetX/Y
     46// Orientation works like the angle argument in placeObject
     47// 0 is always right (towards positive X)
     48// Raising the angle will rotate the wall counter-clockwise (mathmatical positive in default 2D)
     49// PI/2 faces top (positive Y)
     50// Orientation might be a little confusing for placeWall since it defines where the wall has its 'front' or 'outside' not the direction it will be build to.
     51// It's because all other methods work like that and it's intuitive there
     52// That means the walls outside by default (orientation = 0) faces positive X and (without bending wall elements) will be build towards positive Y
     53
     54// Some other arguments are taken but all of them are optional and in most cases not needed
     55// One example is maxAngle for placeCircularWall that defines how far the wall will circumvent the center.
     56// Default is 2*PI which makes a full circle
     57
     58
     59// General wall placement setup
     60const distToMapBorder = 5;
     61const distToOtherWalls = 5;
     62var buildableMapSize = mapSize - 2 * distToMapBorder;
     63var actualX = distToMapBorder;
     64var actualY = distToMapBorder;
     65// Wall styles are chosen by strings so the civ strings got by g_MapSettings.PlayerData[playerId - 1].Civ can be used
     66// Other styles may be present as well but besides the civ styles only 'palisades' includes all wall element types (yet)
     67const wallStyleList = ['cart', 'celt', 'hele', 'iber', 'pers', 'rome', 'romeSiege', 'palisades'];
     68
     69
     70////////////////////////////////////////
     71// Custom wall placement (element based)
     72////////////////////////////////////////
     73var wall = ['endLeft', 'wall', 'tower', 'wall', 'outpost', 'wall', 'cornerOut', 'wall', 'cornerIn', 'wall', 'house', 'endRight', 'entryTower', 'endLeft', 'wall', 'barracks', 'gate', 'tower', 'wall', 'wallFort', 'wall', 'endRight'];
     74for (var styleIndex = 0; styleIndex < wallStyleList.length; styleIndex++)
     75{
     76    var startX = actualX + styleIndex * buildableMapSize/wallStyleList.length; // X coordinate of the first wall element
     77    var startY = actualY; // Y coordinate of the first wall element
     78    var style = wallStyleList[styleIndex]; // // The wall's style like 'cart', 'celt', 'hele', 'iber', 'pers', 'rome', 'romeSiege' or 'palisades'
     79    var orientation = styleIndex * PI/32; // Orientation of the first wall element. 0 means 'outside' or 'front' is right (positive X, like object placement)
     80    // That means the wall will be build towards top (positive Y) if no corners are used
     81    var playerId = 0; // Owner of the wall (like in placeObject). 0 is Gaia, 1 is Player 1 (default colour blue), ...
     82    placeWall(startX, startY, wall, style, playerId, orientation); // Actually placing the wall
     83}
     84actualX = distToMapBorder; // Reset actualX
     85actualY += 80 + distToOtherWalls; // Increase actualY for next wall placement method
     86
     87//////////////////////////////////////////////////////////////
     88// Default fortress placement (chosen by fortress type string)
     89//////////////////////////////////////////////////////////////
     90var fortressRadius = 15; // The space the fortresses take in average. Just for design of this map
     91for (var styleIndex = 0; styleIndex < wallStyleList.length; styleIndex++)
     92{
     93    var centerX = actualX + fortressRadius + styleIndex * buildableMapSize/wallStyleList.length; // X coordinate of the center of the fortress
     94    var centerY = actualY + fortressRadius; // Y coordinate of the center of the fortress
     95    var type = 'tiny'; // Default fortress types are like map sizes: 'tiny', 'small', 'medium', 'large', 'veryLarge', 'giant'
     96    var style = wallStyleList[styleIndex]; // The wall's style like 'cart', 'celt', 'hele', 'iber', 'pers', 'rome', 'romeSiege' or 'palisades'
     97    var playerId = 0; // Owner of the wall. 0 is Gaia, 1 is Player 1 (default colour blue), ...
     98    var orientation = styleIndex * PI/16; // Where the 'main entrance' of the fortress should face (like in placeObject). All fortresses walls should start with an entrance
     99    placeFortress(centerX, centerY, type, style, playerId, orientation); // Actually placing the fortress
     100    placeObject(centerX, centerY, 'other/obelisk', 0, 0*PI); // Place visual marker to see the center of the fortress
     101}
     102actualX = distToMapBorder; // Reset actualX
     103actualY += 2 * fortressRadius + 2 * distToOtherWalls; // Increase actualY for next wall placement method
     104
     105//////////////////////////
     106// Circular wall placement
     107//////////////////////////
     108// NOTE: Don't use bending wall elements like corners here!
     109var radius = min((mapSize - actualY - distToOtherWalls) / 2, (buildableMapSize / wallStyleList.length - distToOtherWalls) / 2); // The radius of wall circle
     110var centerY = actualY + radius; // Y coordinate of the center of the wall circle
     111var orientation = 0; // Where the wall circle will be open if maxAngle < 2*PI, see below. Otherwise where the first wall element will be placed
     112for (var styleIndex = 0; styleIndex < wallStyleList.length; styleIndex++)
     113{
     114    var centerX = actualX + radius + styleIndex * buildableMapSize/wallStyleList.length; // X coordinate of the center of the wall circle
     115    var playerID = 0; // Player ID of the player owning the wall, 0 is Gaia, 1 is the first player (default blue), ...
     116    var wallPart = ['tower', 'wall', 'house']; // List of wall elements the wall will be build of. Optional, default id ['wall']
     117    var style = wallStyleList[styleIndex]; // The wall's style like 'cart', 'celt', 'hele', 'iber', 'pers', 'rome', 'romeSiege' or 'palisades'
     118    var maxAngle = PI/2 * (styleIndex%3 + 2); // How far the wall should circumvent the center
     119    placeCircularWall(centerX, centerY, radius, wallPart, style, playerID, orientation, maxAngle) // Actually placing the wall
     120    placeObject(centerX, centerY, 'other/obelisk', 0, 0*PI); // Place visual marker to see the center of the wall circle
     121    orientation += PI/4; // Increasing orientation to see how rotation works (like for object placement)
     122}
     123actualX = distToMapBorder; // Reset actualX
     124actualY += 2 * radius + distToOtherWalls; // Increase actualY for next wall placement method
     125
     126////////////////////////
     127// Linear wall placement
     128////////////////////////
     129// NOTE: Don't use bending wall elements like corners here!
     130var maxWallLength = (mapSize - actualY - distToMapBorder - distToOtherWalls); // Just for this maps design. How long the longest wall will be
     131var numWallsPerStyle = floor(buildableMapSize / distToOtherWalls / wallStyleList.length); // Just for this maps design. How many walls of the same style will be placed
     132for (var styleIndex = 0; styleIndex < wallStyleList.length; styleIndex++)
     133{
     134    for (var wallIndex = 0; wallIndex < numWallsPerStyle; wallIndex++)
     135    {
     136        var startX = actualX + (styleIndex * numWallsPerStyle + wallIndex) * distToOtherWalls; // X coordinate the wall will start from
     137        var startY = actualY; // Y coordinate the wall will start from
     138        var endX = actualX + (styleIndex * numWallsPerStyle + wallIndex) * distToOtherWalls; // X coordinate the wall will end
     139        var endY = actualY + (wallIndex + 1) * maxWallLength/numWallsPerStyle; // Y coordinate the wall will end
     140        var playerID = 0; // Player ID of the player owning the wall, 0 is Gaia, 1 is the first player (default blue), ...
     141        var wallPart = ['tower', 'wall']; // List of wall elements the wall will be build of
     142        var style = wallStyleList[styleIndex]; // The wall's style like 'cart', 'celt', 'hele', 'iber', 'pers', 'rome', 'romeSiege' or 'palisades'
     143        placeLinearWall(startX, startY, endX, endY, wallPart, style, playerID); // Actually placing the wall
     144        // placeObject(startX, startY, 'other/obelisk', 0, 0*PI); // Place visual marker to see where exsactly the wall begins
     145        // placeObject(endX, endY, 'other/obelisk', 0, 0*PI); // Place visual marker to see where exsactly the wall ends
     146    }
     147}
     148actualX = distToMapBorder; // Reset actualX
     149actualY += maxWallLength + distToOtherWalls; // Increase actualY for next wall placement method
     150
     151
     152// Export map data
     153ExportMap();
  • binaries/data/mods/public/maps/random/wall_demo.json

     
     1{
     2    "settings" : {
     3        "Name" : "Wall Demo",
     4        "Script" : "wall_demo.js",
     5        "Description" : "A demonstration of wall placement methods/code in random maps. Medium map size is recommended.",
     6        "BaseTerrain" : ["grass1"],
     7        "BaseHeight" : 0,
     8        "Keywords": ["demo"],
     9        "CircularMap" : false,
     10        "XXXXXX" : "Optionally define other things here, like we would for a scenario"
     11    }
     12}
     13 No newline at end of file