Funtion Aoe 3

25
Introduction So okay if we want to get more advance and add water trade routes, I think first we will need to start with the basics of how to not "mod", but rather "create" RMs. That is, instead of moddifying the script that already exists, we start with a blank page and we know what functions to copy and paste to make the script do what ever we want to with great freedom. For example, say we want to make a Missouri River map. What if instead of adding Great Plains grass to the Pampas map and adding the appropriate Great Plains fauna to the Pamaps map, we were able to trully create a Missouri River map. That is, we could arbitrarilly decide we want the course of the river to take, the size of the river width, have tributaries, and have river bluffs. Instead of being limited to RM scripts that already exist, such as modding Saqueny into Alaska, we could create any map we wanted from scratch with total freedom. This "creating" is a more difficult knowledge than "modding", but a much more powerful knowledge than "modding". I would like this thread to be used for exchanging ideas for the testing of RMs built from scratch and for eventually creating a master list of what every function does in the context of creating from scratch. The "library of functions" will be me editting this original post. It will later include knowledge of all the functions from the Monte Python RMS tutorial. I don't have enough time to list them right now. Library of RMS Functions Introduction As a start to our knowledge, let's discuss what is a "function". In mathematics classes, we learn that a function is when you have an operation where you input a value and the outputed value is different from the inputed value. Examples of continuous functions are like parabolas and sine waves. but now we want number functions.

description

algunas funciones para RMS de AOE3

Transcript of Funtion Aoe 3

Page 1: Funtion Aoe 3

Introduction

So okay if we want to get more advance and add water trade routes, I think first we will need to start with the basics of how to not "mod", but rather "create" RMs.

That is, instead of moddifying the script that already exists, we start with a blank page and we know what functions to copy and paste to make the script do what ever we want to with great freedom.

For example, say we want to make a Missouri River map. What if instead of adding Great Plains grass to the Pampas map and adding the appropriate Great Plains fauna to the Pamaps map, we were able to trully create a Missouri River map. That is, we could arbitrarilly decide we want the course of the river to take, the size of the river width, have tributaries, and have river bluffs.

Instead of being limited to RM scripts that already exist, such as modding Saqueny into Alaska, we could create any map we wanted from scratch with total freedom.

This "creating" is a more difficult knowledge than "modding", but a much more powerful knowledge than "modding".

I would like this thread to be used for exchanging ideas for the testing of RMs built from scratch and for eventually creating a master list of what every function does in the context of creating from scratch.

The "library of functions" will be me editting this original post.

It will later include knowledge of all the functions from the Monte Python RMS tutorial. I don't have enough time to list them right now.

Library of RMS Functions Introduction

As a start to our knowledge, let's discuss what is a "function".

In mathematics classes, we learn that a function is when you have an operation where you input a value and the outputed value is different from the inputed value.

Examples of continuous functions are like parabolas and sine waves.

but now we want number functions.

In statistics class I learned that there are some main logical functions:

(a) AND

(b) OR

(c) NOT

(d) GREATER THAN OR EQUAL TO

(e) LESS THAN OR EQUAL TO

Page 2: Funtion Aoe 3

(f) >

(g) <

(h) INTERSECT

(i) TRUE

(j) FALSE

The number logical functions can be continous, like finding a temperature between 70 degrees F and 71 degrees F is continuous since decimal answers are included.

The number logical functions can be discrete, like you can only have a true or false answer.

In statistics we learn that AND function is multiplying the numbers together.

In statistics we learn that OR function is adding the numbers together.

In statistics we learn that NOT function is subtracting 1 - OR.

See we just created a new function, the NOT function, by using the OR function.

In statistics for finding the binomial probability, we could use for factorial multipling and mulitplying many times. but instead we use the factorial function. We could use the factorial function many times, but instead we can program the calculator to have a binomial probability function.

So we can create a new function by defining it in terms of functions that already exist and then only calling to the new higher level function instead of entering in all of the lower level functions.

So it should be perfectly possible to create a new function in RM scripting as well.

In fact, that "new function" is called a "trigger".

So to create a "new function", also known as a "trigger", we are just using lower level functions to build the higher level function.

but before we go creating new functions, let's establish what RM functions already exist.

So first of all, how do we do these basic functions in RM scripting.

These basic functions that is, are labled (a) - (j).

Here is how to do them labled with numbers below once someone tells me how to do them (filled with "null" until I know what the function is):

