You must be logged in to post messages.
Please login or register

Scenario Design
Moderated by MosheLevi, Mister SCP

Hop to:    
Welcome! You are not logged in. Please Login or Register.735 replies, Sticky
Age of Empires III Heaven » Forums » Scenario Design » The RMS question Thread
Bottom
Topic Subject:The RMS question Thread
« Previous Page  1 ··· 10 ··· 20 ··· 26 27 28 29 30  Next Page »
RF_Gandalf
Skirmisher
posted 04-27-06 06:09 AM EDT (US)         
This thread is intended for discussion of questions regarding Random Map Scripting for AOE3. Instead of posting questions separately in the forum, use this thread which will serve as a collection of (?)wisdom for those looking for information. I will be checking this thread at least several times per week, and I hope that the other experienced scripters will join in to add their wisdom.

For those seeking some basic starting help, try these links to some helpful information:
The Age of Wiki has a useful section on Random Map Scripting.

An AOE3RMS Tutorial by MOnTy PyThOn is a pretty complete guide to help you understand the various commands.

Finally, try downloading some of the map scripts at the Age of Empires IIIHeaven RMS Download section and open the map scripts in a text editor and check them out to see how it is done. You could also open the map scripts that came with the game to study their commands; these will be found in the directory: Program Files\Microsoft Games\Age of Empires III\rm.

So post any RMS questions here, we will try to help!

AuthorReplies:
Neuron
Skirmisher
posted 11-10-13 05:58 AM EDT (US)     676 / 735       
@Peter194

Do you want just to make one map or you want to make maps in general? Because if you only want to make one map once, then learning how to script random maps might not be worth the time.

Random maps have one big advantage over scenarios: you can play with your own decks, not pre-made decks. So they allow for more strategy than scenarios.

Random maps in AOE3 are made by programming in an interpreted language called XS, which was made by the game makers (Ensemble Studios). If you had any programming experience before, then you can learn faster, but if you have no such experience, it will be harder to understand what is a variable, why you need to initialise/define it before using it, what are functions, types of variables, conditional statements, loops and so on.

If you don't want to learn scripting, but just want to make one single map, then you can make a graphic layout of your map and describe it and if it's a good idea (and I have the time), I might script it.

Making a good map is actually pretty hard, but a crap map can be made in an hour. A good map must have a good layout, it must look like a unique place (not just a bunch of lakes and forests thrown around), and it must have good terrain design so that units pathing won't have any problems. Also, the resources distribution and quantity must have a reason behind, so that you give players some strategic choices when they play the map.

If you want to learn random map scripting you can start by playing with the game maps, modifying them until you learn the functions. There is an index of random maps functions at http://aomcodereference.googlecode.com/svn/trunk/doc/aom/scripting/xs/rm/package-summary.html. The index was made for AoM, but random maps functions are mostly the same, except a few are missing from there, such as functions related to trading posts (because AoM had no trading posts).
There's also a list of random maps functions at the Japanese community site: http://tournament.jpn.org/modules/xpwiki/397.html

@Zwartevalk

I think AIs suck on playing on water maps. They do have some plans to go water, but they work 100% only on Amazon and Carribean. I'm pretty sure this is a problem of how the AI in this game was scripted, which everyone says it sucks.

You could try giving each player a starting dock and see if they actually get it that they have to use it. AIs are stupid, anyway.

Another possible solution would be to set maptype to Amazon or Caribean but this will also change the treasure set and the soundscape, so it won't fit the winter seasonal pattern on this map.
Zwartevalk
Skirmisher
posted 11-10-13 06:01 AM EDT (US)     677 / 735       
@Mister SCP, I am using the command rmSetMapType("water");, but none of the 7 Expert computer players built a dock, while some starting town centers were in shooting distance of it. I also searched on the internet and they state that it is a coding thing, where the developers hard-coded into the game on which maps computer players build docks. However, there should be an option somewhere to change AI behaviour - would you (or anyone) know how and where that is possible? It would really help out my map if computer players used the water to their advantage, as they should.

I don't know if you're serious about my name being difficult, since in Dutch it's a pretty easy name (in English it would be Blackfalcon), but I also know some English people or people from other countries have difficulties with it, so I hope it's no big deal. :/
Neuron
Skirmisher
posted 11-10-13 06:08 AM EDT (US)     678 / 735       
@ Zwartevalk

You can install a custom AI (there are a few I think), which might do better on water maps. Or you could set maptype to Amazon or Carribean, or give all players a starting dock (as I suggested in the post above).
Zwartevalk
Skirmisher
posted 11-10-13 07:46 AM EDT (US)     679 / 735       
Thank you for your response, Neuron, I didn't check after I posted mine if there were any updates - if I had, I would've seen your post sooner. :/ I indeed don't want to change the mapType, since randoming that is one of my favourite parts of the code... I'm not sure if I want everyone to start with a dock, which leaves me with dockless computer players. This might also leave potential for a better map, though. I have noted computer players not knowing fog of war, and they try to hunt on the other side of the cliff, resulting in their settlers to walk through the gap which I'm defending. If I just take their lake away, I can place them closer to the top of the map, hopefully giving them more opportunity to hunt and to start farming before they try to reach my part of the map.
Neuron
Skirmisher
posted 11-10-13 08:19 AM EDT (US)     680 / 735       
How about installing one of the improved AIs, I think murdilator made one and there was another one by Felix Hermansson (Custom Draugur AI).
But if you install it, I think both the host and the players need to install it, so that if the host drops from the game, the game doesn't OOS.

[This message has been edited by Neuron (edited 11-10-2013 @ 08:21 AM).]

