Jump to content

FeXoR

WFG Retired
  • Posts

    1.426
  • Joined

  • Last visited

  • Days Won

    28

Posts posted by FeXoR

  1. First of all, how are you defining x and z?

    Half the code needed for that so see the full code further below.

    And second: coherence and smoothness should be floats to ints. use 1.0 instead of 1. I had the same problem before.

    I'll do that but it works for now...

    pathWidth is not technically correct. Size parameter defines the area of placer not it's width.

    I know:


    var pathWidth = 5; // This is not really the path's sickness in tiles but the number of tiles in the clumbs of the path

    But your overall code should work.

    It does, but the uncommented stuff is the thing in question. So in this code it's the 'avoidClasses' and I have no idea why. I fixed this by painting the hills after the path, so don't tell me that it will not work because no tiles are added to 'clHill' at this point ;) . I just wanted to tell that 'avoidClasses' sometimes fails (maybe because of the centered placer with given coordinated, I don't have a clue)

    What do you want to do exactly?

    For the dark forest map I want the forest to be placed differently from the other maps to really make it dark (well, at least in theory possible). So I add it on every tile if a random check vs the 'actual density' succeeds. This 'actual density' is mainly the 'maxTreeDensity' (constant for a single map dependent on map size to avoid out of memory errors) scaled by other density modifiers (Dependent on distance to next start location or the center eye candy and the radius to have room to place additional resources at the given radius). This works fine and as I want it.

    However, to enable the players to reach the center and each other on more than 1 path I added paths that should cut through the woods (I think that would just be possible by adding the paths after the woods, but I wanted to get used to the painter/placer/constraint/area usage that is in most cases the perfect thing).

    I noticed that the paths sometimes run in the non-starting-resource-hills and that looked bad so I added an TileClassPainter(clHill) to the resource area and the avoidClasses(clHill) constraint to the paths. But it didn't avoid the hills. So I placed the hills after the paths.

    That was most likely a bug in my code that I didn't find because for the woods (that avoids paths) it works and it's a centered placer, too.

    Besides: As it is now only the center of the paths and the resource terrain clumbs are in the corresponding classes not all terrain clumb's tiles.

    I should see your complete code this time. Could you show it to me in PM?

    Here it is though not in a PM, someone might find it useful (like your suggestion to use float, not int):


    RMS.LoadLibrary("rmgen");

    // initialize map
    log("Initializing map...");
    InitMap();


    // Setup tile classes
    var clPlayer = createTileClass();
    var clPath = createTileClass();
    var clHill = createTileClass();
    var clForest = createTileClass();
    // var clWater = createTileClass();
    // var clRock = createTileClass();
    // var clFood = createTileClass();
    // var clBaseResource = createTileClass();

    // Setup Templates
    var templateStone = "gaia/geology_stone_temperate"
    var templateStoneMine = "gaia/geology_stonemine_temperate_quarry";
    var templateMetal = "gaia/geology_metal_temperate";
    var templateMetalMine = "gaia/geology_metal_temperate_slabs";
    var startingResourcees = ["gaia/flora_tree_oak_large", "gaia/flora_bush_temperate", templateStoneMine,
    "gaia/flora_bush_grapes", "gaia/flora_tree_apple", "gaia/flora_bush_berry", templateMetalMine, "gaia/flora_bush_temperate"];

    // Setup terrain
    var terrainWood = ['temp_forestfloor_a|gaia/flora_tree_oak', 'temp_forestfloor_autumn|gaia/flora_tree_carob', 'temp_forestfloor_pine|gaia/flora_tree_pine'];
    var terrainWoodBorder = ['temp_grass_plants|gaia/flora_bush_berry', 'temp_grass_clovers_2|gaia/flora_bush_grapes', 'temp_grass_long_b|gaia/flora_tree_apple',
    'temp_grass_long|gaia/flora_bush_temperate', 'temp_highlands|gaia/flora_bush_temperate', 'temp_grass_mossy|gaia/flora_bush_temperate',
    'temp_grass_plants|gaia/fauna_deer', "temp_mud_plants|gaia/fauna_boar", "temp_grass_long_b|gaia/fauna_rabbit"];
    var terrainBase = ['temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b',
    'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b',
    'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b',
    'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b',
    'temp_grass_b|gaia/fauna_pig', 'temp_dirt_gravel|gaia/fauna_chicken'];
    var terrainBaseBorder = ['temp_grass_b', 'temp_grass_b', 'temp_grass_c'];
    var terrainPath = ['temp_road', 'temp_grass_b', "temp_road_overgrown"];
    var terrainHill = ["temp_highlands", "temp_highlands", "temp_dirt_gravel_b"];
    var terrainHillBorder = ["temp_highlands", "temp_mud_plants", "temp_highlands", "temp_mud_plants", "temp_highlands", "temp_mud_plants", "temp_highlands", "temp_mud_plants",
    "temp_highlands", "temp_mud_plants", "temp_highlands", "temp_mud_plants", "temp_highlands", "temp_mud_plants", "temp_highlands", "temp_mud_plants",
    "temp_grass_clovers_2|gaia/fauna_goat"];


    // Setup map
    var mapSize = getMapSize();
    var mapRadius = mapSize/2;
    var playableMapRadius = mapRadius - 5;
    var mapCenterX = mapRadius;
    var mapCenterZ = mapRadius;

    // Setup players and bases
    var fortresses = false;
    var numPlayers = getNumPlayers();
    var baseRadius = 20;
    if (fortresses == true)
    baseRadius = 30;
    var minPlayerRadius = min(mapRadius-1.5*baseRadius, 5*mapRadius/8);
    var maxPlayerRadius = min(mapRadius-baseRadius, 3*mapRadius/4);
    const BUILDING_ANlE = 3*PI/4;
    var buildAngle = 3*PI/4;
    var playerStartLocX = new Array(numPlayers);
    var playerStartLocZ = new Array(numPlayers);
    var playerAngle = new Array(numPlayers);
    var playerAngleStart = randFloat(0, 2*PI);
    var playerAngleAddAvrg = 2*PI / numPlayers;
    var playerAngleMaxOff = playerAngleAddAvrg/4;

    // Setup eyecandy
    var templateEC = "other/unfinished_greek_temple";
    var radiusEC = max(mapRadius/8, baseRadius/2);

    // Setup paths
    var pathSucsessRadius = baseRadius/2;
    var pathAngleOff = PI/2;
    var pathWidth = 5; // This is not really the path's sickness in tiles but the number of tiles in the clumbs of the path
    if (fortresses == true)
    pathSucsessRadius = baseRadius;;

    // Setup additional resources
    var resourceRadius = 2*mapRadius/3; // 3*mapRadius/8;
    var recourcePerPlayer = [];
    var resourcePerPlayer = 2;

    // Setup woods
    var maxTreeDensity = min(256*256/mapSize/mapSize, 1); // Has to be tweeked but works ok
    var bushChance = 0.5; // 1 means 50% chance in deepest wood, 0.5 means 25% chance in deepest wood

    // Place bases
    for (var i=0; i < numPlayers; i++)
    {
    var civ = g_MapSettings.PlayerData[i].Civ;
    var startEntities = getStartingEntities(i);
    playerAngle[i] = (playerAngleStart + i*playerAngleAddAvrg + randFloat(0, playerAngleMaxOff))%(2*PI);
    var x = round(mapCenterX + randFloat(minPlayerRadius, maxPlayerRadius)*cos(playerAngle[i]));
    var z = round(mapCenterZ + randFloat(minPlayerRadius, maxPlayerRadius)*sin(playerAngle[i]));
    playerStartLocX[i] = x;
    playerStartLocZ[i] = z;
    // Place starting entities
    createStartingPlayerEntities(x, z, i+1, startEntities, buildAngle)
    // Place base texture
    var placer = new ClumpPlacer(baseRadius*baseRadius, 1/2, 1/8, 1, x, z);
    var painter = [new LayeredPainter([terrainBaseBorder, terrainBase], [2+randFloat()])];
    createArea(placer, painter);
    addToClass(x, z, clPlayer);
    // Place fortresses
    if (fortresses == true)
    {
    // Place fortresses
    new wallTool(civ, "small").place(x, z, i+1, buildAngle);
    // if (civ == "iber")
    // new wallTool("iber").setGenericFortress(x, z, i+1, 20, PI/6);
    };
    // Place starting resources
    var distToSL = 10;
    var resStartAngle = playerAngle[i] + PI;
    var resAddAngle = 2*PI / startingResourcees.length;
    for (var rIndex = 0; rIndex < startingResourcees.length; rIndex++)
    {
    var angleOff = randFloat(-resAddAngle/2, resAddAngle/2);
    var placeX = x + distToSL*cos(resStartAngle + rIndex*resAddAngle + angleOff);
    var placeZ = z + distToSL*sin(resStartAngle + rIndex*resAddAngle + angleOff);
    placeObject(placeX, placeZ, startingResourcees[rIndex], 0, randFloat(0, 2*PI));
    };
    };

    // Place paths (2 path between each 2 players and each player and the eyecandy in the middle)
    for (var i = 0; i < numPlayers+1; i++)
    {
    for (var j = 0; j < numPlayers+1; j++)
    {
    if (i < numPlayers)
    {
    var x = playerStartLocX[i];
    var z = playerStartLocZ[i];
    }
    else
    {
    var x = mapCenterX;
    var z = mapCenterZ;
    };
    if (j < numPlayers)
    {
    var targetX = playerStartLocX[j];
    var targetZ = playerStartLocZ[j];
    }
    else
    {
    var targetX = mapCenterX;
    var targetZ = mapCenterZ;
    };
    var angle = getAngle(x, z, targetX, targetZ);
    x += round(pathSucsessRadius*cos(angle));
    z += round(pathSucsessRadius*sin(angle));
    var targetReached = false;
    var tries = 0;
    while (targetReached == false && tries < 2*mapSize)
    {
    var placer = new ClumpPlacer(pathWidth, 1, 1, 1, x, z);
    var painter = [new TerrainPainter(terrainPath), new ElevationPainter(-randFloat())];
    createArea(placer, painter, avoidClasses(clHill, 20)); // DOES NOT WORK!!! Because of centred placer???
    addToClass(x, z, clPath);
    // Set vars for next loop
    angle = getAngle(x, z, targetX, targetZ);
    x += round(cos(angle + randFloat(-pathAngleOff/2, 3*pathAngleOff/2)));
    z += round(sin(angle + randFloat(-pathAngleOff/2, 3*pathAngleOff/2)));
    if (getDistance(x, z, targetX, targetZ) < pathSucsessRadius)
    targetReached = true;
    tries++;

    };
    };
    };

    // Place expansion resources
    for (var i=0; i < numPlayers; i++)
    {
    for (var rIndex = 0; rIndex < resourcePerPlayer; rIndex++)
    {
    if (numPlayers > 1)
    var angleDist = (playerAngle[(i+1)%numPlayers] - playerAngle[i] + 2*PI)%(2*PI);
    else
    var angleDist = 2*PI;
    var placeX = round(mapCenterX + resourceRadius*cos(playerAngle[i] + (rIndex+1)*angleDist/(resourcePerPlayer+1)));
    var placeZ = round(mapCenterX + resourceRadius*sin(playerAngle[i] + (rIndex+1)*angleDist/(resourcePerPlayer+1)));
    if (rIndex%2 == 0)
    placeObject(placeX, placeZ, templateStone, 0, randFloat(0, 2*PI));
    else
    placeObject(placeX, placeZ, templateMetalMine, 0, randFloat(0, 2*PI));
    var placer = new ClumpPlacer(40, 1/2, 1/8, 1, placeX, placeZ);
    var painter = [new LayeredPainter([terrainHillBorder, terrainHill], [1]), new ElevationPainter(1+randFloat())];
    createArea(placer, painter);
    // addToClass(placeX, placeX, clHill);
    };
    };

    // Place eyecandy
    placeObject(mapCenterX, mapCenterZ, templateEC, 0, randFloat(0, 2*PI));
    var placer = new ClumpPlacer(radiusEC*radiusEC, 1/2, 1/8, 1, mapCenterX, mapCenterZ);
    var painter = [new LayeredPainter([terrainHillBorder, terrainHill], [radiusEC/4]), new ElevationPainter(1+randFloat())];
    createArea(placer, painter);
    addToClass(mapCenterX, mapCenterZ, clHill);

    // Woods and hills
    for (var x = 0; x < mapSize; x++)
    {
    for (var z = 0;z < mapSize;z++)
    {
    // Some variables
    var radius = Math.pow(Math.pow(mapCenterX - x, 2) + Math.pow(mapCenterZ - z, 2), 1/2);
    var minDistToSL = mapSize;
    for (var i=0; i < numPlayers; i++)
    minDistToSL = min(minDistToSL, getDistance(playerStartLocX[i], playerStartLocZ[i], x, z))
    // Woods tile based
    var tDensFactSL = max(min((minDistToSL - baseRadius) / baseRadius, 1), 0);
    var tDensFactRad = abs((resourceRadius - radius) / resourceRadius);
    var tDensFactEC = max(min((radius - radiusEC) / radiusEC, 1), 0);
    var tDensActual = maxTreeDensity * tDensFactSL * tDensFactRad * tDensFactEC;
    if (randFloat() < tDensActual && radius < playableMapRadius)
    {
    if (tDensActual < bushChance*randFloat()*maxTreeDensity)
    {
    var placer = new ClumpPlacer(1, 1, 1, 1, x, z);
    var painter = [new TerrainPainter(terrainWoodBorder), new ElevationPainter(randFloat())];
    createArea(placer, painter, avoidClasses(clPath, 1));
    }
    else
    {
    var placer = new ClumpPlacer(1, 1, 1, 1, x, z);
    var painter = [new TerrainPainter(terrainWood), new ElevationPainter(randFloat())]; // new TileClassPainter(clForest)
    createArea(placer, painter, avoidClasses(clPath, 2));
    };
    addToClass(x, z, clForest);
    };
    // Hills
    var hVarMiddleHill = mapSize/64 * (1+cos(3*PI/2 * radius/mapRadius));
    var hVarHills = 5*(1+sin(x/10)*sin(z/10));
    setHeight(x, z, getHeight(x, z) + hVarMiddleHill + hVarHills + 1);
    };
    };


    // Export map data
    ExportMap();

    And a download: fexor_simple2012-3-22.zip

    By the way, NONE of the existing maps use 'TileClassPainter' so I'm quite sure it doesn't work properly.

    For SmoothElevationPainter: I can't reproduce this on a simple map (why ever) but just replace line 223 with:

    var painter = [new TerrainPainter(terrainWoodBorder), new SmoothElevationPainter(ELEVATION_MODIFY, 0.0, 10.0)];

    And play around with the 'ClumpPlacer' and 'SmoothElevationPainter' arguments. Then generate the map and watch the terrain elevation below bushes/wild animals/apple trees (all in 'terrainWoodBorder')

    I recommend to generate it with 3 players on a small map. It generates relatively fast then and has enough wood/wood border to play around with the variables and see the results.

    Writing a test map... 

  2. Well, according to this, none of the current maps should work.:P

    OK ^^

    Then what do I do wrong when:

    var placer = new ClumpPlacer(pathWidth, 1, 1, 1, x, z);
    var painter = [new TerrainPainter(terrainPath), new ElevationPainter(-randFloat())];
    createArea(placer, painter, avoidClasses(clHill, 20)); // AVOID CLASS DOES NOT WORK!!! Because of centred placer???

    Here:

    var placer = new ClumpPlacer(1, 1, 1, 1, x, z);
    var painter = [new TerrainPainter(terrainWood), new ElevationPainter(randFloat())]; // new TileClassPainter(clForest) RAISES ERROR!!! SmoothElevationPainter(ELEVATION_MODIFY, randFloat(1), 1) STRANGE ACTING!
    createArea(placer, painter, avoidClasses(clPath, 2));

    If I add SmoothElevationPainter here it's only lowering the terrain when I set elevation AND blendRadius negative.

    However, when used with a bigger  ClumpPlacerit seams to work much better though even if the  elevation is positive it sometimes lowers the terrain on the right.

  3. I noticed that some placers/painters does not work in combination.

    - avoidClasses does not seam to work for centered placers.

    - SmoothElevationPainter does not seam to work for non-centered placers (at least not properly for a ClumpPlacer of size 1).

    - TileClassPainter does not seam to work at all.

  4. Here is a total rewrite.

    Not finished but 1/4 of the lines of the previous version ;)

    It may happen (though it only happened to me once) that a path runs out of the map and causes an error.

    deep_forest2012-3-20.zip

    I'm still not happy with the terrain textures. Any suggestions welcome.

    If you play with many players on a small map everything will be covered with paths. But 3 players on a tiny map is ok so it's not that bad.

    On large or greater maps the woods is still thin to avoid out of memory errors.

    Ideas and criticism welcome.

    Edit: Start position and starting resource placement not randomized yet.

    Deer, sheep and chicken to be added.

  5. I'm a little surprised as well. In most communities the problem is that players leave before the game is over and ruin it for other players especially when in teams.

    To ensure high gaming quality in public servers the only decent working mechanisms are whitelists and votekicks with all other players agreeing.

    And even then players will sometimes be kicked without a serious reason...

    I can't understand this...

  6. We had a chat on irc and ended up with changing the engine's random map loader so it does the conversion. This means the change will only affect random maps rather than the whole engine so not too much needs changing. So this will need coding, I don't know if you are interested in doing it? Otherwise I can have a go.

    Edit: Also it must be documented (or we risk histroric bruno's wrath).

    Well, I don't know if I can do it and what '...engine's random map loader so it does the conversion...' means in total, since I only read the rmgen libs yet.

    However, I can of cause look into it and I would like to help documenting the results to RMS scripters.

    The documentation of code change should of cause be done by the person who changes it...

    I'll look deeper into the code on Monday.

  7. Yeah, when we have running & charging, cavalry will be able to run down skirmishers quite easily.

    If they are able to hit an enemy running away at all (which is not the case a.t.m. since the attack will be broken up cause target out of range)

    By the way... what about ranged cavalry?

    I agree that chasing (running) could solve some things.

    If an attack deals damage right at the beginning of the attack animation it could help melee units as well (and is realistic since the unit can arrange his attack while running)

    However, it will be a bit out of sync with the animation unless there will be a chasing animation with raised weapons.

  8. 1st: The army camp costs mainly wood witch is (on most maps) massively available.

    2nd: The normal fortress is to cheep in my opinion

    Lets calculate: 15 Upkeep, 20 garrison space and production building ~= 3 towers (125 resources each) + 3 celt huts (100 wood each) + barracks (200 resources) -> 675 resources... and I didn't took in consideration the firepower (I think > than 3 towers) and that you can produce better units.

  9. I would like to replace the current unit placement angle with the anticlockwise angle from positive x. This is quite a big change though, I don't know what the other programmers think about it.

    Well, then talk to them.

    I don't really mind what comes out in the end, but I think (like stated above) the advantages of default x/y plain behavior are greater than both, the 3D mathematical consistence and the clockwise rotation.

    Whatever happens one thing is important to me:

    Unit placement and the functions of the rmgen libs have to be consistent!

    If I can do anything just ask... I just don't know how to help ATM.

  10. You can do that I think. Painters are only dependent on an array of points no matter the number/placement.

    Hm, ok.

    Did this by:

    var placer = new ClumpPlacer(1, 1, 1, 1, x, z);
    var painter = [new TerrainPainter(terrainWood), new ElevationPainter(randFloat())]; // new TileClassPainter(clForest)
    createArea(placer, painter);

    for every single tile.

    The TileClassPainter is commented out because he throws an error. (Not a problem for me cause I can add them by addToClass but in general it is)

    A problem is that the SmoothElevationPainter does not work properly too. Even if I set height to 0 and no matter if I choose ELEVATION_MODIFY or ELEVATION_SET a single tile is alway very high on the left side (perhaps +10) and about half as high on the right.

    However, it works with ElevationPainter as I did it manually.

    Thx! Just needed a little motivation ^^

    What happens if you place 2 clump placers at the same position when painting entities. Will there be 2 placed at the center of the same tile?

  11. When I have a list of tiles for example tileList = [[23, 116], [23, 117], [65, 86]] is it possible to use the standard area/placers/painters/constraints methods to place terrain/hight/... on them?

    As you can see the tiles in the list are not necessarily connected.

    I can add them to a tile-class or place terrain and set hight manually but I want them only to be placed if constraints are ok so their placement has to check other tile-classes.

    So it would already help if I could check the constraints of the other tile-classes.

    I would be grateful if someone could help me with that.

    I don't mind the notation like tileList = [x1, z1, x2, z2...] or whatever.

  12. theta > 0 since phi < 2*pi though.

    Oh, true x)

    But theta < 0 because it's the angle from vector to point1 towards vector to point2.

    It just that phi - theta = 2*PI (not phi + theta = 2*PI) no matter how often you rotate them around full circle.

    That make phi = 2*PI + theta, but since theta < 0 -> phi < 2*PI.

    Sorry x)

    Though it's a wonderful conversation :thumbup:  but I have to go , will get back to this tomorrow... 

  13. Exactly!

    It should be phi but it doesn't really matter cause sin/cos will give the same values, or? Edit, yes, they do. and you get the same result when using them for building placement.

    Otherwise phi%(2*PI) Edit: Makes no sense, always smaller than 2*PI and never negative.

    So the current function is basically getDirection but using anticlockwise from the x axis rather than clockwise from the z axis which is what buildings use?

    Yes, and both should be consistent of cause.

    As we agree that z should just be taken as y counter clockwise starting from positive x would be the choice to take.

  14. This function will return the angle of the vector from point 1 to point 2. So since the vector from (1,0) to (0,0) is (-1,0) the function is behaving correctly (for what I thought it should be doing). This unfortunately doesn't seem to be what you are wanting from this function.

    From what you say I think you want the acute angle between the line passing through points 1 and 2 and the x axis. Is this correct?

    When I made the request to add this functions I thought of (though I didn't clearly say, sry):

    With 2 given points (witch also can be interpreted as vectors from [0, 0] to this point):

    point1 = [x1, y1]

    point2 = [x2, y2]

    getVector(point1, point2) returning the vector from point1 to point2: [x2-x1, y2-y1]

    getDistance(point1, point2) returning the distance between 2 points: Math.pow(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2), 1/2)

    getAngle(point1, point2) returning the angle between the vectors to point1 and point2.

    getDirection(point1, point2) returning the angle between getVector(point1, point2) and and a vector directed where a unit faces to when placed with angle = 0.

    Since we agreed to use z as y it would be getAngle(getVector(point1, point2), [1, 0]) with counter clockwise rotation with growing angle (as far as unit placement is done this way too).

    And, yes, as I use the function now it's the angle of the line between the 2 points towards the coordinate system.

     

  15. From my point of view I would like to see more "battle simulation" type of features implemented [...]

    I totally agree!

    Balancing should be watched at this stage to ensure high playability when hitting beta.

    However, some things like 'allowed targets' can make a huge difference and are not implemented fully right now as far as I know.

  16. Thanks for the fix.

    I am not sure why you think it should be changed to z1-z2, I have attached a diagram and my testing matches with the diagram.

    You are right, kept x/y2 = 0 which was wrong. Need to keep x/y1 = 0 to see against which axis it turns.

    Fixed the values for BUILDING_ANGlE in my post that I got wrong 1st.

    Edit: There's still something strange (from mainlog.html):

    getAngle(1, 0, 0, 0) = 3.141592653589793 <- Should be 0 or?

    getAngle(1, 1, 0, 0) = -2.356194490192345

    getAngle(0, 1, 0, 0) = -1.5707963267948966

    getAngle(-1, 1, 0, 0) = -0.7853981633974483

    getAngle(-1, 0, 0, 0) = 0

    getAngle(-1, -1, 0, 0) = 0.7853981633974483

    getAngle(0, -1, 0, 0) = 1.5707963267948966

    getAngle(1, -1, 0, 0) = 2.356194490192345

    (Everything's right from this point on though)

    getAngle(0, 0, 1, 0) = 0

    getAngle(0, 0, 1, 1) = 0.7853981633974483

    getAngle(0, 0, 0, 1) = 1.5707963267948966

    getAngle(0, 0, -1, 1) = 2.356194490192345

    getAngle(0, 0, -1, 0) = 3.141592653589793

    getAngle(0, 0, -1, -1) = -2.356194490192345

    getAngle(0, 0, 0, -1) = -1.5707963267948966

    getAngle(0, 0, 1, -1) = -0.7853981633974483

    By the way, generally I agree with you the map surface plane should act like x/y plane. I just guess that when making the engine the clockwise rotation on the plane to design was exactly the idea that made them choose x/z (or more accurate z/x rotated by -PI/4).

    I think rotation direction is less of an issue for designers to get used to counter clockwise rotation then for people using trigonometric functions and has to figure out where sin/cos belongs and which sign they should have to act as they like.

    So, yes, it should act like x/y, I agree.

    OT: Did I mention that I hate the edit function of this forum? x)

    It often eats my newlines or adds some or adds spaces at the beginning of the line I add one.  

  17. Thanks for sending this application. However as quoted below this is not necessary for programmers so this means you can get started right away :). If you haven't already discovered it the developers irc channel is a good place to go for quick questions.

    Gameplay, AI, Sound and Graphics Programmers - If you dig 0 A.D., and you can write code, just come as you are and start contributing. We don't want to hinder your progress with any application forms. People who make good, substantial contributions over time will be asked to be a part of the official team anyway. (All contributors will get credit for their work, though). Check out our intro in 0 A.D. programming for more info on how to get started, checking out the code from SVN, submitting patches and more.

    Thanks for the reply. I was told in the chat already.

    Sorry for doing this since it might cause others to do as me, that's not what I intended.

  18. My logic was to look at what is being represented by the coordinates rather than the variable names. Basically we have the map which is the x-z plane. In the default orientation on the minimap x positive is right and z positive is up, so we are using the standard x-y plane with y labeled as z. This is the way people creating maps should be thinking about it since they are working in 2d (or 2.5d). The labeling is an unfortunate consequence of the coordinates being chosen in the 3D engine and then being directly transferred into the 2D system used for the games simulation. Changing at this point would be far too much hassle for what is gained.

    Well, then you have to change the unit angle for placement too to stay consistent.

    Angle of 0 then should mean facing positive x, PI/2 facing bottom (on the minimap) and so on.

    The BUILDING_ANGlE then should be -PI/4 instead of 3*PI/4 (Edited, got it wrong 1st)

    By the way, I use it and it crashes with:

    ERROR: JavaScript error: maps/random/rmgen/library.js line 620 ReferenceError: assignment to undeclared variable output getAngle(98,86,103,55)@maps/random/rmgen/library.js:620 @maps/random/fexor.js:119ERROR: CMapGeneratorWorker::Run: Failed to load RMS 'maps/random/fexor.js'

    Checking my map and the libs...

    Edit: Just remove the 'output =' after the 'return' Edit: Thx for the fix, now it works as x/y plain

    Edit: And it has to read:

    function getAngle(x1, z1, x2, z2)
    {
    return Math.atan2(z1 - z2, x1 - x2);
    }

    Otherwise it's the angle towards negative x axis...

×
×
  • Create New...