(1) AND:&&

Example:

Page 3: Funtion Aoe 3

(2) OR:||

Example:

(3) NOT:!=

Example:

(4) GREATER THAN OR EQUAL TO:>=

Example:

(5) LESS THAN OR EQUAL TO:<=

Example:

(6) >:>

Example:

(7) <:<

Example:

(8) INTERSECT:==

Example:

Page 4: Funtion Aoe 3

(9) TRUE:bool myCheckIfItIsTrue = "true";

Example:

(10) FALSE:bool myCheckIfItIsTrue = "false";

Example:

Defining and Calling a Function

(Credit to the Monte Python RMS tutorial for the copy and pasting)

We must define a function before we can call it.

Defining a Function: int myRMSFunction (int x=0) { return(x+2); }

You all know functions from Maths, like y=x+2. As you can see, this function is also an equation. A function in a program code (like the random map script) can also contain an equation. It can even contain a few equations and also commands. We can also write the Math function y=x+2 in RMS code. It would look like this:int myRMSFunction (int x=0) { return(x+2); }You see, we need a bit more to define, in order to tell the AOE3 program, which kind of variables we want to use. First, we gave our function a name (myRMSFunction) and defined it as an integer variable. In the brackets () we defined the input variable x. You see, we defined also x as integer with value 0, but we can change this value when we call this function later in our script.

Calling a Function: myRMSFunction (3);

To call a function just means that we want to execute this function and want to get the result. Now, let's call this function:myRMSFunction (3);Well, nothing happens! Really? No! What have we done? We inserted "3" into the brackets, so this means that x now has the value "3" instead of the old value "0". Since we called this function, everything within the brackets {} will be executed. Since x is now "3", we get a value for the variable myRMSFunction, which is "5" and surely of type integer, as we defined it before. The command "return" just executes the equation in the brackets of "return()". Now you can easily see, that myRMSFunction(3) is nothing but the y of our math equation, when using x=3. Even more, you are now be able to use this function like a regular integer variable! However, do not forget to insert a correct variable into the bracket, since x has to be an integer. Well, why don't we use float for x and myRMSFunction? Simple answer: Don't use it if not necessary, since calculating integers works much faster than calculating floats.

Page 5: Funtion Aoe 3

Now we are able to call this function in our RMS as often as we want and with different integer values. 

In a random map script there are two different kinds of functions, predefined functions and custom functions.

Predefined functions are already defined by the AOE3 program. Most of them start with the letters "rm...".Example: "rmEchoInfo("Large map");".

You have to define all additional custom functions BEFORE you define the function main.

You can even call a custom function in a definition of a new custom function, but the function you call has to be defined BEFORE you call it.

So see we can have total freedom by creating custom functions, since we can use a predefined function to create custom functions and the custom functions can be defined using custom functions.