Aizamk
Skirmisher
posted 11-10-13 12:03 PM EDT (US)     681 / 735       
I don't think the other players installing it makes a difference- if the host drops from the game, the AI just stops working.
Zwartevalk
Skirmisher
posted 11-10-13 01:05 PM EDT (US)     682 / 735       
I have a new question!

I am trying to get treasures working now, and they're giving me pains. I want every player to have 1 treasure of difficulty 1, but sometimes they don't spawn. In my map, players are quite close to the edge of the map and to the water, but I use a constraint for both the avoid edge and avoid water. Why do they still not show up? Is the player area too full? (Is that possible?)

Another question, sometimes random treasure guardians show up, but no treasure. I've had 2 games in a row now where at least 1 random guardian stands around guarding air in the middle of the map. Is there anything I can do about that?
Neuron
Skirmisher
posted 11-10-13 02:08 PM EDT (US)     683 / 735       
This happens a lot in random maps, at least in AoE3. It's probably caused by other objects either colliding in constraints or erasing the already placed objects by placing other stuff on top of them. So that's why you see guards without treasure crates or halves of herds instead of full ones. It's a game engine design problem. All you can do is play around with constraints and orders of placement until you find one which has a lower rate of failure. ^^
Zwartevalk
Skirmisher
posted 11-10-13 03:34 PM EDT (US)     684 / 735       
Neuron, thank you once again. With a new constraint that keeps forests 10 away from nuggets, the starting treasures all spawn and I don't see any wild guardians anymore. I am going to play around a bit with that 10 a bit, 5 was not enough but 10 might be too much... I'm going to try placing native villages as well, and once that is done I think I'm finally ready to play my map!


EDIT: I have a final question, since my map is as good as finished!

I am trying to create native villages for a few days now. After a lot of difficulties with not wanting much code, I finally figured out how to do it shortly (the unknown map has so much excess code!), but I still run into one problem: native villages spawn way too close to town centers, one time even taking its place. How can I change this? I am already using 3 constraints, I will place their code and the native creation codes here:

int nativesAvoidPlayers = rmCreateClassDistanceConstraint("natives vs. players", classPlayer, 30.0);
int avoidStartingUnits=rmCreateClassDistanceConstraint("objects avoid starting units", rmClassID("startingUnit"), 30.0);
int avoidTC=rmCreateTypeDistanceConstraint("objects avoid TC", "towncenter", 25.0);

//Create the first native tribe


for (i = 0; <nativeNumber)
{
rmSetSubCiv(i, native1);
rmEchoInfo("subCiv"+i+" is " + native1);
nativeVillageID = rmCreateGrouping("native village "+i, native1String + rmRandInt(1,5));
rmSetGroupingMinDistance(nativeVillageID, 25);
rmSetGroupingMaxDistance(nativeVillageID, rmXFractionToMeters(0.5));
rmAddGroupingToClass(nativeVillageID, rmClassID("classNatives"));
rmAddGroupingConstraint(nativeVillageID, nativesAvoidImpassableLand);
rmAddGroupingConstraint(nativeVillageID, avoidTradeRoute);
rmAddGroupingConstraint(nativeVillageID, avoidTradeRouteSocket);
rmAddGroupingConstraint(nativeVillageID, nativesAvoidPlayers);
rmAddGroupingConstraint(nativeVillageID, avoidNatives);
rmAddGroupingConstraint(nativeVillageID, tcAvoidEdgeConstraint);
rmAddGroupingConstraint(nativeVillageID, avoidTC);
rmAddGroupingConstraint(nativeVillageID, avoidStartingUnits);
rmPlaceGroupingAtLoc(nativeVillageID, 0, 0.5, 0.5);
}

Does anyone have any idea? Personally I'm totally out, since I don't know another way than constraints to handle these things, but they sometimes almost touch a town center, which is exactly what I do not want. :/

[This message has been edited by Zwartevalk (edited 11-12-2013 @ 01:30 PM).]

Peter194
Skirmisher
posted 11-12-13 02:05 PM EDT (US)     685 / 735       
many thanks for your help. sorry for the late answer.

@neuron: I am going to create a map for my mod, so I will learn how to create random maps. (I also created a native civ, and I want to give it a special map) so I will later add random maps on every mod i upload.

@zwartevalk: Thanks for the Tutorial link, It helped me a lot. I tried to edit a map but it failed :S. hopefully I will soon understand RMS
Neuron
Skirmisher
posted 11-13-13 05:52 AM EDT (US)     686 / 735       
@Zwartevalk

In AoE3 if you give an object a maximum spawn distance of X, it will tend to always spawn at the maximum distance, for some reason. So, if you place natives groupings with a loop at a maximum distance of rmXFractionToMeters(0.5) from point (0.5, 0.5) -- basically the center of the map -- this means you give this object the entire map to spawn. So the object will tend to spawn close to the edges of the map. If town centers are also set to spawn close to the map edge, then they will conflict with native groupings placement.

Try this:

rmSetGroupingMinDistance(nativeVillageID, 0);
rmSetGroupingMaxDistance(nativeVillageID, rmXFractionToMeters(0.3));

I wouldn't use this method of placement for natives, though. If you want to place them per player, you can place them in reference to player starting locations, like they did it in the original Yucatan script (which is a mess, but, at least, it works).

// First detect the position of each player TC and store it in a vector variable
vector TCLoc = rmGetUnitPosition(rmGetUnitPlacedOfPlayer(TCID, i));