The Void Main Function:void main(void) {

Now that we know what a function is, we can say what the void main function is. The void main function is predefined function. The void main function specifies the begging of the script after the "includes".

Like this: 

// EASTER ISLAND//Gamma Release. I think Tahattus made it.// Main entry point for random map script

include "mercenaries.xs";include "GWevent.xs";

void main(void){// --------------- Make load bar move. ----------------------------------------------------------------------------rmSetStatusText("",0.10);

// Define Carib Nativesint subCiv0=-1;int subCiv1=-1;int subCiv2=-1;

if (rmAllocateSubCivs(3) == true) {subCiv0=rmGetCivID("caribs");rmEchoInfo("subCiv0 is caribs "+subCiv0);if (subCiv0 >= 0)rmSetSubCiv(0, "caribs");

Page 6: Funtion Aoe 3

subCiv1=rmGetCivID("caribs");rmEchoInfo("subCiv1 is caribs "+subCiv1);if (subCiv1 >= 0)rmSetSubCiv(1, "caribs");

subCiv2=rmGetCivID("caribs");rmEchoInfo("subCiv2 is caribs "+subCiv2);if (subCiv2 >= 0)rmSetSubCiv(2, "caribs");}

All the way at the end of the script is:

if (cNumberNonGaiaPlayers <5)// If less than 5 players, place extra fish.{rmPlaceObjectDefAtLoc(fishID, 0, 0.5, 0.5, 10*cNumberNonGaiaPlayers);}

// --------------- Make load bar move. ----------------------------------------------------------------------------rmSetStatusText("",0.99);

// RANDOM TREES

int randomTreeID=rmCreateObjectDef("random tree");rmAddObjectDefItem(randomTreeID, "treeCaribbean", 1, 0.0);rmSetObjectDefMinDistance(randomTreeID, 0.0);rmSetObjectDefMaxDistance(randomTreeID, rmXFractionToMeters(0.5));rmAddObjectDefConstraint(randomTreeID, avoidImpassableLand);rmAddObjectDefConstraint(randomTreeID, avoidTC);rmAddObjectDefConstraint(randomTreeID, avoidCW);rmAddObjectDefConstraint(randomTreeID, avoidAll); rmAddObjectDefConstraint(randomTreeID, smallMesaConstraint);rmPlaceObjectDefInArea(randomTreeID, 0, bigIslandID, 8*cNumberNonGaiaPlayers); //Scatter 8 random trees per player.

}

See that the last bracket is indented the same as the void main function bracket. You must always close the brackets of the void main function.

See that all of the functions's brackets other than void main are intended to the right of the void main function's brackets.

So in simplest form if what was inside the void main function was not included, the Easter Island RMS would look like this:

// EASTER ISLAND//Gamma Release. I think Tahattus made it.// Main entry point for random map script

include "mercenaries.xs";

Page 7: Funtion Aoe 3

include "GWevent.xs";

void main(void){}

The RMS file always ends with the void main function closing bracket.

Nothing else can come after the void main function closing bracket that isn't a comment.

Remember that of course a comment is simply: //

Now we are well on our way to creating our very own RMS completely from scratch.

We want to create an Island.

To create an Island, we will need to use the functions reffered to by the Monte Python RMS tutorial and put those functions inside the void main function brackets.

Let's see if we can get just an island to appear in game with no trade route, no town centers, no natives, no trees, no mines, no objects, no herdables, no fish, no whales, no berry bushes, and no triggers.

Of course this is why I am referencing to the Easter Island RM, because it makes an island, as well as Tahattus or whoever made it has left some great comments about what the functions do.

The Easter Island RM that I keep refering to is in the Gamma release of the mod War of the Triple Alliance for The Asian Dynasties expansion pack + The War Chiefs expansion pack + the original Age of Empires III game + TAD 1.03 patch.

The Monty Python RMS tutorial that I keep referring to is here.

Just to let you know, the Easter Island map is hidden in Wotta Gamma and won't appear in the custom maps.The map xml and xs files for Easter Island are in RM3 but it won't appear in the custom maps.

Introduction to Deleting Functions to Test the Effects on the Map In Game

First you want to create xml and xs files called "testmap01".

Copy and paste an existing map you want to mod and rename it as "testmap01.xml"

Page 8: Funtion Aoe 3

and "testmap01.xs".

Change the display name in the xml file from the name of the map to "testmap01".

For an example here, we will use the Texas Winter map from the Monte Python RMS tutorial. Shame on you if you can't mod Texas into Texas Winter, you should read that tutorial to learn how to do that if you don't know how to before continuing to read this thread.

Can someone please help me, I have run into a silly extremely n00b problem.

I wanted to test what effects deleting functions in an RMS would have in game, so I made a map called "testmap01".

It is the Texas Winter Map copy and pasted and with the .xml and the .xs files renamed to "testmap01.xs" and "testmap01.xml" with display name in the xml file changed from "Texas Winter dietermoreno" to "testmap01".

For now I have not touched the map script, but the testmap01 won't show up in custom maps.

The Texas Winter map shows up in custom maps, but the testmap01 won't show up in custom maps.

Here is the xml file:

<?xml version = "1.0" encoding = "UTF-8"?><mapinfo details = "25997" imagepath = "ui\random_map\texas" displayName = "testmap01" cannotReplace = "" loadDetails="35876" loadBackground="ui\random_map\texas\texas_map"> <loadss>ui\random_map\yukon\yukon_ss_01</loadss> <loadss>ui\random_map\yukon\yukon_ss_02</loadss> <loadss>ui\random_map\yukon\yukon_ss_03</loadss></mapinfo>

The .xs file is the exact same as the Texas Winter map in the Monty Python tutorial.

What is the solution to make it appear in custom maps?

Don't forget that for custom maps you must copy and paste the xml and xs files into the "users/owner/documents/my games/age of empires 3/RM3/" directory or for WotTA into "users/owner/documents/my games/War of the Triple Alliance/RM3/".

Or else it won't appear on the custom map screen!

Now your "testmap01" appears on the custom map screen and the map loads and you can start a game.

Now as well the Easter Island map can be played on in WotTA if you copy and paste it to its correct local user documents folder. That map actually has an island with a

Page 9: Funtion Aoe 3

custom shape, so it is a very interesting map for our learning.

Now on your "testmap01", delete the trade route codes and see what happens. You in theory should have a map with no trade route.

Remember that your testmap01 is a renamed Winter Texas.

Delete these trade route codes:

int tradeRouteID = rmCreateTradeRoute();// rmAddTradeRouteWaypoint(tradeRouteID, 0.1, 0.9);// rmAddTradeRouteWaypoint(tradeRouteID, 0.4, 0.6);// rmAddTradeRouteWaypoint(tradeRouteID, 0.6, 0.4);

// NOTE: weird conditional stuff in trade route waypoint location is// to account for weird edge cases in FFA games where sometimes TCs wouldn't place.if ( cNumberTeams == 2 ){rmAddTradeRouteWaypoint(tradeRouteID, 0.8, 1.0);}else{rmAddTradeRouteWaypoint(tradeRouteID, 0.85, 1.0);}rmAddTradeRouteWaypoint(tradeRouteID, 0.8, 1.0);rmAddTradeRouteWaypoint(tradeRouteID, 0.65, 0.65);rmAddTradeRouteWaypoint(tradeRouteID, 0.65, 0.35);if ( cNumberTeams == 2 ){rmAddTradeRouteWaypoint(tradeRouteID, 0.8, 0.0);}else{rmAddTradeRouteWaypoint(tradeRouteID, 0.85, 0.0);}// rmAddRandomTradeRouteWaypoints(tradeRouteID, 0.8, 1.0, 8, 8);

bool placedTradeRoute = rmBuildTradeRoute(tradeRouteID, "dirt");

if(placedTradeRoute == false)rmEchoError("Failed to place trade route #1");

// float tradeRouteLoc2 = rmRandFloat(0,1);int tradeRouteID2 = rmCreateTradeRoute();if ( cNumberTeams == 2 ){rmAddTradeRouteWaypoint(tradeRouteID2, 0.2, 0.0);}else{rmAddTradeRouteWaypoint(tradeRouteID2, 0.15, 0.0);}rmAddTradeRouteWaypoint(tradeRouteID2, 0.35, 0.35);rmAddTradeRouteWaypoint(tradeRouteID2, 0.35, 0.65);

Page 10: Funtion Aoe 3

if ( cNumberTeams == 2 ){rmAddTradeRouteWaypoint(tradeRouteID2, 0.2, 1.0);}else{rmAddTradeRouteWaypoint(tradeRouteID2, 0.15, 1.0);}

bool placedTradeRoute2 = rmBuildTradeRoute(tradeRouteID2, "carolinas\trade_route");if(placedTradeRoute2 == false)rmEchoError("Failed to place trade route #2");

// Trade sockets int socketID=rmCreateObjectDef("sockets to dock Trade Posts"); rmAddObjectDefItem(socketID, "SocketTradeRoute", 1, 0.0);rmSetObjectDefAllowOverlap(socketID, true); rmAddObjectDefToClass(socketID, rmClassID("importantItem")); rmSetObjectDefMinDistance(socketID, 0.0); rmSetObjectDefMaxDistance(socketID, 6.0);

// add the meeting poles along the trade route. rmSetObjectDefTradeRouteID(socketID, tradeRouteID); vector socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, 0.30); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc);

socketLoc = rmGetTradeRouteWayPoint(tradeRouteID, 0.60); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc);

// change the trade route for the new sockets rmSetObjectDefTradeRouteID(socketID, tradeRouteID2);socketLoc = rmGetTradeRouteWayPoint(tradeRouteID2, 0.30); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc);

socketLoc = rmGetTradeRouteWayPoint(tradeRouteID2, 0.60); rmPlaceObjectDefAtPoint(socketID, 0, socketLoc);

// Text rmSetStatusText("",0.30);

/* // Second set of poles poleLoc = rmGetTradeRouteWayPoint(tradeRouteID2, 0.3); rmPlaceObjectDefAtPoint(poleID, 0, poleLoc);

poleLoc = rmGetTradeRouteWayPoint(tradeRouteID2, 0.6); rmPlaceObjectDefAtPoint(poleID, 0, poleLoc); */

See that trade route stuff is an additional type of function in addition to area functions used to create areas.

Comment something like this where you deleted the trade route functions so you know where they are so you can put them back if you want to if you mess up:

Page 11: Funtion Aoe 3

//Trade route stuff removed by Dieter that was right here//end removed trade route functions

We have deleted the trade route functions now, so now when you start the game your map has no trade route.

You look at the map after you click resign and you see that the map has no trade route.

That went well, so now let's delete the town center placement functions, the native placement functions, and the nugget placement functions so we can change the area functions without worrying about the map failing to load from town centers placing on top of each other or something strange like that.