// Then place the grouping in reference to the TC position
rmPlaceGroupingAtLoc(nativeVillageID, 0, rmXMetersToFraction(xsVectorGetX(TCLoc)), rmZMetersToFraction(xsVectorGetZ(TCLoc));

But first you will have to set the maximum spawn distance for the object lower, so the native post is at distance X from player TC location.

So, something like this:

rmSetGroupingMinDistance(nativeVillageID, 0);
rmSetGroupingMaxDistance(nativeVillageID, 50);

Or:

rmSetGroupingMinDistance(nativeVillageID, 0);
rmSetGroupingMaxDistance(nativeVillageID, rmRandFloat(25.0,50.0));

Etc.
----------------

For placement with reference to player starting location, you can also use another function which does the same thing:

rmPlaceGroupingAtLoc(nativeVillageID, 0, rmPlayerLocXFraction(i), rmPlayerLocZFraction(i));

But this method is only useful if you want to place native trading posts close to player starting locations. You can also make the posts spawn at fixed locations on the map (like on Great Plains).

In this case, though, you can't define and place the native posts using a loop, you have to make a separate object definition and then place them at different points with different coordinates.


@Peter194

Well, I can give you a simple map script you can use to modify and learn by doing. So, this script gives each player a TC and starting units, the rest of the map is empty, so you can add anything:

// This is the main function, in which all the map functions are executed
void main(void) {

// Use this function to set the map size
rmSetMapSize(300, 300);

// After you defined all the terrain parameters (size, elevation, etc) always initialise the map using this function
rmTerrainInitialize("default", 0.0);

// Define players starting locations
rmSetPlacementSection(0.7, 0.3);
rmSetTeamSpacingModifier(0.6);
rmPlacePlayersCircular(0.33, 0.33, 0);

// Here you can define and create areas you use in your map script

//..........

// Here you can create a trade route

// Define starting units for players (explorers, dogs, scouts, orchards are included here, depending on each civ's starting units)
int startingUnits = rmCreateStartingUnitsObjectDef(5.0);

// Use a loop to create an area for each player, and give them a town center and the starting units
for(i=1; <cNumberPlayers) {

// Create players' areas
int id=rmCreateArea("Player"+i);
rmSetPlayerArea(i, id);
rmSetAreaSize(id, rmAreaTilesToFraction(100), rmAreaTilesToFraction(100));

// Define town centers
int TCID = rmCreateObjectDef("Player TC"+i);
rmAddObjectDefItem(TCID, "TownCenter", 1, 0.0);
rmSetObjectDefMinDistance(TCID, 0.0);
rmSetObjectDefMaxDistance(TCID, 5.0);

// Place town centers
rmPlaceObjectDefAtLoc(TCID, i, rmPlayerLocXFraction(i), rmPlayerLocZFraction(i));

// Place starting units
rmPlaceObjectDefAtLoc(startingUnits, i, rmPlayerLocXFraction(i), rmPlayerLocZFraction(i));
}

// Add other stuff here:

// Natives

// Trees, forests

// Lakes

// Mines

// Hunts

// Decoration

}

[This message has been edited by Neuron (edited 11-13-2013 @ 06:57 AM).]

dietermoreno
Skirmisher
posted 11-13-13 11:50 PM EDT (US)     687 / 735       
Hi Neuron. The "carribean test" map that I downloaded that you posted in the Wotta forum didn't work. The maps loaded, but the water trade route docks failed to load.

I posted a thread in the Modding Discussions sub forum.

If it helps, here is the exact script: script

Please help. Thanks.


P.S.: In your above post, I tested out the simplest script needed to create a map (that I named "simplest RM.xs") and it worked! Thanks!

Mummy zombies on the Nile map is actually more historically accurate than tanks being destroyed by pikemen.

Want denser forests and a huge Amazon?

[This message has been edited by dietermoreno (edited 11-14-2013 @ 00:57 AM).]

Neuron
Skirmisher
posted 11-14-13 06:58 AM EDT (US)     688 / 735       
I did a random test in 2v2 now:



Btw, someone from Wotta asked me to make a dock owned by nature spawn on the shores on this map, so I made one dock spawn on the island with the trade route, nothing more. I have no idea what they were using it for, I suppose it was for some mod which made docks usable as trading posts. So, I didn't write anything about how these nature docks would be used or captured by players.

Yeah, the simple RMS was for anyone who wants to start learning how to script and doesn't want to waste too much time learning using Ensemble maps, which are not the best example, because very few were written from zero, and most had re-used code from other maps, so many map scripts look chaotic and lack a logical structure.
Zwartevalk
Skirmisher
posted 11-14-13 10:10 AM EDT (US)     689 / 735       
Yeah, I can second the part of Ensemble maps lacking structure, I recognized so many mistakes and I managed to make a 49 kB map with a lot more randomness involved than Unknown! (Only thing I can't get working is the detail text in the .xml file, if anyone has an idea for that I would be very grateful.)

Neuron, I want to thank you once again. Even though I have no idea why objects prefer spawning at their max distance, but when I lowered it to 0.4 they still spawned far away but not on top of town centers anymore. With that out of my way, I created 11 variations of map types and stuff, each having different animals, cliffs, trees etc. Now I can finally play!
Neuron
Skirmisher
posted 11-14-13 10:41 AM EDT (US)     690 / 735       
You're welcome.
when I lowered it to 0.4 they still spawned far away but not on top of town centers anymore. With that out of my way, I created 11 variations of map types and stuff, each having different animals, cliffs, trees etc. Now I can finally play
Hehe cool. Yeah, it's possible to write much shorter scripts than the original maps and put a lot more stuff in them.

The detailsText in the xml file is the text you see in the tooltip when you hover the mouse over the selected map icon.

The loadDetailsText is the map description you see in the map loading screen.

displayName changes the name displayed in the map selection dropdown menu.
dietermoreno
Skirmisher
posted 11-14-13 08:50 PM EDT (US)     691 / 735       
Oh...I assumed it would be on an island with players, so I didn't look on the trade island after I clicked resign.

So that's why you made the "trade island" define class...

Also I was looking for a socket icon on the mini map but I see that actually its a nature brown icon.

I'll look for it on the trade island now as a brown icon on the mini map.

I'll screen shot it.



by the way, I second you that the ES scripts are lacking organization. The ES scripts are all over the place and challenging to learn compared to your simplest script is easy to learn to build things off of.

Then when I am looking at mod maps, which are modified ES scripts, its even more confusing.

I don't know why can't mods just do it like you Neuron and start from scratch. They could have so many more possibilities.

Mummy zombies on the Nile map is actually more historically accurate than tanks being destroyed by pikemen.

Want denser forests and a huge Amazon?

[This message has been edited by dietermoreno (edited 11-14-2013 @ 08:52 PM).]

Peter194
Skirmisher
posted 01-20-14 01:47 PM EDT (US)     692 / 735       
Does some of you know how to create a native in a new random map (or how to edit a existing one)?

what I have:
Native units/techs (that's modding so it isn't important)
a settlement post to place the trading post on (like every native)
and i have created a custom grouping in scenario. then I copied it to the RMS/Groupings folder
so what next?
Neuron
Skirmisher
posted 01-20-14 05:50 PM EDT (US)     693 / 735       
I'll write an example for placing Comanche in a random map:

First tell the random map generator how many native subcivs you're going to have on the map:

rmAllocateSubCivs(1);

If you have 2 set to 2, etc.

Then set the name of each subciv (it starts from 0):

rmSetSubCiv(0, "Comanche");

So, if the hardcoded name of the subciv is cCivComanche you will need to use only "Comanche". It's the same for all civs/subcivs in the game. I'm not sure where the native subcivs are created or where the native sockets unit spawn, tactics, etc, are enabled in the game files (I'm not a modder) so I assume you created the subciv like the other native subcivs. It might be in some civs.xml file and in the proto files.

Then define the grouping object:

int comancheVillageAID = rmCreateGrouping("comanche village A", "native comanche village "+rmRandInt(1,5));
rmSetGroupingMinDistance(comancheVillageAID, 0.0);
rmSetGroupingMaxDistance(comancheVillageAID, rmXFractionToMeters(0.1));
rmPlaceGroupingAtLoc(comancheVillageAID, 0, 0.5, 0.5);

Note that the grouping object creation function has this syntax:

rmCreateGrouping(string name, string filename);

comancheVillageAID is the name of the object which will be used by the game engine as a reference for anything linked to this created object. So it needs to be declared like any new variable in a programming language.

The string name can be any text you want to use to identify the grouping with, such as "some native village 1". The second string must be the name of the file in which you saved the grouping. For Comanche there are 5 different variations for the grouping:

native comanche village 1.xml
native comanche village 2.xml
native comanche village 3.xml
native comanche village 4.xml
native comanche village 5.xml

So, to identify the grouping in the function you use either one name (if you don't have variations), like "native comanche village 1" or you use some function which will add a random or incremented variation for the grouping, like:

"native comanche village "+rmRandInt(1,5)

You only need the first part of the name file, not the extension or the dot. If you use variations and the name of the grouping includes a space at the end, always include the space in the name.

The functions rmSetGroupingMinDistance and rmSetGroupingMaxDistance will give a minimum and maximum possible space for the grouping to spawn. If an object fails to appear on the map, it's a good idea to increase the maximum distance to give it more chance to make it on the map.

rmPlaceGroupingAtLoc will place the grouping at a fixed point, in this case in the middle of the map (coordinates: 0.5, 0.5). The 0 before the coordinates shows the owner of the object, in this case nature/player 0.

Optionally you can use constraints which make sure objects in the map will not collide and possibly fail to spawn. Here's an example of a constraint. First it's defined:

int avoidTC =rmCreateTypeDistanceConstraint("avoid Town Center", "townCenter", 28.0);

then used:

rmAddGroupingConstraint(comancheVillageAID, avoidTC);

Constraints must be, like any variable, defined before they are used. I only wrote them at the end because they are optional if you want to place the grouping at a fixed spot (so, using specific coordinates). Also, place everything related to the grouping (constraints, class assignment, min/max distance settings) before using the rmPlaceGroupingAtLoc. The placement function must always be the last for any defined object.

Example with unknown, new subciv. Let's say the name of the new native subciv is Zulu.

rmAllocateSubCivs(1);
rmSetSubCiv(0, "Zulu");
int zuluVillageID = rmCreateGrouping("write some unique text here", "name of the zulu grouping file");
rmSetGroupingMinDistance(zuluVillageID, 0.0);
rmSetGroupingMaxDistance(zuluVillageID, rmXFractionToMeters(0.1));
rmPlaceGroupingAtLoc(zuluVillageID, 0, 0.5, 0.5);

[This message has been edited by Neuron (edited 01-20-2014 @ 06:14 PM).]

Peter194
Skirmisher
posted 03-26-14 03:02 PM EDT (US)     694 / 735       
okay, I've created the map, included the natives. start playing it a while. but I wasn't satisfied with it.

so I wanted to create a random possibility that the water could be 'eb', I already created a new water (waddenzeedry), based on the bayou swamp.

and tried this:

// Waterlevel
int Waterlevel = rmRandInt(1,2);

if ( waterlevel == 1 )
{
// waterlevel is Flood
rmSetSeaLevel(1.0);
// Picks default terrain and water
// rmSetMapElevationParameters(long type, float minFrequency, long numberOctaves, float persistence, float heightVariation)
rmSetMapElevationParameters(cElevTurbulence, 0.1, 4, 0.3, 2.0);
rmSetSeaType("caribbean coast");
rmEnableLocalWater(false);
rmSetBaseTerrainMix("caribbean grass");
rmTerrainInitialize("new_england\ground3_ne",10);
rmSetMapType("saguenay");
rmSetMapType("water");
rmSetMapType("grass");
// rmSetGlobalSnow( 0.7 );
rmSetWorldCircleConstraint(true);
}
else
{
// waterlevel is eb
rmSetSeaLevel(1.0);
// Picks default terrain and water
// rmSetMapElevationParameters(long type, float minFrequency, long numberOctaves, float persistence, float heightVariation)
rmSetMapElevationParameters(cElevTurbulence, 0.1, 4, 0.3, 2.0);
rmSetSeaType("Waddenzeedry");
rmEnableLocalWater(false);
rmSetBaseTerrainMix("caribbean grass");
rmTerrainInitialize("new_england\ground3_ne",10);
rmSetMapType("saguenay");
rmSetMapType("water");
rmSetMapType("grass");
// rmSetGlobalSnow( 0.7 );
rmSetWorldCircleConstraint(true);
{

note: I haven't applied the changes on the HCwaterspawn, and the fishes. but I thought that wouldn't be neccesary
Neuron
Skirmisher
posted 03-26-14 04:34 PM EDT (US)     695 / 735       
Where are the water areas placed? Because from the map initialisation, I see both versions were set up as land. So, I suppose you created rivers, ponds or other areas with the water types.

Normally, you set a sea type because you initialise the map as water, then create land areas separately (as continents or islands). But if you don't initialise the map as all-water, there's no need to define the sea type. You can just use the old or new/modded water types when you define the areas where you want water to be placed (rivers, ponds, lakes, etc).

If you created a new watertype based on the Bayou one, it's possible that it has the same characteristics. The Bayou watertype doesn't allow either building in it or placing units in it, like warships or the water HC spawn point. I'm not sure about decoration and fish, but that's beside the point, since you can't build any fishing ships in the Bayou watertype.
Peter194
Skirmisher
posted 03-28-14 04:27 AM EDT (US)     696 / 735       
wow, I'm feeling stupid now: so I took a closer look to the file and found this (because I haven't written everything by myself I can forget things like this, it is based on Saguenay)

I have now tried this also:

   // Build the areas.
rmBuildAllAreas();

// Create a HudsonBay water area -- the mediterranean part.

if ( Waterlevel == 1 );
{
// waterlevel is flood
int HudsonBayID=rmCreateArea("Hudson Bay");
if ( cNumberNonGaiaPlayers < 8 )
{
rmSetAreaSize(HudsonBayID, 0.15, 0.15);
}
else
{
rmSetAreaSize(HudsonBayID, 0.2, 0.2);
}
rmSetAreaLocation(HudsonBayID, 0.8, 0.8);
rmAddAreaInfluenceSegment(HudsonBayID, 1.0, 1.0, 0.5, 0.5);
rmSetAreaWaterType(HudsonBayID, "caribbean coast");
rmSetAreaBaseHeight(HudsonBayID, 4.0); // Was 10
rmSetAreaMinBlobs(HudsonBayID, 8);
rmSetAreaMaxBlobs(HudsonBayID, 10);
rmSetAreaMinBlobDistance(HudsonBayID, 10);
rmSetAreaMaxBlobDistance(HudsonBayID, 20);
rmSetAreaSmoothDistance(HudsonBayID, 50);
rmSetAreaCoherence(HudsonBayID, 0.3);
rmAddAreaConstraint(HudsonBayID, avoidStartingUnitsBay);
rmAddAreaToClass(HudsonBayID, rmClassID("bay"));
rmSetAreaObeyWorldCircleConstraint(HudsonBayID, false);

rmBuildArea(HudsonBayID);
}
else
{
// waterlevel is eb
int HudsonBayID=rmCreateArea("Hudson Bay");
if ( cNumberNonGaiaPlayers < 8 )
{
rmSetAreaSize(HudsonBayID, 0.15, 0.15);
}
else
{
rmSetAreaSize(HudsonBayID, 0.2, 0.2);
}
rmSetAreaLocation(HudsonBayID, 0.8, 0.8);
rmAddAreaInfluenceSegment(HudsonBayID, 1.0, 1.0, 0.5, 0.5);
rmSetAreaWaterType(HudsonBayID, "Waddenzeedry");
rmSetAreaBaseHeight(HudsonBayID, 4.0); // Was 10
rmSetAreaMinBlobs(HudsonBayID, 8);
rmSetAreaMaxBlobs(HudsonBayID, 10);
rmSetAreaMinBlobDistance(HudsonBayID, 10);
rmSetAreaMaxBlobDistance(HudsonBayID, 20);
rmSetAreaSmoothDistance(HudsonBayID, 50);
rmSetAreaCoherence(HudsonBayID, 0.3);
rmAddAreaConstraint(HudsonBayID, avoidStartingUnitsBay);
rmAddAreaToClass(HudsonBayID, rmClassID("bay"));
rmSetAreaObeyWorldCircleConstraint(HudsonBayID, false);

rmBuildArea(HudsonBayID);
}
Neuron
Skirmisher
posted 03-28-14 07:39 AM EDT (US)     697 / 735       
There was a semicolon ; after the IF statement, which would result in an error.

You could also write it in a shorter form:

// Create a HudsonBay water area -- the mediterranean part.

int HudsonBayID=rmCreateArea("Hudson Bay");

if ( cNumberNonGaiaPlayers < 8 ) {
rmSetAreaSize(HudsonBayID, 0.15, 0.15);
}
else {
rmSetAreaSize(HudsonBayID, 0.2, 0.2);
}
rmSetAreaLocation(HudsonBayID, 0.8, 0.8);
rmAddAreaInfluenceSegment(HudsonBayID, 1.0, 1.0, 0.5, 0.5);

if ( Waterlevel == 1 ) {
// waterlevel is flood
rmSetAreaWaterType(HudsonBayID, "caribbean coast");
}
else {
// waterlevel is eb
rmSetAreaWaterType(HudsonBayID, "Waddenzeedry");
}
rmSetAreaBaseHeight(HudsonBayID, 4.0); // Was 10
rmSetAreaMinBlobs(HudsonBayID, 8);
rmSetAreaMaxBlobs(HudsonBayID, 10);
rmSetAreaMinBlobDistance(HudsonBayID, 10);
rmSetAreaMaxBlobDistance(HudsonBayID, 20);
rmSetAreaSmoothDistance(HudsonBayID, 50);
rmSetAreaCoherence(HudsonBayID, 0.3);
rmAddAreaConstraint(HudsonBayID, avoidStartingUnitsBay);
rmAddAreaToClass(HudsonBayID, rmClassID("bay"));
rmSetAreaObeyWorldCircleConstraint(HudsonBayID, false);
rmBuildArea(HudsonBayID);
Peter194
Skirmisher
posted 03-28-14 10:52 AM EDT (US)     698 / 735       
Thanks for the quick answer, I will probably trying this out tomorrow because I cant go on the pc today

Doesnt I have to change the rmsetseatype in the map initialisation also?

Like:


If ( waterlevel == 1 )
{
Rmsetseatype: ("carribean coast")
}
Else
{
rmsetseatype: ("waddenzeedry")
}

Note: This has maybe error because i have directly written it from my mind
Neuron
Skirmisher
posted 03-28-14 01:24 PM EDT (US)     699 / 735       
Doesnt I have to change the rmsetseatype in the map initialisation also?
Well, you only set a sea type when you initialise the map as water. So, like this:

rmSetSeaType("Write water type here");
rmTerrainInitialize("water");

If you do this the whole map will be initialised as water. But now you need to build some land areas on it to make sure player stuff can be placed. If land is missing the map loads, but if players units can't be placed, everyone is resigned.

If you don't want to make an all water map, but just have some ponds or rivers and mostly land, you can do it like this:

rmSetBaseMix("caribbean grass");
rmTerrainInitialize("new_england\ground3_ne", 10);

Now the whole map is initialised as land, based on this pattern ("new_england\ground3_ne") and base height (10).

And then later in the script, you can create the areas which have water:

// Create a HudsonBay water area -- the mediterranean part.

int HudsonBayID=rmCreateArea("Hudson Bay");

if ( cNumberNonGaiaPlayers < 8 ) {
rmSetAreaSize(HudsonBayID, 0.15, 0.15);
}
else {
rmSetAreaSize(HudsonBayID, 0.2, 0.2);
}
rmSetAreaLocation(HudsonBayID, 0.8, 0.8);
rmAddAreaInfluenceSegment(HudsonBayID, 1.0, 1.0, 0.5, 0.5);

if ( Waterlevel == 1 ) {
// waterlevel is flood
rmSetAreaWaterType(HudsonBayID, "caribbean coast");
}
else {
// waterlevel is eb
rmSetAreaWaterType(HudsonBayID, "Waddenzeedry");
}
rmSetAreaBaseHeight(HudsonBayID, 4.0); // Was 10
rmSetAreaMinBlobs(HudsonBayID, 8);
rmSetAreaMaxBlobs(HudsonBayID, 10);
rmSetAreaMinBlobDistance(HudsonBayID, 10);
rmSetAreaMaxBlobDistance(HudsonBayID, 20);
rmSetAreaSmoothDistance(HudsonBayID, 50);
rmSetAreaCoherence(HudsonBayID, 0.3);
rmAddAreaConstraint(HudsonBayID, avoidStartingUnitsBay);
rmAddAreaToClass(HudsonBayID, rmClassID("bay"));
rmSetAreaObeyWorldCircleConstraint(HudsonBayID, false);
rmBuildArea(HudsonBayID);

---------
Doesnt I have to change the rmsetseatype in the map initialisation also?

Like:

If ( waterlevel == 1 )
{
Rmsetseatype: ("carribean coast")
}
Else
{
rmsetseatype: ("waddenzeedry")
}

If you use this code, it should be like this:

If ( waterlevel == 1 )
{
rmSetSeaType("carribean coast");
}
else
{
rmSetSeaType("waddenzeedry");
}

But I think this only makes sense to use if you initialise the whole map as water, so Case 1 in what I wrote above.
Thanks for the quick answer
No problem.
dietermoreno
Skirmisher
posted 05-21-14 02:54 PM EDT (US)     700 / 735       
Neuron
Normally, you set a sea type because you initialise the map as water, then create land areas separately (as continents or islands). But if you don't initialise the map as all-water, there's no need to define the sea type. You can just use the old or new/modded water types when you define the areas where you want water to be placed (rivers, ponds, lakes, etc).
Can you give an example?




Peter124
kay, I've created the map, included the natives. start playing it a while. but I wasn't satisfied with it.

so I wanted to create a random possibility that the water could be 'eb', I already created a new water (waddenzeedry), based on the bayou swamp.
What is "eb water"?




Peter194
// Waterlevel int Waterlevel = rmRandInt(1,2); if ( waterlevel == 1 ) { // waterlevel is Flood rmSetSeaLevel(1.0); // Picks default terrain and water // rmSetMapElevationParameters(long type, float minFrequency, long numberOctaves, float persistence, float heightVariation) rmSetMapElevationParameters(cElevTurbulence, 0.1, 4, 0.3, 2.0); rmSetSeaType("caribbean coast"); rmEnableLocalWater(false); rmSetBaseTerrainMix("caribbean grass"); rmTerrainInitialize("new_england\ground3_ne",10); rmSetMapType("saguenay"); rmSetMapType("water"); rmSetMapType("grass"); // rmSetGlobalSnow( 0.7 ); rmSetWorldCircleConstraint(true); } else { // waterlevel is eb rmSetSeaLevel(1.0); // Picks default terrain and water // rmSetMapElevationParameters(long type, float minFrequency, long numberOctaves, float persistence, float heightVariation) rmSetMapElevationParameters(cElevTurbulence, 0.1, 4, 0.3, 2.0); rmSetSeaType("Waddenzeedry"); rmEnableLocalWater(false); rmSetBaseTerrainMix("caribbean grass"); rmTerrainInitialize("new_england\ground3_ne",10); rmSetMapType("saguenay"); rmSetMapType("water"); rmSetMapType("grass"); // rmSetGlobalSnow( 0.7 ); rmSetWorldCircleConstraint(true); {
What does this do?: int Waterlevel = rmRandInt(1,2);


What does this do?: if ( waterlevel == 1 ) { // waterlevel is Flood



What does this do?: // rmSetMapElevationParameters(long type, float minFrequency, long numberOctaves, float persistence, float heightVariation) rmSetMapElevationParameters(cElevTurbulence, 0.1, 4, 0.3, 2.0);


What does this do?: rmSetSeaType("Waddenzeedry");


What does this do?: rmEnableLocalWater(false);



I know this picks the map ground texture: rmSetBaseTerrainMix("caribbean grass");



What does this do?: rmTerrainInitialize("new_england\ground3_ne",10);



What does this do?:
rmSetMapType("saguenay");



What does this do?:
rmSetMapType("water");



What does this do?:
rmSetMapType("grass");


What does this do?:
// rmSetGlobalSnow( 0.7 );
Why did you comment it to cause it to not be used?



What does this do?:
rmSetWorldCircleConstraint(true);


So... How did you define a new sea type?

if ( waterlevel == 1 )
{
rmSetSeaLevel(1.0);
rmSetMapElevationParameters(cElevTurbulence, 0.1, 4, 0.3, 2.0);
rmSetSeaType("caribbean coast");
.....

}
else
{
rmSetMapElevationParameters(cElevTurbulence, 0.1, 4, 0.3, 2.0);
rmSetSeaType("Waddenzeedry");
.....
{



How do you add a coast line to an existing land RM?

I want to convert Sonora to have a coast line and name the map "Pacific Mexico".

Even if I borrowed code from Large Carolina cost line, how would I make the new coast not interfer with other objects already placed by the original Sonora map?

Is this what's important from Large Carolina?:

// DEFINE AREAS

// Complex placement to avoid water and enemy players

if(handedness < 0.5) // NE ocean
{
// If only 2 players place as 2 points
if(cNumberNonGaiaPlayers == 2)
{
rmPlacePlayer(1, 0.5, 0.85);
rmPlacePlayer(2, 0.5, 0.15);
}
// Place by team if 2 teams and sane teams
else if(cNumberTeams == 2 && rmGetNumberPlayersOnTeam(0) < 5 && rmGetNumberPlayersOnTeam(1) < 5)
{
rmSetPlacementTeam(0);
rmSetPlacementSection(0.85, 0.05);
rmPlacePlayersCircular(0.4, 0.4, rmDegreesToRadians(5.0));
rmSetPlacementTeam(1);
rmSetPlacementSection(0.45, 0.65);
rmPlacePlayersCircular(0.4, 0.4, rmDegreesToRadians(5.0));
}
// otherwise just place in one arc FFA style
else
{
rmSetPlacementSection(0.45, 0.05);
rmPlacePlayersCircular(0.4, 0.4, rmDegreesToRadians(5.0));
}
}
else // SE ocean
{
// If only 2 players place as 2 points
if(cNumberNonGaiaPlayers == 2)
{
rmPlacePlayer(1, 0.85, 0.5);
rmPlacePlayer(2, 0.15, 0.5);
}
// Place by team if 2 teams and sane teams
else if(cNumberTeams == 2 && rmGetNumberPlayersOnTeam(0) < 5 && rmGetNumberPlayersOnTeam(1) < 5)
{
rmSetPlacementTeam(0);
rmSetPlacementSection(0.10, 0.30);
rmPlacePlayersCircular(0.4, 0.4, rmDegreesToRadians(5.0));
rmSetPlacementTeam(1);
rmSetPlacementSection(0.70, 0.90);
rmPlacePlayersCircular(0.4, 0.4, rmDegreesToRadians(5.0));
}
// otherwise just place in one arc FFA style
else
{
rmSetPlacementSection(0.70, 0.30);
rmPlacePlayersCircular(0.4, 0.4, rmDegreesToRadians(5.0));
}
}








// Invisible continent added to have big continent avoid player areas

int invisContinentID=rmCreateArea("invisible continent for constraint");
rmSetAreaSize(invisContinentID, 0.01, 0.01);
rmSetAreaWarnFailure(invisContinentID, false);

if(handedness < 0.5) // NE ocean
{
rmSetAreaLocation(invisContinentID, 0.99, 0.5);
rmAddAreaInfluenceSegment(invisContinentID, 0.95, 0.30, 0.99, 0.5);
rmAddAreaInfluenceSegment(invisContinentID, 0.99, 0.5, 0.95, 0.70);
}
else
{
rmSetAreaLocation(invisContinentID, 0.5, 0.01);
rmAddAreaInfluenceSegment(invisContinentID, 0.30, 0.05, 0.5, 0.01);
rmAddAreaInfluenceSegment(invisContinentID, 0.5, 0.01, 0.70, 0.05);
}
rmAddAreaToClass(invisContinentID, rmClassID("classInvis"));
rmSetAreaCoherence(invisContinentID, 0.8);
//rmSetAreaBaseHeight(invisContinentID, 3);
//rmSetAreaMix(invisContinentID, "carolina_grass");

// Build the areas.
rmBuildArea(invisContinentID);




// Build up big continent called "big continent"
int bigContinentID = -1;
bigContinentID=rmCreateArea("big continent");
rmSetAreaSize(bigContinentID, 0.40, 0.47); // 0.38 0.47
rmSetAreaWarnFailure(bigContinentID, false);
rmAddAreaConstraint(bigContinentID, invisConstraint);
rmAddAreaToClass(bigContinentID, classbigContinent);

rmSetAreaMinBlobs(bigContinentID, 10);
rmSetAreaMaxBlobs(bigContinentID, 10);
rmSetAreaMinBlobDistance(bigContinentID, rmXFractionToMeters(0.1));
rmSetAreaMaxBlobDistance(bigContinentID, rmXFractionToMeters(0.4));

rmSetAreaSmoothDistance(bigContinentID, 50);
rmSetAreaMix(bigContinentID, "carolina_grass");
rmSetAreaElevationType(bigContinentID, cElevTurbulence);
rmSetAreaElevationVariation(bigContinentID, 4.0);
rmSetAreaBaseHeight(bigContinentID, 3.5);
rmSetAreaElevationMinFrequency(bigContinentID, 0.09);
rmSetAreaElevationOctaves(bigContinentID, 3);
rmSetAreaElevationPersistence(bigContinentID, 0.2);
rmSetAreaElevationNoiseBias(bigContinentID, 1);

rmSetAreaCoherence(bigContinentID, 0.15);

// CHOOSE RIGHT OR LEFT-HANDED CONTINENT
if(handedness < 0.5) // NE ocean
{
rmSetAreaLocation(bigContinentID, 0.25, 0.5);
rmAddAreaInfluenceSegment(bigContinentID, 0.5, 0.0, 0.5, 1.0);
rmAddAreaInfluenceSegment(bigContinentID, 0.0, 0.5, 0.4, 0.5);
}
else // SE ocean
{
rmSetAreaLocation(bigContinentID, 0.5, 0.75);
rmAddAreaInfluenceSegment(bigContinentID, 0.0, 0.5, 1.0, 0.5);
rmAddAreaInfluenceSegment(bigContinentID, 0.5, 1.0, 0.5, 0.6);
}
rmSetAreaEdgeFilling(bigContinentID, 10);

rmSetAreaObeyWorldCircleConstraint(bigContinentID, false);

rmBuildArea(bigContinentID);




// TRADE ROUTES
int tradeRouteID = rmCreateTradeRoute();

int socketID=rmCreateObjectDef("sockets for Trade Route");
rmAddObjectDefItem(socketID, "SocketTradeRoute", 1, 0.0);
rmAddObjectDefConstraint(socketID, avoidWater8);
rmAddObjectDefToClass(socketID, rmClassID("importantItem"));
rmSetObjectDefAllowOverlap(socketID, true);
rmSetObjectDefMinDistance(socketID, 0.0);
rmSetObjectDefMaxDistance(socketID, 8.0);

rmAddClosestPointConstraint(avoidWater16);
vector tradeRoutePoint = cOriginVector;


if(handedness < 0.5) // Ocean to NE
{
tradeRoutePoint = rmFindClosestPoint(0.3, 0.05, 20.0);
rmAddTradeRouteWaypoint(tradeRouteID, rmXMetersToFraction(xsVectorGetX(tradeRoutePoint)), rmZMetersToFraction(xsVectorGetZ(tradeRoutePoint)));

rmAddRandomTradeRouteWaypoints(tradeRouteID, 0.5, 0.5, 6, 6);

tradeRoutePoint = rmFindClosestPoint(0.3, 0.95, 20.0);
rmAddRandomTradeRouteWaypoints(tradeRouteID, rmXMetersToFraction(xsVectorGetX(tradeRoutePoint)), rmZMetersToFraction(xsVectorGetZ(tradeRoutePoint)), 4, 6);

}
else // Ocean to SE
{
tradeRoutePoint = rmFindClosestPoint(0.05, 0.7, 20.0);
rmAddTradeRouteWaypoint(tradeRouteID, rmXMetersToFraction(xsVectorGetX(tradeRoutePoint)), rmZMetersToFraction(xsVectorGetZ(tradeRoutePoint)));

rmAddRandomTradeRouteWaypoints(tradeRouteID, 0.5, 0.5, 6, 6);

tradeRoutePoint = rmFindClosestPoint(0.95, 0.7, 20.0);
rmAddRandomTradeRouteWaypoints(tradeRouteID, rmXMetersToFraction(xsVectorGetX(tradeRoutePoint)), rmZMetersToFraction(xsVectorGetZ(tradeRoutePoint)), 4, 6);

}

bool placedTradeRoute = rmBuildTradeRoute(tradeRouteID, "dirt");
if(placedTradeRoute == false)
rmEchoError("Failed to place trade route");

and then give everything contrainsts to place on bigcontinent so things don't place on water?

Mummy zombies on the Nile map is actually more historically accurate than tanks being destroyed by pikemen.

Want denser forests and a huge Amazon?

[This message has been edited by dietermoreno (edited 05-21-2014 @ 03:22 PM).]

« Previous Page  1 ··· 10 ··· 20 ··· 26 27 28 29 30  Next Page »
You must be logged in to post messages.
Please login or register

Hop to:    

Age of Empires III Heaven | HeavenGames