Where you delete stuff, always comment where you deleted it so you can find it if you mess up.

For herdables, delete these functions:

// Place some extra small-ish Pronghorn herds. // DAL int pronghornHerdID=rmCreateObjectDef("pronghorn herd edge"); rmAddObjectDefItem(pronghornHerdID, "pronghorn", rmRandInt(2,4), 6.0); rmSetObjectDefMinDistance(pronghornHerdID, 0.5); rmSetObjectDefMaxDistance(pronghornHerdID, rmXFractionToMeters(0.9));rmAddObjectDefConstraint(pronghornHerdID, centerConstraintFar);rmAddObjectDefConstraint(pronghornHerdID, longPlayerConstraint);rmSetObjectDefCreateHerd(pronghornHerdID, true);numTries=cNumberNonGaiaPlayers*2;

for (i=0; <numTries){rmPlaceObjectDefAtLoc(pronghornHerdID, 0, 0.5, 0.5);}

For forests, delete these functions:

// Define and place forests - north and southint forestTreeID = 0;

numTries=5*cNumberNonGaiaPlayers; // DAL - 5 here, 5 belowfailCount=0;for (i=0; <numTries){ int westForest=rmCreateArea("westForest"+i);rmSetAreaWarnFailure(westForest, false);rmSetAreaSize(westForest, rmAreaTilesToFraction(150), rmAreaTilesToFraction(150));rmSetAreaForestType(westForest, "yukon forest"); /* old forest type was "texas forest dirt" */rmSetAreaForestDensity(westForest, 0.7);rmSetAreaForestClumpiness(westForest, 0.4);rmSetAreaForestUnderbrush(westForest, 0.0);rmSetAreaMinBlobs(westForest, 1);rmSetAreaMaxBlobs(westForest, 3);

Page 12: Funtion Aoe 3

rmSetAreaMinBlobDistance(westForest, 5.0);rmSetAreaMaxBlobDistance(westForest, 20.0);rmSetAreaCoherence(westForest, 0.4);rmSetAreaSmoothDistance(westForest, 10);rmAddAreaConstraint(westForest, avoidImportantItem); // DAL added, to try and make sure natives got on the map w/o override.rmAddAreaConstraint(westForest, avoidCoin);rmAddAreaConstraint(westForest, playerConstraintForest);// DAL adeed, to keep forests away from the player.rmAddAreaConstraint(westForest, forestConstraint);// DAL adeed, to keep forests away from each other.rmAddAreaConstraint(westForest, Westward);// DAL adeed, to keep these forests in the west.rmAddAreaConstraint(westForest, avoidTradeRoute);rmAddAreaConstraint(westForest, avoidCliffs);rmAddAreaConstraint(westForest, forestsAvoidBison);if(rmBuildArea(westForest)==false){// Stop trying once we fail 5 times in a row. failCount++;if(failCount==5)break;}elsefailCount=0; }

numTries=5*cNumberNonGaiaPlayers; // DAL - 5 here, 5 above.failCount=0;for (i=0; <numTries){ int eastForest=rmCreateArea("eastForest"+i);rmSetAreaWarnFailure(eastForest, false);rmSetAreaSize(eastForest, rmAreaTilesToFraction(150), rmAreaTilesToFraction(150));rmSetAreaForestType(eastForest, "yukon snow forest"); /* old forest type was "texas forest" */rmSetAreaForestDensity(eastForest, 0.7);rmSetAreaForestClumpiness(eastForest, 0.4);rmSetAreaForestUnderbrush(eastForest, 0.0);rmSetAreaMinBlobs(eastForest, 1);rmSetAreaMaxBlobs(eastForest, 3);rmSetAreaMinBlobDistance(eastForest, 5.0);rmSetAreaMaxBlobDistance(eastForest, 20.0);rmSetAreaCoherence(eastForest, 0.4);rmSetAreaSmoothDistance(eastForest, 10);rmAddAreaConstraint(eastForest, avoidImportantItem);// DAL added, to try and make sure natives got on the map w/o override.rmAddAreaConstraint(eastForest, avoidCoin);rmAddAreaConstraint(eastForest, playerConstraintForest);// DAL adeed, to keep forests away from the player.rmAddAreaConstraint(eastForest, forestConstraint);// DAL adeed, to keep forests away from each other.rmAddAreaConstraint(eastForest, Eastward);// DAL adeed, to keep these forests in the east.rmAddAreaConstraint(eastForest, avoidTradeRoute);rmAddAreaConstraint(eastForest, avoidCliffs);

Page 13: Funtion Aoe 3

rmAddAreaConstraint(eastForest, forestsAvoidBison);if(rmBuildArea(eastForest)==false){// Stop trying once we fail 5 times in a row.failCount++;if(failCount==5)break;}elsefailCount=0; }

For mines, delete these functions:

// More coin in the middle int middleMineType = -1; int middleMineID = -1; for(i=0; < 2) { middleMineType = rmRandInt(1,4); middleMineID = rmCreateObjectDef("center middleMine "+i); rmAddObjectDefItem(middleMineID, "mine", 1, 0.0); rmSetObjectDefMinDistance(middleMineID, 0.0); rmSetObjectDefMaxDistance(middleMineID, rmXFractionToMeters(0.10));rmAddObjectDefConstraint(middleMineID, coinAvoidCoin);rmAddObjectDefConstraint(middleMineID, avoidImportantItem); rmAddObjectDefConstraint(middleMineID, avoidImpassableLand); rmAddObjectDefConstraint(middleMineID, avoidTradeRoute);rmAddObjectDefConstraint(middleMineID, avoidAll);rmAddObjectDefConstraint(middleMineID, avoidCliffs);rmPlaceObjectDefAtLoc(middleMineID, 0, 0.5, 0.5); }

for(i=0; < 2) { middleMineType = rmRandInt(1,4); middleMineID = rmCreateObjectDef("south middleMine "+i); rmAddObjectDefItem(middleMineID, "mine", 1, 0.0);rmSetObjectDefMinDistance(middleMineID, 0.0); rmSetObjectDefMaxDistance(middleMineID, rmXFractionToMeters(0.10));rmAddObjectDefConstraint(middleMineID, coinAvoidCoin);rmAddObjectDefConstraint(middleMineID, avoidImportantItem); rmAddObjectDefConstraint(middleMineID, avoidImpassableLand); rmAddObjectDefConstraint(middleMineID, avoidTradeRoute);rmAddObjectDefConstraint(middleMineID, avoidAll);rmAddObjectDefConstraint(middleMineID, avoidCliffs);rmPlaceObjectDefAtLoc(middleMineID, 0, 0.5, 0.2); }

for(i=0; < 2) { middleMineType = rmRandInt(1,4); middleMineID = rmCreateObjectDef("north middleMine "+i); rmAddObjectDefItem(middleMineID, "mine", 1, 0.0);rmSetObjectDefMinDistance(middleMineID, 0.0); rmSetObjectDefMaxDistance(middleMineID, rmXFractionToMeters(0.10));

Page 14: Funtion Aoe 3

rmAddObjectDefConstraint(middleMineID, coinAvoidCoin);rmAddObjectDefConstraint(middleMineID, avoidImportantItem); rmAddObjectDefConstraint(middleMineID, avoidImpassableLand); rmAddObjectDefConstraint(middleMineID, avoidTradeRoute);rmAddObjectDefConstraint(middleMineID, avoidAll);rmAddObjectDefConstraint(middleMineID, avoidCliffs);rmPlaceObjectDefAtLoc(middleMineID, 0, 0.5, 0.8); }

For extra mines, delete these functions:

// Two extra silver mines in the spots where the natives aren't.silverType = rmRandInt(1,10);int extraGoldID = rmCreateObjectDef("extra silver "+i);rmAddObjectDefItem(extraGoldID, "mine", 1, 0.0);rmAddObjectDefToClass(extraGoldID, rmClassID("importantItem"));rmAddObjectDefConstraint(extraGoldID, avoidCoin);rmAddObjectDefConstraint(extraGoldID, avoidCliffs);rmAddObjectDefConstraint(extraGoldID, avoidImportantItemSmall);

rmSetObjectDefMinDistance(extraGoldID, 0.0);rmSetObjectDefMaxDistance(extraGoldID, 10.0);

if ( whichVariation > 4 ){rmPlaceObjectDefAtLoc(extraGoldID, 0, 0.9, 0.5);rmPlaceObjectDefAtLoc(extraGoldID, 0, 0.1, 0.5);}else{rmPlaceObjectDefAtLoc(extraGoldID, 0, 0.5, 0.8);rmPlaceObjectDefAtLoc(extraGoldID, 0, 0.5, 0.2);}

Now follow a similar process to complete the rest, to remove the functions for native placement, nugget placement, tree placement, player placement (town center placement), herdable placement, cow placement, and object placement.

Do not delete the constraints functions or the functions that determine how big the map is.

So now from the comments I left we see an RM has a construction like this of all the things that I removed that were originally there:

// TEXAS WINTER - made by dietermoreno - with help of M0nTy_PyTh0n's RMS Tutorial /* old was "TEXAS" */// July 2013 - The Tutorial can be found here: http://hyenastudios.mugamo.com/aoe3rmstutorial.htm /* old was "October 2003" */// Main entry point for random map scriptinclude "mercenaries.xs";void main(void){ // Text // These status text lines are used to manually animate the map

Page 15: Funtion Aoe 3

generation progress bar rmSetStatusText("",0.01);

//Natives picking placement definitions deleted by Dieter //end removed native picking placement functions definitions

//map size here, i didn't remove

// Picks a default water height, i didn't remove

// Picks default terrain and water, i didn't remove

//Choose mercs, i didn't remove

//Corner constraint, i didn't remove

//Define classes, i didn't remove

//Define constraints, i didn't remove

//Define objects, i didn't remove

//wood resources deleted by Dieter //end wood resources functions removed //starting resources deleted by Dieter //end starting resources functions removed

// -------------Done defining objects // Text rmSetStatusText("",0.10);

//player areas stuff removed by Dieter //end player area functions removed

//Create a center area, i didn't remove

// Build the areas. rmBuildAllAreas();

// Text rmSetStatusText("",0.20);

// Placement order// Trade Route -> Players and player stuff -> Natives -> Secrets -> Cliffs -> Nuggets// Place other objects that were defined earlier

// DAL added - two trade routes placed

Page 16: Funtion Aoe 3

//Trade route stuff removed by Dieter that was right here//end removed trade route functions

//starting units stuff removed by Dieter that was right here //end starting units placement functions removed //town center placement stuff removed by Dieter that was right here //end town center placement functions removed

//player starting berry bush stuff removed by Dieter that was right here //end player starting berry bush functions removed

//player starting bison herd stuff removed by Dieter that was right here //end player starting bison herd functions removed

//player starting nugget stuff removed by Dieter that was right here //end player starting nugget functions removed

//player starting outpost stuff removed by Dieter that was right here //end player starting outpost functions removed

//player starting barracks stuff removed by Dieter that was right here //end player starting barracks functions removed

//player starting blockhouse stuff removed by Dieter that was right here //end player starting blockhouse functions removed

//player starting mine stuff removed by Dieter that was right here //end player starting mine functions removed

//player placement stuff removed by Dieter that was right here //end player placement functions removed// TextrmSetStatusText("",0.40);

// Textint numTries = -1;int failCount = -1;

// Central Pond //native definition and placement functions removed by Dieter//end removed native definition and placement functions

//extra mines removed by Dieter//end removed extra mine functions

// Define and place cliffs

// TextrmSetStatusText("",0.60);

//herdables deleted by Dieter//end removed herdable placement functions

Page 17: Funtion Aoe 3

//forests deleted by Dieter//end removed forest placement functions// TextrmSetStatusText("",0.70);

//mines deleted by Dieter//end removed mine placement functions

// */

//define and place nuggets stuff removed by Dieter//end define and place nuggests functions removed

// TextrmSetStatusText("",0.80);

/*rmPlaceObjectDefAtLoc(randomTreeID, 0, 0.5, 0.5, 8*cNumberNonGaiaPlayers);*/

// TextrmSetStatusText("",0.90);

//cow placement and constraint functions removed by Dieter//end cow placement and constraint functions removed

//big decorative things placement and constraint functions removed by Dieter//end big decorative things placement and constraint functions removed

//perching vulchers placement and constraint functions removed by Dieter//end perching vulchers placement and constraint functions removed

// TextrmSetStatusText("",1.0);}}

So now we know that some basic types of functions are:

(a) operators (the first functions we discussed)

(b) void main

(c) define class

(d) define constraints

(e) constraints

Page 18: Funtion Aoe 3

(f) areas

(g) cliffs

(h) player areas

(i) player (town center) placement

(j) native choice definitions

(k) native definitions

(l) native placements

(m) trade route definitions

(n) trade route placement

(o) herdable definitions

(p) herdable placements

(q) mine definitions

(r) mine placements

(s) cow/sheep definitions

(t) cow/sheep placements

(u) tree definitions

(v) tree placements

(w) berry definitions

(x) berry placements

(y) starting unit definitions

(z) starting unit placements

(z1) player starting resource and nugget definitions (put a gold mine, a bison herd, a berry bush, and a treasure near every town center)

(z2) player starting resource and nugget placement

(z3) water definitions

Page 19: Funtion Aoe 3

(z4) water placements

(z5) decorative object definitions

(z6) decorative object placements

(z7) nugget definitions

(z8) nugget placements

(z9) player starting buildings definitions(barracks, outpost, blockhouse, or even a fort was planned on the Texas map)

(z10) player starting buildings placements

(z11) connections

(z12) triggers

In the Monte Python RMS tutorial, we see that there are 

(1) General Purpose Functions

(2) Players Functions: Player locations need to be determined so that objects and area can be placed “by player.” Player areas must still be created as individual areas. A special player in an RM script is the "Gaia" player and always has the player number "0" in a map script.

(3) Area Functions: Areas are regions on a map. They are often irregular in shape, but can be rectangular as well. Some areas are used for placing specific terrain, like a cliff or ocean, while others are just used as boundaries for other areas. Special types of areas are player areas, which belong to a certain player, or team areas, which belong to a team. Saying these areas “belong” is just a convenient method of making sure other areas or objects are placed in that area.

(4) Connection Functions: Connections are special areas that are used to connect other areas. They are typically used to place land-bridges or mountain-passes among players. Connections must be placed after the areas they are trying to connect, but often need to be defined before those areas if the area needs the rmAddConnectionArea command.

(5) Objects Functions: Objects include anything placed on a map that is not a terrain. Buildings, units and resources are all objects. Objects can even be collections of many different units. Just remember that objects are always placed as clusters and sometimes it might be easier to place 2 different objects than to add different types of

Page 20: Funtion Aoe 3

units to one object.

(6) Fair Objects Functions: These special commands are designed to place critical resources, such as TownCenters and sometimes Silver Mines. They are expensive and slow, so should not be used for many objects, but can insure that objects that “must place” are present on a map.

(7) Constraints Functions: Constraints are used for areas, connections, and objects. They make sure that objects avoid other objects, that objects are placed near certain areas and similar restrictions.

(8) Trade Routes Functions: Trade routes are a new feature in the Age series. You create a trade route by placing waypoints for the paths. Later, you place "SocketTradeRoute" objects to the trade route. Trade routes should be created and built straight after the map terrain and player areas were created. All additional objects such as resources, forests, etc. should be placed with a trade route constraint to avoid the routes. Also, make sure you always place waypoints on connected land. 

(9) Triggers Functions: These commands are used to incorporate triggers from the scenario editor into a random map script. Triggers can get complicated quickly and can also create an unfair map, so they must be used with caution. A full explanation of all the triggers is beyond the scope of this article, but you can generate a random map script within the scenario editor to see how the triggers are created-just look at the triggers as if you had set them up manually. You can also look at the "C:\...\Age of Empires III\trigger\typetest.xml" file for help with debugging RMS triggers.

Furthermore, a trigtemp.xs file is generated every time when loading your RMS into the map editor. It will show you all triggers you set into your random map. This file is in xs-trigger code, which looks a bit different from the RMS file. You can find this file in the directory:"C:\...\My Documents\My Games\Age of Empires 3\trigger\trigtemp.xs" .

So now back to the map that we deleted a lot of stuff from.

Page 21: Funtion Aoe 3

Don't forget to save your xs file, and now copy and paste and replace your edited xs file into the ".../documents/my games/..." directory before you test it.

Now let's test it.

[to be continued]